mesa: put constants before state vars for ARB programs

This moves state vars to the end of the parameter list, so that state vars
can be loaded directly into a buffer instead of loaded into the parameter list.
Also, state vars don't need to be searched in the parameter list anymore,
because we will know their index range. (this will make gallium faster)

This commit just wraps a for loop around the existing code.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6946>
This commit is contained in:
Marek Olšák 2020-09-27 21:42:46 -04:00 committed by Marge Bot
parent 06a141469b
commit b9bff76b63

View file

@ -128,94 +128,106 @@ _mesa_layout_parameters(struct asm_parser_state *state)
{
struct gl_program_parameter_list *layout;
struct asm_instruction *inst;
unsigned i;
layout =
_mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters);
/* PASS 1: Move any parameters that are accessed indirectly from the
* original parameter list to the new parameter list.
*/
for (inst = state->inst_head; inst != NULL; inst = inst->next) {
for (i = 0; i < 3; i++) {
if (inst->SrcReg[i].Base.RelAddr) {
/* Only attempt to add the to the new parameter list once.
*/
if (!inst->SrcReg[i].Symbol->pass1_done) {
const int new_begin =
copy_indirect_accessed_array(state->prog->Parameters, layout,
inst->SrcReg[i].Symbol->param_binding_begin,
inst->SrcReg[i].Symbol->param_binding_length);
for (unsigned f = 0; f < 2; f++) {
unsigned file = !f ? PROGRAM_CONSTANT : PROGRAM_STATE_VAR;
if (new_begin < 0) {
_mesa_free_parameter_list(layout);
return GL_FALSE;
}
/* PASS 1: Move any parameters that are accessed indirectly from the
* original parameter list to the new parameter list.
*/
for (inst = state->inst_head; inst != NULL; inst = inst->next) {
for (unsigned i = 0; i < 3; i++) {
if (inst->SrcReg[i].Base.RelAddr) {
unsigned begin = inst->SrcReg[i].Symbol->param_binding_begin;
if (state->prog->Parameters->Parameters[begin].Type != file)
continue;
inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
inst->SrcReg[i].Symbol->pass1_done = 1;
}
/* Only attempt to add the to the new parameter list once.
*/
if (!inst->SrcReg[i].Symbol->pass1_done) {
const int new_begin =
copy_indirect_accessed_array(state->prog->Parameters, layout,
inst->SrcReg[i].Symbol->param_binding_begin,
inst->SrcReg[i].Symbol->param_binding_length);
/* Previously the Index was just the offset from the parameter
* array. Now that the base of the parameter array is known, the
* index can be updated to its actual value.
*/
inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
inst->Base.SrcReg[i].Index +=
inst->SrcReg[i].Symbol->param_binding_begin;
}
if (new_begin < 0) {
_mesa_free_parameter_list(layout);
return GL_FALSE;
}
inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
inst->SrcReg[i].Symbol->pass1_done = 1;
}
/* Previously the Index was just the offset from the parameter
* array. Now that the base of the parameter array is known, the
* index can be updated to its actual value.
*/
inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
inst->Base.SrcReg[i].Index +=
inst->SrcReg[i].Symbol->param_binding_begin;
}
}
}
}
/* PASS 2: Move any parameters that are not accessed indirectly from the
* original parameter list to the new parameter list.
*/
for (inst = state->inst_head; inst != NULL; inst = inst->next) {
for (i = 0; i < 3; i++) {
const struct gl_program_parameter *p;
const int idx = inst->SrcReg[i].Base.Index;
unsigned swizzle = SWIZZLE_NOOP;
/* PASS 2: Move any parameters that are not accessed indirectly from the
* original parameter list to the new parameter list.
*/
for (inst = state->inst_head; inst != NULL; inst = inst->next) {
for (unsigned i = 0; i < 3; i++) {
const struct gl_program_parameter *p;
const int idx = inst->SrcReg[i].Base.Index;
unsigned swizzle = SWIZZLE_NOOP;
/* All relative addressed operands were processed on the first
* pass. Just skip them here.
*/
if (inst->SrcReg[i].Base.RelAddr) {
continue;
}
/* All relative addressed operands were processed on the first
* pass. Just skip them here.
*/
if (inst->SrcReg[i].Base.RelAddr) {
continue;
}
if ((inst->SrcReg[i].Base.File <= PROGRAM_OUTPUT)
|| (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
continue;
}
p = &state->prog->Parameters->Parameters[idx];
inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
p = & state->prog->Parameters->Parameters[idx];
if ((inst->SrcReg[i].Base.File <= PROGRAM_OUTPUT)
|| (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
continue;
}
switch (p->Type) {
case PROGRAM_CONSTANT: {
unsigned pvo = state->prog->Parameters->ParameterValueOffset[idx];
const gl_constant_value *const v =
state->prog->Parameters->ParameterValues + pvo;
if (p->Type != file) {
continue;
}
inst->Base.SrcReg[i].Index =
_mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);
inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
inst->Base.SrcReg[i].Swizzle =
_mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
break;
}
switch (p->Type) {
case PROGRAM_CONSTANT: {
unsigned pvo = state->prog->Parameters->ParameterValueOffset[idx];
const gl_constant_value *const v =
state->prog->Parameters->ParameterValues + pvo;
case PROGRAM_STATE_VAR:
inst->Base.SrcReg[i].Index =
_mesa_add_state_reference(layout, p->StateIndexes);
break;
inst->Base.SrcReg[i].Index =
_mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);
default:
break;
}
inst->Base.SrcReg[i].Swizzle =
_mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
break;
}
inst->SrcReg[i].Base.File = p->Type;
inst->Base.SrcReg[i].File = p->Type;
case PROGRAM_STATE_VAR:
inst->Base.SrcReg[i].Index =
_mesa_add_state_reference(layout, p->StateIndexes);
break;
default:
break;
}
inst->SrcReg[i].Base.File = p->Type;
inst->Base.SrcReg[i].File = p->Type;
}
}
}