mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 13:58:04 +02:00
gallivm: Implement brilinear filtering.
This commit is contained in:
parent
c8179ef5e8
commit
eb605701aa
1 changed files with 89 additions and 1 deletions
|
|
@ -39,12 +39,20 @@
|
|||
#include "lp_bld_arit.h"
|
||||
#include "lp_bld_const.h"
|
||||
#include "lp_bld_debug.h"
|
||||
#include "lp_bld_printf.h"
|
||||
#include "lp_bld_flow.h"
|
||||
#include "lp_bld_sample.h"
|
||||
#include "lp_bld_swizzle.h"
|
||||
#include "lp_bld_type.h"
|
||||
|
||||
|
||||
/*
|
||||
* Bri-linear factor. Use zero or any other number less than one to force
|
||||
* tri-linear filtering.
|
||||
*/
|
||||
#define BRILINEAR_FACTOR 2
|
||||
|
||||
|
||||
/**
|
||||
* Does the given texture wrap mode allow sampling the texture border color?
|
||||
* XXX maybe move this into gallium util code.
|
||||
|
|
@ -254,6 +262,79 @@ lp_build_rho(struct lp_build_sample_context *bld,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Bri-linear lod computation
|
||||
*
|
||||
* Use a piece-wise linear approximation of log2 such that:
|
||||
* - round to nearest, for values in the neighborhood of -1, 0, 1, 2, etc.
|
||||
* - linear approximation for values in the neighborhood of 0.5, 1.5., etc,
|
||||
* with the steepness specified in 'factor'
|
||||
* - exact result for 0.5, 1.5, etc.
|
||||
*
|
||||
*
|
||||
* 1.0 - /----*
|
||||
* /
|
||||
* /
|
||||
* /
|
||||
* 0.5 - *
|
||||
* /
|
||||
* /
|
||||
* /
|
||||
* 0.0 - *----/
|
||||
*
|
||||
* | |
|
||||
* 2^0 2^1
|
||||
*
|
||||
* This is a technique also commonly used in hardware:
|
||||
* - http://ixbtlabs.com/articles2/gffx/nv40-rx800-3.html
|
||||
*
|
||||
* TODO: For correctness, this should only be applied when texture is known to
|
||||
* have regular mipmaps, i.e., mipmaps derived from the base level.
|
||||
*
|
||||
* TODO: This could be done in fixed point, where applicable.
|
||||
*/
|
||||
static void
|
||||
lp_build_brilinear_lod(struct lp_build_sample_context *bld,
|
||||
LLVMValueRef lod,
|
||||
double factor,
|
||||
LLVMValueRef *out_lod_ipart,
|
||||
LLVMValueRef *out_lod_fpart)
|
||||
{
|
||||
struct lp_build_context *float_bld = &bld->float_bld;
|
||||
LLVMValueRef lod_fpart;
|
||||
float pre_offset = (factor - 0.5)/factor - 0.5;
|
||||
float post_offset = 1 - factor;
|
||||
|
||||
if (0) {
|
||||
lp_build_printf(bld->builder, "lod = %f\n", lod);
|
||||
}
|
||||
|
||||
lod = lp_build_add(float_bld, lod,
|
||||
lp_build_const_vec(float_bld->type, pre_offset));
|
||||
|
||||
lp_build_ifloor_fract(float_bld, lod, out_lod_ipart, &lod_fpart);
|
||||
|
||||
lod_fpart = lp_build_mul(float_bld, lod_fpart,
|
||||
lp_build_const_vec(float_bld->type, factor));
|
||||
|
||||
lod_fpart = lp_build_add(float_bld, lod_fpart,
|
||||
lp_build_const_vec(float_bld->type, post_offset));
|
||||
|
||||
/*
|
||||
* It's not necessary to clamp lod_fpart since:
|
||||
* - the above expression will never produce numbers greater than one.
|
||||
* - the mip filtering branch is only taken if lod_fpart is positive
|
||||
*/
|
||||
|
||||
*out_lod_fpart = lod_fpart;
|
||||
|
||||
if (0) {
|
||||
lp_build_printf(bld->builder, "lod_ipart = %i\n", *out_lod_ipart);
|
||||
lp_build_printf(bld->builder, "lod_fpart = %f\n\n", *out_lod_fpart);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate code to compute texture level of detail (lambda).
|
||||
* \param ddx partial derivatives of (s, t, r, q) with respect to X
|
||||
|
|
@ -359,7 +440,14 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
|
|||
}
|
||||
|
||||
if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
|
||||
lp_build_ifloor_fract(float_bld, lod, out_lod_ipart, out_lod_fpart);
|
||||
if (BRILINEAR_FACTOR > 1.0) {
|
||||
lp_build_brilinear_lod(bld, lod, BRILINEAR_FACTOR,
|
||||
out_lod_ipart, out_lod_fpart);
|
||||
}
|
||||
else {
|
||||
lp_build_ifloor_fract(float_bld, lod, out_lod_ipart, out_lod_fpart);
|
||||
}
|
||||
|
||||
lp_build_name(*out_lod_ipart, "lod_ipart");
|
||||
lp_build_name(*out_lod_fpart, "lod_fpart");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue