i965: Make FS uniforms be the actual type of the uniform at upload time.

This fixes some insanity that would otherwise be required for GLSL
1.30 bit ops or gen6 integer uniform operations in general, at the
cost of upload-time pain.  Given that we only have that pain because
mesa's mangling our integer uniforms to be floats, this something that
should be fixed outside of the shader codegen.
This commit is contained in:
Eric Anholt 2010-10-25 12:52:29 -07:00 committed by Kenneth Graunke
parent 502943049a
commit 9e3641bd0d
6 changed files with 81 additions and 9 deletions

View File

@ -188,6 +188,13 @@ struct brw_shader_program {
struct gl_shader_program base;
};
enum param_conversion {
PARAM_NO_CONVERT,
PARAM_CONVERT_F2I,
PARAM_CONVERT_F2U,
PARAM_CONVERT_F2B,
};
/* Data about a particular attempt to compile a program. Note that
* there can be many of these, each in a different GL state
* corresponding to a different brw_wm_prog_key struct, with different
@ -208,8 +215,10 @@ struct brw_wm_prog_data {
/* Pointer to tracked values (only valid once
* _mesa_load_state_parameters has been called at runtime).
*/
const GLfloat *param[MAX_UNIFORMS * 4]; /* should be: BRW_MAX_CURBE */
const GLfloat *pull_param[MAX_UNIFORMS * 4];
const float *param[MAX_UNIFORMS * 4]; /* should be: BRW_MAX_CURBE */
enum param_conversion param_convert[MAX_UNIFORMS * 4];
const float *pull_param[MAX_UNIFORMS * 4];
enum param_conversion pull_param_convert[MAX_UNIFORMS * 4];
};
struct brw_sf_prog_data {
@ -800,6 +809,35 @@ brw_fragment_program_const(const struct gl_fragment_program *p)
return (const struct brw_fragment_program *) p;
}
static inline
float convert_param(enum param_conversion conversion, float param)
{
union {
float f;
uint32_t u;
int32_t i;
} fi;
switch (conversion) {
case PARAM_NO_CONVERT:
return param;
case PARAM_CONVERT_F2I:
fi.i = param;
return fi.f;
case PARAM_CONVERT_F2U:
fi.u = param;
return fi.f;
case PARAM_CONVERT_F2B:
if (param != 0.0)
fi.i = 1;
else
fi.i = 0;
return fi.f;
default:
return param;
}
}
GLboolean brw_do_cubemap_normalize(struct exec_list *instructions);
#endif

View File

@ -199,8 +199,10 @@ static void prepare_constant_buffer(struct brw_context *brw)
GLuint offset = brw->curbe.wm_start * 16;
/* copy float constants */
for (i = 0; i < brw->wm.prog_data->nr_params; i++)
buf[offset + i] = *brw->wm.prog_data->param[i];
for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
buf[offset + i] = convert_param(brw->wm.prog_data->param_convert[i],
*brw->wm.prog_data->param[i]);
}
}

View File

