summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-09-27 22:26:22 -0700
committerEric Anholt <[email protected]>2010-09-28 09:33:31 -0700
commitba481f2046e6427c8bd7fc5f8cb8ef3059a7881a (patch)
treeb7817724f8cead0c1e803ab1b24bcb2261548250
parent07fc8eed8f0398063d87acf3a7ee392da4184822 (diff)
i965: Add support for dereferencing structs to the new FS backend.
Fixes: glsl1-struct(2)
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp67
1 files changed, 32 insertions, 35 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 3b56340343f..4f88ca10c19 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -499,42 +499,42 @@ fs_reg::fs_reg(enum register_file file, int hw_reg)
this->type = BRW_REGISTER_TYPE_F;
}
-/** Automatic reg constructor. */
-fs_reg::fs_reg(class fs_visitor *v, const struct glsl_type *type)
+int
+brw_type_for_base_type(const struct glsl_type *type)
{
- init();
-
- this->file = GRF;
- this->reg = v->next_abstract_grf;
- this->reg_offset = 0;
- v->next_abstract_grf += type_size(type);
-
switch (type->base_type) {
case GLSL_TYPE_FLOAT:
- this->type = BRW_REGISTER_TYPE_F;
- break;
+ return BRW_REGISTER_TYPE_F;
case GLSL_TYPE_INT:
case GLSL_TYPE_BOOL:
- this->type = BRW_REGISTER_TYPE_D;
- break;
+ return BRW_REGISTER_TYPE_D;
case GLSL_TYPE_UINT:
- this->type = BRW_REGISTER_TYPE_UD;
- break;
+ return BRW_REGISTER_TYPE_UD;
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_STRUCT:
/* 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.
*/
- this->type = BRW_REGISTER_TYPE_UD;
- break;
+ return BRW_REGISTER_TYPE_UD;
default:
assert(!"not reached");
- this->type = BRW_REGISTER_TYPE_F;
- break;
+ return BRW_REGISTER_TYPE_F;
}
}
+/** Automatic reg constructor. */
+fs_reg::fs_reg(class fs_visitor *v, const struct glsl_type *type)
+{
+ init();
+
+ this->file = GRF;
+ this->reg = v->next_abstract_grf;
+ this->reg_offset = 0;
+ v->next_abstract_grf += type_size(type);
+ this->type = brw_type_for_base_type(type);
+}
+
fs_reg *
fs_visitor::variable_storage(ir_variable *var)
{
@@ -597,7 +597,18 @@ fs_visitor::visit(ir_dereference_variable *ir)
void
fs_visitor::visit(ir_dereference_record *ir)
{
- assert(!"FINISHME");
+ const glsl_type *struct_type = ir->record->type;
+
+ ir->record->accept(this);
+
+ unsigned int offset = 0;
+ for (unsigned int i = 0; i < struct_type->length; i++) {
+ if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
+ break;
+ offset += type_size(struct_type->fields.structure[i].type);
+ }
+ this->result.reg_offset += offset;
+ this->result.type = brw_type_for_base_type(ir->type);
}
void
@@ -613,21 +624,7 @@ fs_visitor::visit(ir_dereference_array *ir)
element_size = ir->type->vector_elements;
} else {
element_size = type_size(ir->type);
- switch (ir->type->base_type) {
- case GLSL_TYPE_UINT:
- this->result.type = BRW_REGISTER_TYPE_UD;
- break;
- case GLSL_TYPE_INT:
- case GLSL_TYPE_BOOL:
- this->result.type = BRW_REGISTER_TYPE_D;
- break;
- case GLSL_TYPE_FLOAT:
- this->result.type = BRW_REGISTER_TYPE_F;
- break;
- default:
- /* deref producing struct, no need to tweak type yet. */
- break;
- }
+ this->result.type = brw_type_for_base_type(ir->type);
}
if (index) {