i965: Add support for builtin uniforms to the new FS backend.

Fixes 8 piglit tests.
This commit is contained in:
Eric Anholt 2010-09-28 16:23:04 -07:00
parent daacaac3c8
commit 1747aa6755
1 changed files with 70 additions and 1 deletions

View File

@ -31,6 +31,7 @@ extern "C" {
#include "main/macros.h"
#include "main/shaderobj.h"
#include "main/uniforms.h"
#include "program/prog_parameter.h"
#include "program/prog_print.h"
#include "program/prog_optimize.h"
@ -461,6 +462,7 @@ public:
struct brw_reg interp_reg(int location, int channel);
int setup_uniform_values(int loc, const glsl_type *type);
void setup_builtin_uniform_values(ir_variable *ir);
struct brw_context *brw;
const struct gl_fragment_program *fp;
@ -607,6 +609,69 @@ fs_visitor::setup_uniform_values(int loc, const glsl_type *type)
}
}
/* Our support for builtin uniforms is even scarier than non-builtin.
* It sits on top of the PROG_STATE_VAR parameters that are
* automatically updated from GL context state.
*/
void
fs_visitor::setup_builtin_uniform_values(ir_variable *ir)
{
const struct gl_builtin_uniform_desc *statevar = NULL;
for (unsigned int i = 0; _mesa_builtin_uniform_desc[i].name; i++) {
statevar = &_mesa_builtin_uniform_desc[i];
if (strcmp(ir->name, _mesa_builtin_uniform_desc[i].name) == 0)
break;
}
if (!statevar->name) {
this->fail = true;
printf("Failed to find builtin uniform `%s'\n", ir->name);
return;
}
int array_count;
if (ir->type->is_array()) {
array_count = ir->type->length;
} else {
array_count = 1;
}
for (int a = 0; a < array_count; a++) {
for (unsigned int i = 0; i < statevar->num_elements; i++) {
struct gl_builtin_uniform_element *element = &statevar->elements[i];
int tokens[STATE_LENGTH];
memcpy(tokens, element->tokens, sizeof(element->tokens));
if (ir->type->is_array()) {
tokens[1] = a;
}
/* This state reference has already been setup by ir_to_mesa,
* but we'll get the same index back here.
*/
int index = _mesa_add_state_reference(this->fp->Base.Parameters,
(gl_state_index *)tokens);
float *vec_values = this->fp->Base.Parameters->ParameterValues[index];
/* Add each of the unique swizzles of the element as a
* parameter. This'll end up matching the expected layout of
* the array/matrix/structure we're trying to fill in.
*/
int last_swiz = -1;
for (unsigned int i = 0; i < 4; i++) {
int this_swiz = GET_SWZ(element->swizzle, i);
if (this_swiz == last_swiz)
break;
last_swiz = this_swiz;
c->prog_data.param[c->prog_data.nr_params++] = &vec_values[i];
}
}
}
}
void
fs_visitor::emit_fragcoord_interpolation(ir_variable *ir)
{
@ -751,7 +816,11 @@ fs_visitor::visit(ir_variable *ir)
if (ir->mode == ir_var_uniform) {
int param_index = c->prog_data.nr_params;
setup_uniform_values(ir->location, ir->type);
if (!strncmp(ir->name, "gl_", 3)) {
setup_builtin_uniform_values(ir);
} else {
setup_uniform_values(ir->location, ir->type);
}
reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index);
}