From: José Fonseca Date: Fri, 8 Oct 2010 12:26:37 +0000 (+0100) Subject: gallivm: Don't compute the second mipmap level when frac(lod) == 0 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4f2e2ca4e39a4c6fe11739832203a36877bdf0d8;p=mesa.git gallivm: Don't compute the second mipmap level when frac(lod) == 0 --- diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c index 5c5669bb8b7..511090ed14d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c @@ -794,63 +794,89 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, LLVMValueRef img_stride1_vec, LLVMValueRef data_ptr0, LLVMValueRef data_ptr1, - LLVMValueRef *colors_lo, - LLVMValueRef *colors_hi) + LLVMValueRef colors_lo_var, + LLVMValueRef colors_hi_var) { + LLVMBuilderRef builder = bld->builder; LLVMValueRef colors0_lo, colors0_hi; LLVMValueRef colors1_lo, colors1_hi; + /* sample the first mipmap level */ if (img_filter == PIPE_TEX_FILTER_NEAREST) { - /* sample the first mipmap level */ lp_build_sample_image_nearest(bld, width0_vec, height0_vec, depth0_vec, row_stride0_vec, img_stride0_vec, data_ptr0, s, t, r, &colors0_lo, &colors0_hi); - - if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { - /* sample the second mipmap level */ - lp_build_sample_image_nearest(bld, - width1_vec, height1_vec, depth1_vec, - row_stride1_vec, img_stride1_vec, - data_ptr1, s, t, r, - &colors1_lo, &colors1_hi); - } } else { assert(img_filter == PIPE_TEX_FILTER_LINEAR); - - /* sample the first mipmap level */ lp_build_sample_image_linear(bld, width0_vec, height0_vec, depth0_vec, row_stride0_vec, img_stride0_vec, data_ptr0, s, t, r, &colors0_lo, &colors0_hi); + } + + /* Store the first level's colors in the output variables */ + LLVMBuildStore(builder, colors0_lo, colors_lo_var); + LLVMBuildStore(builder, colors0_hi, colors_hi_var); + + if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { + LLVMValueRef h16_scale = LLVMConstReal(LLVMFloatType(), 256.0); + LLVMTypeRef i32_type = LLVMIntType(32); + struct lp_build_flow_context *flow_ctx; + struct lp_build_if_state if_ctx; + LLVMValueRef need_lerp; + + flow_ctx = lp_build_flow_create(builder); + + lod_fpart = LLVMBuildFMul(builder, lod_fpart, h16_scale, ""); + lod_fpart = LLVMBuildFPToSI(builder, lod_fpart, i32_type, "lod_fpart.fixed16"); + + /* need_lerp = lod_fpart > 0 */ + need_lerp = LLVMBuildICmp(builder, LLVMIntSGT, + lod_fpart, LLVMConstNull(i32_type), + "need_lerp"); + + lp_build_if(&if_ctx, flow_ctx, builder, need_lerp); + { + struct lp_build_context h16_bld; + + lp_build_context_init(&h16_bld, builder, lp_type_ufixed(16)); - if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { /* sample the second mipmap level */ - lp_build_sample_image_linear(bld, - width1_vec, height1_vec, depth1_vec, - row_stride1_vec, img_stride1_vec, - data_ptr1, s, t, r, - &colors1_lo, &colors1_hi); + if (img_filter == PIPE_TEX_FILTER_NEAREST) { + lp_build_sample_image_nearest(bld, + width1_vec, height1_vec, depth1_vec, + row_stride1_vec, img_stride1_vec, + data_ptr1, s, t, r, + &colors1_lo, &colors1_hi); + } + else { + lp_build_sample_image_linear(bld, + width1_vec, height1_vec, depth1_vec, + row_stride1_vec, img_stride1_vec, + data_ptr1, s, t, r, + &colors1_lo, &colors1_hi); + } + + /* interpolate samples from the two mipmap levels */ + + lod_fpart = LLVMBuildTrunc(builder, lod_fpart, h16_bld.elem_type, ""); + lod_fpart = lp_build_broadcast_scalar(&h16_bld, lod_fpart); + + colors0_lo = lp_build_lerp(&h16_bld, lod_fpart, + colors0_lo, colors1_lo); + colors0_hi = lp_build_lerp(&h16_bld, lod_fpart, + colors0_hi, colors1_hi); + + LLVMBuildStore(builder, colors0_lo, colors_lo_var); + LLVMBuildStore(builder, colors0_hi, colors_hi_var); } - } + lp_build_endif(&if_ctx); - if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { - /* interpolate samples from the two mipmap levels */ - struct lp_build_context h16; - lp_build_context_init(&h16, bld->builder, lp_type_ufixed(16)); - - *colors_lo = lp_build_lerp(&h16, lod_fpart, - colors0_lo, colors1_lo); - *colors_hi = lp_build_lerp(&h16, lod_fpart, - colors0_hi, colors1_hi); - } - else { - /* use first/only level's colors */ - *colors_lo = colors0_lo; - *colors_hi = colors0_hi; + lp_build_flow_destroy(flow_ctx); } } @@ -898,8 +924,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, LLVMValueRef packed, packed_lo, packed_hi; LLVMValueRef unswizzled[4]; LLVMValueRef face_ddx[4], face_ddy[4]; - struct lp_build_context h16; - LLVMTypeRef h16_vec_type; + struct lp_build_context h16_bld; /* we only support the common/simple wrap modes at this time */ assert(lp_is_simple_wrap_mode(bld->static_state->wrap_s)); @@ -910,9 +935,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, /* make 16-bit fixed-pt builder context */ - lp_build_context_init(&h16, builder, lp_type_ufixed(16)); - h16_vec_type = lp_build_vec_type(h16.type); - + lp_build_context_init(&h16_bld, builder, lp_type_ufixed(16)); /* cube face selection, compute pre-face coords, etc. */ if (bld->static_state->target == PIPE_TEXTURE_CUBE) { @@ -955,8 +978,6 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, /* * Compute integer mipmap level(s) to fetch texels from: ilevel0, ilevel1 - * If mipfilter=linear, also compute the weight between the two - * mipmap levels: lod_fpart */ switch (mip_filter) { default: @@ -981,22 +1002,9 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, lp_build_nearest_mip_level(bld, unit, lod_ipart, &ilevel0); break; case PIPE_TEX_MIPFILTER_LINEAR: - { - LLVMValueRef f256 = LLVMConstReal(LLVMFloatType(), 256.0); - LLVMTypeRef i32_type = LLVMIntType(32); - LLVMTypeRef i16_type = LLVMIntType(16); - - assert(lod_fpart); - - lp_build_linear_mip_levels(bld, unit, lod_ipart, &ilevel0, &ilevel1); - - lod_fpart = LLVMBuildFMul(builder, lod_fpart, f256, ""); - lod_fpart = LLVMBuildFPToSI(builder, lod_fpart, i32_type, ""); - lod_fpart = LLVMBuildTrunc(builder, lod_fpart, i16_type, ""); - lod_fpart = lp_build_broadcast_scalar(&h16, lod_fpart); - - /* the lod_fpart values will be fixed pt values in [0,1) */ - } + assert(lod_ipart); + assert(lod_fpart); + lp_build_linear_mip_levels(bld, unit, lod_ipart, &ilevel0, &ilevel1); break; } @@ -1022,13 +1030,17 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, data_ptr1 = lp_build_get_mipmap_level(bld, data_array, ilevel1); } - /* * Get/interpolate texture colors. */ + + packed_lo = lp_build_alloca(builder, h16_bld.vec_type, "packed_lo"); + packed_hi = lp_build_alloca(builder, h16_bld.vec_type, "packed_hi"); + if (min_filter == mag_filter) { /* no need to distinquish between minification and magnification */ - lp_build_sample_mipmap(bld, min_filter, mip_filter, + lp_build_sample_mipmap(bld, + min_filter, mip_filter, s, t, r, lod_fpart, width0_vec, width1_vec, height0_vec, height1_vec, @@ -1036,7 +1048,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, row_stride0_vec, row_stride1_vec, img_stride0_vec, img_stride1_vec, data_ptr0, data_ptr1, - &packed_lo, &packed_hi); + packed_lo, packed_hi); } else { /* Emit conditional to choose min image filter or mag image filter @@ -1047,13 +1059,6 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, LLVMValueRef minify; flow_ctx = lp_build_flow_create(builder); - lp_build_flow_scope_begin(flow_ctx); - - packed_lo = LLVMGetUndef(h16_vec_type); - packed_hi = LLVMGetUndef(h16_vec_type); - - lp_build_flow_scope_declare(flow_ctx, &packed_lo); - lp_build_flow_scope_declare(flow_ctx, &packed_hi); /* minify = lod >= 0.0 */ minify = LLVMBuildICmp(builder, LLVMIntSGE, @@ -1070,12 +1075,13 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, row_stride0_vec, row_stride1_vec, img_stride0_vec, img_stride1_vec, data_ptr0, data_ptr1, - &packed_lo, &packed_hi); + packed_lo, packed_hi); } lp_build_else(&if_ctx); { /* Use the magnification filter */ - lp_build_sample_mipmap(bld, mag_filter, PIPE_TEX_MIPFILTER_NONE, + lp_build_sample_mipmap(bld, + mag_filter, PIPE_TEX_MIPFILTER_NONE, s, t, r, NULL, width_vec, NULL, height_vec, NULL, @@ -1083,24 +1089,21 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, row_stride0_vec, NULL, img_stride0_vec, NULL, data_ptr0, NULL, - &packed_lo, &packed_hi); + packed_lo, packed_hi); } lp_build_endif(&if_ctx); - lp_build_flow_scope_end(flow_ctx); lp_build_flow_destroy(flow_ctx); } - /* combine 'packed_lo', 'packed_hi' into 'packed' */ - { - struct lp_build_context h16, u8n; - - lp_build_context_init(&h16, builder, lp_type_ufixed(16)); - lp_build_context_init(&u8n, builder, lp_type_unorm(8)); - - packed = lp_build_pack2(builder, h16.type, u8n.type, - packed_lo, packed_hi); - } + /* + * combine the values stored in 'packed_lo' and 'packed_hi' variables + * into 'packed' + */ + packed = lp_build_pack2(builder, + h16_bld.type, lp_type_unorm(8), + LLVMBuildLoad(builder, packed_lo, ""), + LLVMBuildLoad(builder, packed_hi, "")); /* * Convert to SoA and swizzle. diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 1883c198e57..4adce4e8b32 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -805,54 +805,76 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, LLVMValueRef data_ptr1, LLVMValueRef *colors_out) { + LLVMBuilderRef builder = bld->builder; LLVMValueRef colors0[4], colors1[4]; - int chan; + unsigned chan; + /* sample the first mipmap level */ if (img_filter == PIPE_TEX_FILTER_NEAREST) { - /* sample the first mipmap level */ lp_build_sample_image_nearest(bld, unit, width0_vec, height0_vec, depth0_vec, row_stride0_vec, img_stride0_vec, - data_ptr0, s, t, r, colors0); - - if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { - /* sample the second mipmap level */ - lp_build_sample_image_nearest(bld, unit, - width1_vec, height1_vec, depth1_vec, - row_stride1_vec, img_stride1_vec, - data_ptr1, s, t, r, colors1); - } + data_ptr0, s, t, r, + colors0); } else { assert(img_filter == PIPE_TEX_FILTER_LINEAR); - - /* sample the first mipmap level */ lp_build_sample_image_linear(bld, unit, width0_vec, height0_vec, depth0_vec, row_stride0_vec, img_stride0_vec, - data_ptr0, s, t, r, colors0); + data_ptr0, s, t, r, + colors0); + } - if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { - /* sample the second mipmap level */ - lp_build_sample_image_linear(bld, unit, - width1_vec, height1_vec, depth1_vec, - row_stride1_vec, img_stride1_vec, - data_ptr1, s, t, r, colors1); - } + /* Store the first level's colors in the output variables */ + for (chan = 0; chan < 4; chan++) { + LLVMBuildStore(builder, colors0[chan], colors_out[chan]); } if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { - /* interpolate samples from the two mipmap levels */ - for (chan = 0; chan < 4; chan++) { - colors_out[chan] = lp_build_lerp(&bld->texel_bld, lod_fpart, + struct lp_build_flow_context *flow_ctx; + struct lp_build_if_state if_ctx; + LLVMValueRef need_lerp; + + flow_ctx = lp_build_flow_create(builder); + + /* need_lerp = lod_fpart > 0 */ + need_lerp = LLVMBuildFCmp(builder, LLVMRealUGT, + lod_fpart, + bld->float_bld.zero, + "need_lerp"); + + lp_build_if(&if_ctx, flow_ctx, builder, need_lerp); + { + /* sample the second mipmap level */ + if (img_filter == PIPE_TEX_FILTER_NEAREST) { + lp_build_sample_image_nearest(bld, unit, + width1_vec, height1_vec, depth1_vec, + row_stride1_vec, img_stride1_vec, + data_ptr1, s, t, r, + colors1); + } + else { + lp_build_sample_image_linear(bld, unit, + width1_vec, height1_vec, depth1_vec, + row_stride1_vec, img_stride1_vec, + data_ptr1, s, t, r, + colors1); + } + + /* interpolate samples from the two mipmap levels */ + + lod_fpart = lp_build_broadcast_scalar(&bld->texel_bld, lod_fpart); + + for (chan = 0; chan < 4; chan++) { + colors0[chan] = lp_build_lerp(&bld->texel_bld, lod_fpart, colors0[chan], colors1[chan]); + LLVMBuildStore(builder, colors0[chan], colors_out[chan]); + } } - } - else { - /* use first/only level's colors */ - for (chan = 0; chan < 4; chan++) { - colors_out[chan] = colors0[chan]; - } + lp_build_endif(&if_ctx); + + lp_build_flow_destroy(flow_ctx); } } @@ -885,6 +907,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld, LLVMValueRef *colors_out) { struct lp_build_context *int_bld = &bld->int_bld; + LLVMBuilderRef builder = bld->builder; const unsigned mip_filter = bld->static_state->min_mip_filter; const unsigned min_filter = bld->static_state->min_img_filter; const unsigned mag_filter = bld->static_state->mag_img_filter; @@ -897,6 +920,8 @@ lp_build_sample_general(struct lp_build_sample_context *bld, LLVMValueRef img_stride0_vec = NULL, img_stride1_vec = NULL; LLVMValueRef data_ptr0, data_ptr1 = NULL; LLVMValueRef face_ddx[4], face_ddy[4]; + LLVMValueRef texels[4]; + unsigned chan; /* printf("%s mip %d min %d mag %d\n", __FUNCTION__, @@ -945,9 +970,13 @@ lp_build_sample_general(struct lp_build_sample_context *bld, } /* - * Compute integer mipmap level(s) to fetch texels from. + * Compute integer mipmap level(s) to fetch texels from: ilevel0, ilevel1 */ - if (mip_filter == PIPE_TEX_MIPFILTER_NONE) { + switch (mip_filter) { + default: + assert(0 && "bad mip_filter value in lp_build_sample_soa()"); + /* fall-through */ + case PIPE_TEX_MIPFILTER_NONE: /* always use mip level 0 */ if (bld->static_state->target == PIPE_TEXTURE_CUBE) { /* XXX this is a work-around for an apparent bug in LLVM 2.7. @@ -960,17 +989,16 @@ lp_build_sample_general(struct lp_build_sample_context *bld, else { ilevel0 = LLVMConstInt(LLVMInt32Type(), 0, 0); } - } - else { + break; + case PIPE_TEX_MIPFILTER_NEAREST: assert(lod_ipart); - if (mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { - lp_build_nearest_mip_level(bld, unit, lod_ipart, &ilevel0); - } - else { - assert(mip_filter == PIPE_TEX_MIPFILTER_LINEAR); - lp_build_linear_mip_levels(bld, unit, lod_ipart, &ilevel0, &ilevel1); - lod_fpart = lp_build_broadcast_scalar(&bld->coord_bld, lod_fpart); - } + lp_build_nearest_mip_level(bld, unit, lod_ipart, &ilevel0); + break; + case PIPE_TEX_MIPFILTER_LINEAR: + assert(lod_ipart); + assert(lod_fpart); + lp_build_linear_mip_levels(bld, unit, lod_ipart, &ilevel0, &ilevel1); + break; } /* compute image size(s) of source mipmap level(s) */ @@ -998,39 +1026,40 @@ lp_build_sample_general(struct lp_build_sample_context *bld, /* * Get/interpolate texture colors. */ + + for (chan = 0; chan < 4; ++chan) { + texels[chan] = lp_build_alloca(builder, bld->texel_bld.vec_type, ""); + lp_build_name(texels[chan], "sampler%u_texel_%c_var", unit, "xyzw"[chan]); + } + if (min_filter == mag_filter) { /* no need to distinquish between minification and magnification */ lp_build_sample_mipmap(bld, unit, - min_filter, mip_filter, s, t, r, lod_fpart, + min_filter, mip_filter, + s, t, r, lod_fpart, width0_vec, width1_vec, height0_vec, height1_vec, depth0_vec, depth1_vec, row_stride0_vec, row_stride1_vec, img_stride0_vec, img_stride1_vec, data_ptr0, data_ptr1, - colors_out); + texels); } else { /* Emit conditional to choose min image filter or mag image filter - * depending on the lod being >0 or <= 0, respectively. + * depending on the lod being > 0 or <= 0, respectively. */ struct lp_build_flow_context *flow_ctx; struct lp_build_if_state if_ctx; LLVMValueRef minify; - flow_ctx = lp_build_flow_create(bld->builder); - lp_build_flow_scope_begin(flow_ctx); - - lp_build_flow_scope_declare(flow_ctx, &colors_out[0]); - lp_build_flow_scope_declare(flow_ctx, &colors_out[1]); - lp_build_flow_scope_declare(flow_ctx, &colors_out[2]); - lp_build_flow_scope_declare(flow_ctx, &colors_out[3]); + flow_ctx = lp_build_flow_create(builder); /* minify = lod >= 0.0 */ - minify = LLVMBuildICmp(bld->builder, LLVMIntSGE, + minify = LLVMBuildICmp(builder, LLVMIntSGE, lod_ipart, int_bld->zero, ""); - lp_build_if(&if_ctx, flow_ctx, bld->builder, minify); + lp_build_if(&if_ctx, flow_ctx, builder, minify); { /* Use the minification filter */ lp_build_sample_mipmap(bld, unit, @@ -1042,7 +1071,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld, row_stride0_vec, row_stride1_vec, img_stride0_vec, img_stride1_vec, data_ptr0, data_ptr1, - colors_out); + texels); } lp_build_else(&if_ctx); { @@ -1056,13 +1085,17 @@ lp_build_sample_general(struct lp_build_sample_context *bld, row_stride0_vec, NULL, img_stride0_vec, NULL, data_ptr0, NULL, - colors_out); + texels); } lp_build_endif(&if_ctx); - lp_build_flow_scope_end(flow_ctx); lp_build_flow_destroy(flow_ctx); } + + for (chan = 0; chan < 4; ++chan) { + colors_out[chan] = LLVMBuildLoad(builder, texels[chan], ""); + lp_build_name(colors_out[chan], "sampler%u_texel_%c", unit, "xyzw"[chan]); + } }