[Mesa-dev] [PATCH 1/3] gallivm: handle cube map arrays for texture sampling
Roland Scheidegger
sroland at vmware.com
Thu Aug 28 09:25:52 PDT 2014
Am 28.08.2014 18:19, schrieb Jose Fonseca:
> On 28/08/14 04:15, sroland at vmware.com wrote:
>> From: Roland Scheidegger <sroland at vmware.com>
>>
>> Pretty easy, just make sure that all paths testing for PIPE_TEXTURE_CUBE
>> also recognize PIPE_TEXTURE_CUBE_ARRAY, and add the layer * 6 calculation
>> to the calculated face.
>> Also handle it for texture size query, looks like OpenGL wants the number
>> of cubes, not layers (so need division by 6).
>>
>> No piglit regressions.
>> ---
>> src/gallium/auxiliary/gallivm/lp_bld_sample.c | 5 +-
>> src/gallium/auxiliary/gallivm/lp_bld_sample.h | 17 ++++++-
>> src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c | 16 ++----
>> src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 59
>> ++++++++++++++++-------
>> src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 2 +-
>> 5 files changed, 62 insertions(+), 37 deletions(-)
>>
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
>> b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
>> index f1bf285..85c0d4e 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
>> @@ -1313,10 +1313,7 @@ lp_build_mipmap_level_sizes(struct
>> lp_build_sample_context *bld,
>>
>> bld->row_stride_array,
>> ilevel);
>> }
>> - if (dims == 3 ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
>> + if (dims == 3 ||
>> has_layer_coord(bld->static_texture_state->target)) {
>> *img_stride_vec = lp_build_get_level_stride_vec(bld,
>>
>> bld->img_stride_array,
>> ilevel);
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
>> b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
>> index fd4e053..be05b13 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
>> @@ -356,9 +356,7 @@ texture_dims(enum pipe_texture_target tex)
>> case PIPE_TEXTURE_2D_ARRAY:
>> case PIPE_TEXTURE_RECT:
>> case PIPE_TEXTURE_CUBE:
>> - return 2;
>> case PIPE_TEXTURE_CUBE_ARRAY:
>> - assert(0);
>> return 2;
>> case PIPE_TEXTURE_3D:
>> return 3;
>> @@ -368,6 +366,21 @@ texture_dims(enum pipe_texture_target tex)
>> }
>> }
>>
>> +static INLINE boolean
>> +has_layer_coord(enum pipe_texture_target tex)
>> +{
>> + switch (tex) {
>> + case PIPE_TEXTURE_1D_ARRAY:
>> + case PIPE_TEXTURE_2D_ARRAY:
>> + /* cube is not layered but 3rd coord (after cube mapping) behaves
>> the same */
>> + case PIPE_TEXTURE_CUBE:
>> + case PIPE_TEXTURE_CUBE_ARRAY:
>> + return TRUE;
>> + default:
>> + return FALSE;
>> + }
>> +}
>> +
>>
>> boolean
>> lp_sampler_wrap_mode_uses_border_color(unsigned mode,
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
>> b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
>> index 2f02606..394521d 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
>> @@ -704,9 +704,7 @@ lp_build_sample_image_nearest(struct
>> lp_build_sample_context *bld,
>> offset = lp_build_add(&bld->int_coord_bld, offset, z_offset);
>> }
>> }
>> - if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
>> + if (has_layer_coord(bld->static_texture_state->target)) {
>> LLVMValueRef z_offset;
>> /* The r coord is the cube face in [0,5] or array layer */
>> z_offset = lp_build_mul(&bld->int_coord_bld, r, img_stride_vec);
>> @@ -781,9 +779,7 @@ lp_build_sample_image_nearest_afloat(struct
>> lp_build_sample_context *bld,
>> &z_icoord);
>> }
>> }
>> - if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
>> + if (has_layer_coord(bld->static_texture_state->target)) {
>> z_icoord = r;
>> }
>>
>> @@ -1130,9 +1126,7 @@ lp_build_sample_image_linear(struct
>> lp_build_sample_context *bld,
>> &x_subcoord[0], &x_subcoord[1]);
>>
>> /* add potential cube/array/mip offsets now as they are constant
>> per pixel */
>> - if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
>> + if (has_layer_coord(bld->static_texture_state->target)) {
>> LLVMValueRef z_offset;
>> z_offset = lp_build_mul(&bld->int_coord_bld, r, img_stride_vec);
>> /* The r coord is the cube face in [0,5] or array layer */
>> @@ -1301,9 +1295,7 @@ lp_build_sample_image_linear_afloat(struct
>> lp_build_sample_context *bld,
>> &x_offset1, &x_subcoord[1]);
>>
>> /* add potential cube/array/mip offsets now as they are constant
>> per pixel */
>> - if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
>> + if (has_layer_coord(bld->static_texture_state->target)) {
>> LLVMValueRef z_offset;
>> z_offset = lp_build_mul(&bld->int_coord_bld, r, img_stride_vec);
>> /* The r coord is the cube face in [0,5] or array layer */
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
>> b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
>> index e29f503..ec9f851 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
>> @@ -752,9 +752,7 @@ lp_build_sample_image_nearest(struct
>> lp_build_sample_context *bld,
>> lp_build_name(z, "tex.z.wrapped");
>> }
>> }
>> - if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
>> + if (has_layer_coord(bld->static_texture_state->target)) {
>> z = coords[2];
>> lp_build_name(z, "tex.z.layer");
>> }
>> @@ -868,7 +866,8 @@ lp_build_sample_image_linear(struct
>> lp_build_sample_context *bld,
>> int chan, texel_index;
>> boolean seamless_cube_filter, accurate_cube_corners;
>>
>> - seamless_cube_filter = bld->static_texture_state->target ==
>> PIPE_TEXTURE_CUBE &&
>> + seamless_cube_filter = (bld->static_texture_state->target ==
>> PIPE_TEXTURE_CUBE ||
>> + bld->static_texture_state->target ==
>> PIPE_TEXTURE_CUBE_ARRAY) &&
>> bld->static_sampler_state->seamless_cube_map;
>> accurate_cube_corners = ACCURATE_CUBE_CORNERS &&
>> seamless_cube_filter;
>>
>> @@ -923,9 +922,7 @@ lp_build_sample_image_linear(struct
>> lp_build_sample_context *bld,
>> lp_build_name(z1, "tex.z1.wrapped");
>> }
>> }
>> - if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
>> - bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
>> + if (has_layer_coord(bld->static_texture_state->target)) {
>> z00 = z01 = z10 = z11 = z1 = coords[2]; /* cube face or
>> layer */
>> lp_build_name(z00, "tex.z0.layer");
>> lp_build_name(z1, "tex.z1.layer");
>> @@ -1644,6 +1641,7 @@ lp_build_sample_mipmap_both(struct
>> lp_build_sample_context *bld,
>> static LLVMValueRef
>> lp_build_layer_coord(struct lp_build_sample_context *bld,
>> unsigned texture_unit,
>> + boolean is_cube_array,
>> LLVMValueRef layer,
>> LLVMValueRef *out_of_bounds)
>> {
>> @@ -1655,6 +1653,7 @@ lp_build_layer_coord(struct
>> lp_build_sample_context *bld,
>>
>> if (out_of_bounds) {
>> LLVMValueRef out1, out;
>> + assert(!is_cube_array);
>> num_layers = lp_build_broadcast_scalar(int_coord_bld,
>> num_layers);
>> out = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, layer,
>> int_coord_bld->zero);
>> out1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, layer,
>> num_layers);
>> @@ -1663,7 +1662,9 @@ lp_build_layer_coord(struct
>> lp_build_sample_context *bld,
>> }
>> else {
>> LLVMValueRef maxlayer;
>> - maxlayer = lp_build_sub(&bld->int_bld, num_layers,
>> bld->int_bld.one);
>> + LLVMValueRef s = is_cube_array ?
>> lp_build_const_int32(bld->gallivm, 6) :
>> + bld->int_bld.one;
>> + maxlayer = lp_build_sub(&bld->int_bld, num_layers, s);
>> maxlayer = lp_build_broadcast_scalar(int_coord_bld, maxlayer);
>> return lp_build_clamp(int_coord_bld, layer,
>> int_coord_bld->zero, maxlayer);
>> }
>> @@ -1703,7 +1704,7 @@ lp_build_sample_common(struct
>> lp_build_sample_context *bld,
>> * Choose cube face, recompute texcoords for the chosen face and
>> * compute rho here too (as it requires transform of derivatives).
>> */
>> - if (target == PIPE_TEXTURE_CUBE) {
>> + if (target == PIPE_TEXTURE_CUBE || target ==
>> PIPE_TEXTURE_CUBE_ARRAY) {
>> boolean need_derivs;
>> need_derivs = ((min_filter != mag_filter ||
>> mip_filter != PIPE_TEX_MIPFILTER_NONE) &&
>> @@ -1711,11 +1712,19 @@ lp_build_sample_common(struct
>> lp_build_sample_context *bld,
>> !explicit_lod);
>> lp_build_cube_lookup(bld, coords, derivs, &cube_rho,
>> &cube_derivs, need_derivs);
>> derivs = &cube_derivs;
>> + if (target == PIPE_TEXTURE_CUBE_ARRAY) {
>> + /* just add effective layer to face coord now */
>> + LLVMValueRef layer = lp_build_iround(&bld->coord_bld,
>> coords[3]);
>> + LLVMValueRef six = lp_build_const_int_vec(bld->gallivm,
>> bld->int_coord_type, 6);
>> + layer = lp_build_mul(&bld->int_coord_bld, layer, six);
>> + layer = lp_build_layer_coord(bld, texture_index, TRUE,
>> layer, NULL);
>> + coords[2] = lp_build_add(&bld->int_coord_bld, coords[2],
>> layer);
>> + }
>> }
>> else if (target == PIPE_TEXTURE_1D_ARRAY ||
>> target == PIPE_TEXTURE_2D_ARRAY) {
>> coords[2] = lp_build_iround(&bld->coord_bld, coords[2]);
>> - coords[2] = lp_build_layer_coord(bld, texture_index, coords[2],
>> NULL);
>> + coords[2] = lp_build_layer_coord(bld, texture_index, FALSE,
>> coords[2], NULL);
>> }
>>
>> if (bld->static_sampler_state->compare_mode !=
>> PIPE_TEX_COMPARE_NONE) {
>> @@ -2223,11 +2232,11 @@ lp_build_fetch_texel(struct
>> lp_build_sample_context *bld,
>> if (target == PIPE_TEXTURE_1D_ARRAY ||
>> target == PIPE_TEXTURE_2D_ARRAY) {
>> if (out_of_bound_ret_zero) {
>> - z = lp_build_layer_coord(bld, texture_unit, z, &out1);
>> + z = lp_build_layer_coord(bld, texture_unit, FALSE, z, &out1);
>> out_of_bounds = lp_build_or(int_coord_bld, out_of_bounds,
>> out1);
>> }
>> else {
>> - z = lp_build_layer_coord(bld, texture_unit, z, NULL);
>> + z = lp_build_layer_coord(bld, texture_unit, FALSE, z, NULL);
>> }
>> }
>>
>> @@ -2463,7 +2472,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>>
>> if ((gallivm_debug & GALLIVM_DEBUG_NO_QUAD_LOD) &&
>> (gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX) &&
>> - (static_texture_state->target == PIPE_TEXTURE_CUBE) &&
>> + (static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> + static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY) &&
>> (!is_fetch && mip_filter != PIPE_TEX_MIPFILTER_NONE)) {
>> /*
>> * special case for using per-pixel lod even for implicit lod,
>> @@ -2601,7 +2611,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>> use_aos &=
>> lp_is_simple_wrap_mode(derived_sampler_state.wrap_r);
>> }
>> }
>> - if (static_texture_state->target == PIPE_TEXTURE_CUBE &&
>> + if ((static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> + static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY) &&
>> derived_sampler_state.seamless_cube_map &&
>> (derived_sampler_state.min_img_filter ==
>> PIPE_TEX_FILTER_LINEAR ||
>> derived_sampler_state.mag_img_filter ==
>> PIPE_TEX_FILTER_LINEAR)) {
>> @@ -2695,7 +2706,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>> bld4.num_mips = bld4.num_lods = 1;
>> if ((gallivm_debug & GALLIVM_DEBUG_NO_QUAD_LOD) &&
>> (gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX) &&
>> - (static_texture_state->target == PIPE_TEXTURE_CUBE) &&
>> + (static_texture_state->target == PIPE_TEXTURE_CUBE ||
>> + static_texture_state->target ==
>> PIPE_TEXTURE_CUBE_ARRAY) &&
>> (!is_fetch && mip_filter != PIPE_TEX_MIPFILTER_NONE)) {
>> bld4.num_mips = type4.length;
>> bld4.num_lods = type4.length;
>> @@ -2891,6 +2903,7 @@ lp_build_size_query_soa(struct gallivm_state
>> *gallivm,
>> switch (target) {
>> case PIPE_TEXTURE_1D_ARRAY:
>> case PIPE_TEXTURE_2D_ARRAY:
>> + case PIPE_TEXTURE_CUBE_ARRAY:
>> has_array = TRUE;
>> break;
>> default:
>> @@ -2932,10 +2945,20 @@ lp_build_size_query_soa(struct gallivm_state
>> *gallivm,
>>
>> size = lp_build_minify(&bld_int_vec4, size, lod, TRUE);
>>
>> - if (has_array)
>> - size = LLVMBuildInsertElement(gallivm->builder, size,
>> -
>> dynamic_state->depth(dynamic_state, gallivm, texture_unit),
>> + if (has_array) {
>> + LLVMValueRef layers = dynamic_state->depth(dynamic_state,
>> gallivm, texture_unit);
>> + if (target == PIPE_TEXTURE_CUBE_ARRAY) {
>> + /*
>> + * It looks like GL wants number of cubes, d3d10.1 has it
>> undefined?
>> + * Could avoid this by passing in number of cubes instead of
>> total
>> + * number of layers (might make things easier elsewhere too).
>> + */
>> + LLVMValueRef six = lp_build_const_int32(gallivm, 6);
>> + layers = LLVMBuildSDiv(gallivm->builder, layers, six, "");
>> + }
>> + size = LLVMBuildInsertElement(gallivm->builder, size, layers,
>> lp_build_const_int32(gallivm,
>> dims), "");
>> + }
>>
>> /*
>> * d3d10 requires zero for x/y/z values (but not w, i.e. mip levels)
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> index 93c926a..6731e32 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
>> @@ -2333,7 +2333,7 @@ emit_fetch_texels( struct
>> lp_build_tgsi_soa_context *bld,
>> unsigned unit, target;
>> LLVMValueRef coord_undef =
>> LLVMGetUndef(bld->bld_base.base.int_vec_type);
>> LLVMValueRef explicit_lod = NULL;
>> - LLVMValueRef coords[3];
>> + LLVMValueRef coords[5];
>
>
> Is this really necessary? AFAICT, only coord[0..2] is ever writte.
I noticed we copy all 5 array members unconditionally later in
lp_build_sample_soa(), even though clearly in this case they won't be
used, that's why I added it. Blame the sampling interface...
>
> Otherwise series looks good AFAICT. (Though I only skimmed through
> softpipe.)
Thanks! I had to send out a new version though which has some hope to
work with seamless too...
Roland
> Jose
>
>> LLVMValueRef offsets[3] = { NULL };
>> enum lp_sampler_lod_property lod_property = LP_SAMPLER_LOD_SCALAR;
>> unsigned dims, i;
>>
>
More information about the mesa-dev
mailing list