/* Creates a new VS constant buffer reflecting the current VS program's * constants, if needed by the VS program. * * Otherwise, constants go through the CURBEs using the brw_constant_buffer * state atom. */ static void brw_upload_vs_pull_constants(struct brw_context *brw) { struct brw_stage_state *stage_state = &brw->vs.base; /* BRW_NEW_VERTEX_PROGRAM */ struct brw_program *vp = (struct brw_program *) brw->vertex_program; /* BRW_NEW_VS_PROG_DATA */ const struct brw_stage_prog_data *prog_data = brw->vs.base.prog_data; _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_VERTEX); /* _NEW_PROGRAM_CONSTANTS */ brw_upload_pull_constants(brw, BRW_NEW_VS_CONSTBUF, &vp->program, stage_state, prog_data); }
static void gen7_upload_tes_push_constants(struct brw_context *brw) { struct brw_stage_state *stage_state = &brw->tes.base; /* BRW_NEW_TESS_PROGRAMS */ const struct brw_program *tep = brw_program_const(brw->tess_eval_program); if (tep) { /* BRW_NEW_TES_PROG_DATA */ const struct brw_stage_prog_data *prog_data = brw->tes.base.prog_data; _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_TESS_EVAL); gen6_upload_push_constants(brw, &tep->program, prog_data, stage_state, AUB_TRACE_VS_CONSTANTS); } gen7_upload_constant_state(brw, stage_state, tep, _3DSTATE_CONSTANT_DS); }
/* Creates a new TES constant buffer reflecting the current TES program's * constants, if needed by the TES program. * * Otherwise, constants go through the CURBEs using the brw_constant_buffer * state atom. */ static void brw_upload_tes_pull_constants(struct brw_context *brw) { struct brw_stage_state *stage_state = &brw->tes.base; /* BRW_NEW_TESS_PROGRAMS */ struct brw_program *dp = (struct brw_program *) brw->tess_eval_program; if (!dp) return; /* BRW_NEW_TES_PROG_DATA */ const struct brw_stage_prog_data *prog_data = brw->tes.base.prog_data; _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_TESS_EVAL); /* _NEW_PROGRAM_CONSTANTS */ brw_upload_pull_constants(brw, BRW_NEW_TES_CONSTBUF, &dp->program, stage_state, prog_data); }
/* Creates a new GS constant buffer reflecting the current GS program's * constants, if needed by the GS program. * * Otherwise, constants go through the CURBEs using the brw_constant_buffer * state atom. */ static void brw_upload_gs_pull_constants(struct brw_context *brw) { struct brw_stage_state *stage_state = &brw->gs.base; /* BRW_NEW_GEOMETRY_PROGRAM */ struct brw_geometry_program *gp = (struct brw_geometry_program *) brw->geometry_program; if (!gp) return; /* BRW_NEW_GS_PROG_DATA */ const struct brw_stage_prog_data *prog_data = brw->gs.base.prog_data; _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_GEOMETRY); /* _NEW_PROGRAM_CONSTANTS */ brw_upload_pull_constants(brw, BRW_NEW_GS_CONSTBUF, &gp->program.Base, stage_state, prog_data); }
static void gen6_upload_vs_push_constants(struct brw_context *brw) { struct brw_stage_state *stage_state = &brw->vs.base; /* _BRW_NEW_VERTEX_PROGRAM */ const struct brw_vertex_program *vp = brw_vertex_program_const(brw->vertex_program); /* BRW_NEW_VS_PROG_DATA */ const struct brw_stage_prog_data *prog_data = brw->vs.base.prog_data; _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_VERTEX); gen6_upload_push_constants(brw, &vp->program.Base, prog_data, stage_state, AUB_TRACE_VS_CONSTANTS); if (brw->gen >= 7) { if (brw->gen == 7 && !brw->is_haswell && !brw->is_baytrail) gen7_emit_vs_workaround_flush(brw); gen7_upload_constant_state(brw, stage_state, true /* active */, _3DSTATE_CONSTANT_VS); } }
/** * Pass the given program parameters to the graphics pipe as a * constant buffer. */ void st_upload_constants(struct st_context *st, struct gl_program *prog) { gl_shader_stage stage = prog->info.stage; struct gl_program_parameter_list *params = prog->Parameters; enum pipe_shader_type shader_type = pipe_shader_type_from_mesa(stage); assert(shader_type == PIPE_SHADER_VERTEX || shader_type == PIPE_SHADER_FRAGMENT || shader_type == PIPE_SHADER_GEOMETRY || shader_type == PIPE_SHADER_TESS_CTRL || shader_type == PIPE_SHADER_TESS_EVAL || shader_type == PIPE_SHADER_COMPUTE); /* update the ATI constants before rendering */ if (shader_type == PIPE_SHADER_FRAGMENT && st->fp->ati_fs) { struct ati_fragment_shader *ati_fs = st->fp->ati_fs; unsigned c; for (c = 0; c < MAX_NUM_FRAGMENT_CONSTANTS_ATI; c++) { if (ati_fs->LocalConstDef & (1 << c)) memcpy(params->ParameterValues[c], ati_fs->Constants[c], sizeof(GLfloat) * 4); else memcpy(params->ParameterValues[c], st->ctx->ATIFragmentShader.GlobalConstants[c], sizeof(GLfloat) * 4); } } /* Make all bindless samplers/images bound texture/image units resident in * the context. */ st_make_bound_samplers_resident(st, prog); st_make_bound_images_resident(st, prog); /* update constants */ if (params && params->NumParameters) { struct pipe_constant_buffer cb; const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4; /* 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, params->StateFlags); _mesa_print_parameter_list(params); } cso_set_constant_buffer(st->cso_context, shader_type, 0, &cb); pipe_resource_reference(&cb.buffer, NULL); st->state.constants[shader_type].ptr = params->ParameterValues; st->state.constants[shader_type].size = paramBytes; } else if (st->state.constants[shader_type].ptr) { /* Unbind. */ st->state.constants[shader_type].ptr = NULL; st->state.constants[shader_type].size = 0; cso_set_constant_buffer(st->cso_context, shader_type, 0, NULL); } }
/** * Pass the given program parameters to the graphics pipe as a * constant buffer. * \param shader_type either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT */ void st_upload_constants( struct st_context *st, struct gl_program_parameter_list *params, gl_shader_stage stage) { enum pipe_shader_type shader_type = st_shader_stage_to_ptarget(stage); assert(shader_type == PIPE_SHADER_VERTEX || shader_type == PIPE_SHADER_FRAGMENT || shader_type == PIPE_SHADER_GEOMETRY || shader_type == PIPE_SHADER_TESS_CTRL || shader_type == PIPE_SHADER_TESS_EVAL || shader_type == PIPE_SHADER_COMPUTE); /* update the ATI constants before rendering */ if (shader_type == PIPE_SHADER_FRAGMENT && st->fp->ati_fs) { struct ati_fragment_shader *ati_fs = st->fp->ati_fs; unsigned c; for (c = 0; c < MAX_NUM_FRAGMENT_CONSTANTS_ATI; c++) { if (ati_fs->LocalConstDef & (1 << c)) memcpy(params->ParameterValues[c], ati_fs->Constants[c], sizeof(GLfloat) * 4); else memcpy(params->ParameterValues[c], st->ctx->ATIFragmentShader.GlobalConstants[c], sizeof(GLfloat) * 4); } } /* update constants */ if (params && params->NumParameters) { struct pipe_constant_buffer cb; const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4; /* 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); /* We always need to get a new buffer, to keep the drivers simple and * avoid gratuitous rendering synchronization. * Let's use a user buffer to avoid an unnecessary copy. */ if (st->constbuf_uploader) { cb.buffer = NULL; cb.user_buffer = NULL; u_upload_data(st->constbuf_uploader, 0, paramBytes, st->ctx->Const.UniformBufferOffsetAlignment, params->ParameterValues, &cb.buffer_offset, &cb.buffer); u_upload_unmap(st->constbuf_uploader); } else { 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, params->StateFlags); _mesa_print_parameter_list(params); } cso_set_constant_buffer(st->cso_context, shader_type, 0, &cb); pipe_resource_reference(&cb.buffer, NULL); st->state.constants[shader_type].ptr = params->ParameterValues; st->state.constants[shader_type].size = paramBytes; } else if (st->state.constants[shader_type].ptr) { /* Unbind. */ st->state.constants[shader_type].ptr = NULL; st->state.constants[shader_type].size = 0; cso_set_constant_buffer(st->cso_context, shader_type, 0, NULL); } }