diff options
author | Timothy Arceri <[email protected]> | 2015-10-31 10:31:37 +1100 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2015-11-04 13:38:32 +1100 |
commit | fb77da89f51fd82d5cee95400acb20ad74d9e7bc (patch) | |
tree | 02dc302c5c72b7c243ffdf851e405596da7dce7e /src/mesa/drivers/dri/i965/brw_fs_nir.cpp | |
parent | 9285ed98f7557722fbb94f47c5bc138ef5dd9c70 (diff) |
i965: add support for image AoA
V3: clamp array index to the correct size (the size of the current array
rather than the inner array) Francisco Jerez.
V2: avoid useless zero-initialization and addition for the first AoA level,
avoid redundant temporary, make use of type_size_scalar(), rename aoa_size
to element_size, assign the indirect indexing temporary directly to
image.reladdr, and replace while loop with a for loop. All suggested
by Francisco Jerez.
Reviewed-by: Francisco Jerez <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_fs_nir.cpp')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index b6eab069a1f..e7a39ff741c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -1062,18 +1062,17 @@ fs_visitor::get_nir_image_deref(const nir_deref_var *deref) fs_reg image(UNIFORM, deref->var->data.driver_location, BRW_REGISTER_TYPE_UD); - if (deref->deref.child) { - const nir_deref_array *deref_array = - nir_deref_as_array(deref->deref.child); - assert(deref->deref.child->deref_type == nir_deref_type_array && - deref_array->deref.child == NULL); - const unsigned size = glsl_get_length(deref->var->type); + for (const nir_deref *tail = &deref->deref; tail->child; + tail = tail->child) { + const nir_deref_array *deref_array = nir_deref_as_array(tail->child); + assert(tail->child->deref_type == nir_deref_type_array); + const unsigned size = glsl_get_length(tail->type); + const unsigned element_size = type_size_scalar(deref_array->deref.type); const unsigned base = MIN2(deref_array->base_offset, size - 1); - - image = offset(image, bld, base * BRW_IMAGE_PARAM_SIZE); + image = offset(image, bld, base * element_size); if (deref_array->deref_array_type == nir_deref_array_type_indirect) { - fs_reg *tmp = new(mem_ctx) fs_reg(vgrf(glsl_type::int_type)); + fs_reg tmp = vgrf(glsl_type::int_type); if (devinfo->gen == 7 && !devinfo->is_haswell) { /* IVB hangs when trying to access an invalid surface index with @@ -1084,15 +1083,18 @@ fs_visitor::get_nir_image_deref(const nir_deref_var *deref) * of the possible outcomes of the hang. Clamp the index to * prevent access outside of the array bounds. */ - bld.emit_minmax(*tmp, retype(get_nir_src(deref_array->indirect), - BRW_REGISTER_TYPE_UD), + bld.emit_minmax(tmp, retype(get_nir_src(deref_array->indirect), + BRW_REGISTER_TYPE_UD), fs_reg(size - base - 1), BRW_CONDITIONAL_L); } else { - bld.MOV(*tmp, get_nir_src(deref_array->indirect)); + bld.MOV(tmp, get_nir_src(deref_array->indirect)); } - bld.MUL(*tmp, *tmp, fs_reg(BRW_IMAGE_PARAM_SIZE)); - image.reladdr = tmp; + bld.MUL(tmp, tmp, fs_reg(element_size)); + if (image.reladdr) + bld.ADD(*image.reladdr, *image.reladdr, tmp); + else + image.reladdr = new(mem_ctx) fs_reg(tmp); } } |