@ -228,6 +228,7 @@ brw_type_for_base_type(const struct glsl_type *type)
return BRW_REGISTER_TYPE_UD;
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_STRUCT:
case GLSL_TYPE_SAMPLER:
/* These should be overridden with the type of the member when
* dereferenced into. BRW_REGISTER_TYPE_UD seems like a likely
* way to trip up if we don't.
@ -286,8 +287,26 @@ fs_visitor::setup_uniform_values(int loc, const glsl_type *type)
case GLSL_TYPE_BOOL:
vec_values = fp->Base.Parameters->ParameterValues[loc];
for (unsigned int i = 0; i < type->vector_elements; i++) {
assert(c->prog_data.nr_params < ARRAY_SIZE(c->prog_data.param));
c->prog_data.param[c->prog_data.nr_params++] = &vec_values[i];
unsigned int param = c->prog_data.nr_params++;
assert(param < ARRAY_SIZE(c->prog_data.param));
switch (type->base_type) {
case GLSL_TYPE_FLOAT:
c->prog_data.param_convert[param] = PARAM_NO_CONVERT;
break;
case GLSL_TYPE_UINT:
c->prog_data.param_convert[param] = PARAM_CONVERT_F2U;
break;
case GLSL_TYPE_INT:
c->prog_data.param_convert[param] = PARAM_CONVERT_F2I;
break;
case GLSL_TYPE_BOOL:
c->prog_data.param_convert[param] = PARAM_CONVERT_F2B;
break;
}
c->prog_data.param[param] = &vec_values[i];
}
return 1;
@ -371,6 +390,8 @@ fs_visitor::setup_builtin_uniform_values(ir_variable *ir)
break;
last_swiz = swiz;
c->prog_data.param_convert[c->prog_data.nr_params] =
PARAM_NO_CONVERT;
c->prog_data.param[c->prog_data.nr_params++] = &vec_values[swiz];
}
}
@ -625,6 +646,7 @@ fs_visitor::visit(ir_variable *ir)
}
reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index);
reg->type = brw_type_for_base_type(ir->type);
}
if (!reg)
@ -1204,6 +1226,11 @@ fs_visitor::visit(ir_texture *ir)
0
};
c->prog_data.param_convert[c->prog_data.nr_params] =
PARAM_NO_CONVERT;
c->prog_data.param_convert[c->prog_data.nr_params + 1] =
PARAM_NO_CONVERT;
fs_reg scale_x = fs_reg(UNIFORM, c->prog_data.nr_params);
fs_reg scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1);
GLuint index = _mesa_add_state_reference(params,
@ -2359,7 +2386,7 @@ fs_visitor::assign_curb_setup()
constant_nr % 8);
inst->src[i].file = FIXED_HW_REG;
inst->src[i].fixed_hw_reg = brw_reg;
inst->src[i].fixed_hw_reg = retype(brw_reg, inst->src[i].type);
}
}
}
@ -2566,6 +2593,8 @@ fs_visitor::setup_pull_constants()
for (int i = 0; i < pull_uniform_count; i++) {
c->prog_data.pull_param[i] = c->prog_data.param[pull_uniform_base + i];
c->prog_data.pull_param_convert[i] =
c->prog_data.param_convert[pull_uniform_base + i];
}
c->prog_data.nr_params -= pull_uniform_count;
c->prog_data.nr_pull_params = pull_uniform_count;

View File

@ -113,6 +113,7 @@ static const struct brw_wm_ref *get_param_ref( struct brw_wm_compile *c,
struct brw_wm_ref *ref = get_ref(c);
c->prog_data.param[i] = param_ptr;
c->prog_data.param_convert[i] = PARAM_NO_CONVERT;
c->nr_creg = (i+16)/16;
/* Push the offsets into hw_reg. These will be added to the

View File

@ -343,7 +343,8 @@ prepare_wm_constants(struct brw_context *brw)
drm_intel_gem_bo_map_gtt(brw->wm.const_bo);
constants = brw->wm.const_bo->virtual;
for (i = 0; i < brw->wm.prog_data->nr_pull_params; i++) {
constants[i] = *brw->wm.prog_data->pull_param[i];
constants[i] = convert_param(brw->wm.prog_data->pull_param_convert[i],
*brw->wm.prog_data->pull_param[i]);
}
drm_intel_gem_bo_unmap_gtt(brw->wm.const_bo);

View File

@ -63,7 +63,8 @@ prepare_wm_constants(struct brw_context *brw)
drm_intel_gem_bo_map_gtt(brw->wm.push_const_bo);
constants = brw->wm.push_const_bo->virtual;
for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
constants[i] = *brw->wm.prog_data->param[i];
constants[i] = convert_param(brw->wm.prog_data->param_convert[i],
*brw->wm.prog_data->param[i]);
}
drm_intel_gem_bo_unmap_gtt(brw->wm.push_const_bo);
}