#include "lp_state_setup.h"
-
/* currently organized to interpolate full float[4] attributes even
* when some elements are unused. Later, can pack vertex data more
* closely.
}
}
+/*
+ * FIXME: interpolation is always done wrt fb origin (0/0).
+ * However, if some (small) tri is far away from the origin and gradients
+ * are large, this can lead to HUGE errors, since the a0 value calculated
+ * here can get very large (with the actual values inside the triangle way
+ * smaller), leading to complete loss of accuracy. This could be prevented
+ * by using some point inside (or at corner) of the tri as interpolation
+ * origin, or just use barycentric interpolation (which GL suggests and is
+ * what real hw does - you can get the barycentric coordinates from the
+ * edge functions in rasterization in principle (though we skip these
+ * sometimes completely in case of tris covering a block fully,
+ * which obviously wouldn't work)).
+ */
static void
emit_coef4( struct gallivm_state *gallivm,
struct lp_setup_args *args,
LLVMValueRef a2)
{
LLVMBuilderRef b = gallivm->builder;
+ LLVMValueRef attr_0;
LLVMValueRef dy20_ooa = args->dy20_ooa;
LLVMValueRef dy01_ooa = args->dy01_ooa;
LLVMValueRef dx20_ooa = args->dx20_ooa;
/* Calculate a0 - the attribute value at the origin
*/
- LLVMValueRef dadx_x0 = LLVMBuildFMul(b, dadx, x0_center, "dadx_x0");
- LLVMValueRef dady_y0 = LLVMBuildFMul(b, dady, y0_center, "dady_y0");
- LLVMValueRef attr_v0 = LLVMBuildFAdd(b, dadx_x0, dady_y0, "attr_v0");
- LLVMValueRef attr_0 = LLVMBuildFSub(b, a0, attr_v0, "attr_0");
+ LLVMValueRef dadx_x0 = LLVMBuildFMul(b, dadx, x0_center, "dadx_x0");
+ LLVMValueRef dady_y0 = LLVMBuildFMul(b, dady, y0_center, "dady_y0");
+ LLVMValueRef attr_v0 = LLVMBuildFAdd(b, dadx_x0, dady_y0, "attr_v0");
+ attr_0 = LLVMBuildFSub(b, a0, attr_v0, "attr_0");
store_coef(gallivm, args, slot, attr_0, dadx, dady);
}
LLVMValueRef zeroi = lp_build_const_int32(gallivm, 0);
LLVMValueRef pixel_center, xy0_center, dxy01, dxy20, dyx20;
LLVMValueRef e, f, ef, ooa;
- LLVMValueRef shuffles[4];
+ LLVMValueRef shuffles[4], shuf10;
LLVMValueRef attr_pos[3];
struct lp_type typef4 = lp_type_float_vec(32, 128);
struct lp_build_context bld;
shuffles[1] = zeroi;
shuffles[2] = LLVMGetUndef(shuf_type);
shuffles[3] = LLVMGetUndef(shuf_type);
+ shuf10 = LLVMConstVector(shuffles, 4);
- dyx20 = LLVMBuildShuffleVector(b, dxy20, dxy20, LLVMConstVector(shuffles, 4), "");
+ dyx20 = LLVMBuildShuffleVector(b, dxy20, dxy20, shuf10, "");
ef = LLVMBuildFMul(b, dxy01, dyx20, "ef");
e = LLVMBuildExtractElement(b, ef, zeroi, "");