gallivm/llvmpipe: added lp_rast_shader_inputs::facing and pass through
The triangle rasterizer sets this field to indicate front/back-facing. It gets passed into the generated fragment code as another parameter. Used now for stencil front/back selection but will also be used for fragment shaders in general (see TGSI_SEMANTIC_FACE). With this commit two-sided stenciling mostly works but there's still a bug or two...
This commit is contained in:
@@ -143,7 +143,7 @@ lp_build_stencil_test(struct lp_build_context *bld,
|
||||
struct lp_build_if_state if_ctx;
|
||||
LLVMValueRef front_facing;
|
||||
LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0);
|
||||
LLVMValueRef result = NULL;
|
||||
LLVMValueRef result = bld->undef;
|
||||
|
||||
flow_ctx = lp_build_flow_create(bld->builder);
|
||||
lp_build_flow_scope_begin(flow_ctx);
|
||||
@@ -151,7 +151,7 @@ lp_build_stencil_test(struct lp_build_context *bld,
|
||||
lp_build_flow_scope_declare(flow_ctx, &result);
|
||||
|
||||
/* front_facing = face > 0.0 */
|
||||
front_facing = lp_build_cmp(bld, PIPE_FUNC_GREATER, face, zero);
|
||||
front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, "");
|
||||
|
||||
lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing);
|
||||
{
|
||||
@@ -287,7 +287,7 @@ lp_build_stencil_op(struct lp_build_context *bld,
|
||||
struct lp_build_if_state if_ctx;
|
||||
LLVMValueRef front_facing;
|
||||
LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0);
|
||||
LLVMValueRef result = NULL;
|
||||
LLVMValueRef result = bld->undef;
|
||||
|
||||
flow_ctx = lp_build_flow_create(bld->builder);
|
||||
lp_build_flow_scope_begin(flow_ctx);
|
||||
@@ -295,7 +295,7 @@ lp_build_stencil_op(struct lp_build_context *bld,
|
||||
lp_build_flow_scope_declare(flow_ctx, &result);
|
||||
|
||||
/* front_facing = face > 0.0 */
|
||||
front_facing = lp_build_cmp(bld, PIPE_FUNC_GREATER, face, zero);
|
||||
front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, "");
|
||||
|
||||
lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing);
|
||||
{
|
||||
@@ -367,11 +367,15 @@ lp_depth_type(const struct util_format_description *format_desc,
|
||||
* Generate code for performing depth and/or stencil tests.
|
||||
* We operate on a vector of values (typically a 2x2 quad).
|
||||
*
|
||||
* \param depth the depth test state
|
||||
* \param stencil the front/back stencil state
|
||||
* \param type the data type of the fragment depth/stencil values
|
||||
* \param format_desc description of the depth/stencil surface
|
||||
* \param mask the alive/dead pixel mask for the quad
|
||||
* \param src the incoming depth/stencil values (a 2x2 quad)
|
||||
* \param dst_ptr the outgoing/updated depth/stencil values
|
||||
* \param mask the alive/dead pixel mask for the quad (vector)
|
||||
* \param stencil_refs the front/back stencil ref values (scalar)
|
||||
* \param z_src the incoming depth/stencil values (a 2x2 quad)
|
||||
* \param zs_dst_ptr pointer to depth/stencil values in framebuffer
|
||||
* \param facing contains float value indicating front/back facing polygon
|
||||
*/
|
||||
void
|
||||
lp_build_depth_stencil_test(LLVMBuilderRef builder,
|
||||
@@ -382,7 +386,8 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
|
||||
struct lp_build_mask_context *mask,
|
||||
LLVMValueRef stencil_refs[2],
|
||||
LLVMValueRef z_src,
|
||||
LLVMValueRef zs_dst_ptr)
|
||||
LLVMValueRef zs_dst_ptr,
|
||||
LLVMValueRef face)
|
||||
{
|
||||
struct lp_build_context bld;
|
||||
unsigned z_swizzle, s_swizzle;
|
||||
@@ -391,7 +396,6 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
|
||||
LLVMValueRef z_bitmask = NULL, s_bitmask = NULL;
|
||||
LLVMValueRef z_pass = NULL, s_pass_mask = NULL;
|
||||
LLVMValueRef orig_mask = mask->value;
|
||||
LLVMValueRef face = NULL;
|
||||
|
||||
assert(depth->enabled || stencil[0].enabled);
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
|
||||
struct lp_build_mask_context *mask,
|
||||
LLVMValueRef stencil_refs[2],
|
||||
LLVMValueRef zs_src,
|
||||
LLVMValueRef zs_dst_ptr);
|
||||
LLVMValueRef zs_dst_ptr,
|
||||
LLVMValueRef facing);
|
||||
|
||||
|
||||
#endif /* !LP_BLD_DEPTH_H */
|
||||
|
||||
@@ -155,6 +155,7 @@ typedef void
|
||||
(*lp_jit_frag_func)(const struct lp_jit_context *context,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
float facing,
|
||||
const void *a0,
|
||||
const void *dadx,
|
||||
const void *dady,
|
||||
|
||||
@@ -314,6 +314,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
|
||||
/* run shader */
|
||||
state->jit_function[RAST_WHOLE]( &state->jit_context,
|
||||
tile_x + x, tile_y + y,
|
||||
inputs->facing,
|
||||
inputs->a0,
|
||||
inputs->dadx,
|
||||
inputs->dady,
|
||||
@@ -377,6 +378,7 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task,
|
||||
/* run shader */
|
||||
state->jit_function[RAST_EDGE_TEST]( &state->jit_context,
|
||||
x, y,
|
||||
inputs->facing,
|
||||
inputs->a0,
|
||||
inputs->dadx,
|
||||
inputs->dady,
|
||||
|
||||
@@ -82,6 +82,8 @@ struct lp_rast_state {
|
||||
* These pointers point into the bin data buffer.
|
||||
*/
|
||||
struct lp_rast_shader_inputs {
|
||||
float facing; /** Positive for front-facing, negative for back-facing */
|
||||
|
||||
float (*a0)[4];
|
||||
float (*dadx)[4];
|
||||
float (*dady)[4];
|
||||
|
||||
@@ -195,6 +195,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
|
||||
/* run shader */
|
||||
state->jit_function[0]( &state->jit_context,
|
||||
x, y,
|
||||
inputs->facing,
|
||||
inputs->a0,
|
||||
inputs->dadx,
|
||||
inputs->dady,
|
||||
|
||||
@@ -361,6 +361,8 @@ do_triangle_ccw(struct lp_setup_context *setup,
|
||||
*/
|
||||
setup_tri_coefficients( setup, tri, oneoverarea, v1, v2, v3, frontfacing );
|
||||
|
||||
tri->inputs.facing = frontfacing ? 1.0F : -1.0F;
|
||||
|
||||
/* half-edge constants, will be interated over the whole render target.
|
||||
*/
|
||||
tri->c1 = tri->dy12 * x1 - tri->dx12 * y1;
|
||||
|
||||
@@ -147,7 +147,8 @@ generate_depth_stencil(LLVMBuilderRef builder,
|
||||
struct lp_build_mask_context *mask,
|
||||
LLVMValueRef stencil_refs[2],
|
||||
LLVMValueRef src,
|
||||
LLVMValueRef dst_ptr)
|
||||
LLVMValueRef dst_ptr,
|
||||
LLVMValueRef facing)
|
||||
{
|
||||
const struct util_format_description *format_desc;
|
||||
struct lp_type dst_type;
|
||||
@@ -193,7 +194,8 @@ generate_depth_stencil(LLVMBuilderRef builder,
|
||||
mask,
|
||||
stencil_refs,
|
||||
src,
|
||||
dst_ptr);
|
||||
dst_ptr,
|
||||
facing);
|
||||
}
|
||||
|
||||
|
||||
@@ -393,6 +395,7 @@ generate_fs(struct llvmpipe_context *lp,
|
||||
LLVMValueRef *pmask,
|
||||
LLVMValueRef (*color)[4],
|
||||
LLVMValueRef depth_ptr,
|
||||
LLVMValueRef facing,
|
||||
unsigned do_tri_test,
|
||||
LLVMValueRef c0,
|
||||
LLVMValueRef c1,
|
||||
@@ -469,7 +472,7 @@ generate_fs(struct llvmpipe_context *lp,
|
||||
if (early_depth_stencil_test)
|
||||
generate_depth_stencil(builder, key,
|
||||
type, &mask,
|
||||
stencil_refs, z, depth_ptr);
|
||||
stencil_refs, z, depth_ptr, facing);
|
||||
|
||||
lp_build_tgsi_soa(builder, tokens, type, &mask,
|
||||
consts_ptr, interp->pos, interp->inputs,
|
||||
@@ -516,7 +519,7 @@ generate_fs(struct llvmpipe_context *lp,
|
||||
if (!early_depth_stencil_test)
|
||||
generate_depth_stencil(builder, key,
|
||||
type, &mask,
|
||||
stencil_refs, z, depth_ptr);
|
||||
stencil_refs, z, depth_ptr, facing);
|
||||
|
||||
lp_build_mask_end(&mask);
|
||||
|
||||
@@ -627,7 +630,7 @@ generate_fragment(struct llvmpipe_context *lp,
|
||||
LLVMTypeRef fs_int_vec_type;
|
||||
LLVMTypeRef blend_vec_type;
|
||||
LLVMTypeRef blend_int_vec_type;
|
||||
LLVMTypeRef arg_types[14];
|
||||
LLVMTypeRef arg_types[15];
|
||||
LLVMTypeRef func_type;
|
||||
LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type();
|
||||
LLVMValueRef context_ptr;
|
||||
@@ -650,6 +653,7 @@ generate_fragment(struct llvmpipe_context *lp,
|
||||
LLVMValueRef blend_mask;
|
||||
LLVMValueRef blend_in_color[NUM_CHANNELS];
|
||||
LLVMValueRef function;
|
||||
LLVMValueRef facing;
|
||||
unsigned num_fs;
|
||||
unsigned i;
|
||||
unsigned chan;
|
||||
@@ -689,20 +693,21 @@ generate_fragment(struct llvmpipe_context *lp,
|
||||
arg_types[0] = screen->context_ptr_type; /* context */
|
||||
arg_types[1] = LLVMInt32Type(); /* x */
|
||||
arg_types[2] = LLVMInt32Type(); /* y */
|
||||
arg_types[3] = LLVMPointerType(fs_elem_type, 0); /* a0 */
|
||||
arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* dadx */
|
||||
arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dady */
|
||||
arg_types[6] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */
|
||||
arg_types[7] = LLVMPointerType(fs_int_vec_type, 0); /* depth */
|
||||
arg_types[8] = LLVMInt32Type(); /* c0 */
|
||||
arg_types[9] = LLVMInt32Type(); /* c1 */
|
||||
arg_types[10] = LLVMInt32Type(); /* c2 */
|
||||
arg_types[3] = LLVMFloatType(); /* facing */
|
||||
arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* a0 */
|
||||
arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dadx */
|
||||
arg_types[6] = LLVMPointerType(fs_elem_type, 0); /* dady */
|
||||
arg_types[7] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */
|
||||
arg_types[8] = LLVMPointerType(fs_int_vec_type, 0); /* depth */
|
||||
arg_types[9] = LLVMInt32Type(); /* c0 */
|
||||
arg_types[10] = LLVMInt32Type(); /* c1 */
|
||||
arg_types[11] = LLVMInt32Type(); /* c2 */
|
||||
/* Note: the step arrays are built as int32[16] but we interpret
|
||||
* them here as int32_vec4[4].
|
||||
*/
|
||||
arg_types[11] = LLVMPointerType(int32_vec4_type, 0);/* step0 */
|
||||
arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step1 */
|
||||
arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step2 */
|
||||
arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step0 */
|
||||
arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step1 */
|
||||
arg_types[14] = LLVMPointerType(int32_vec4_type, 0);/* step2 */
|
||||
|
||||
func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
|
||||
|
||||
@@ -722,17 +727,18 @@ generate_fragment(struct llvmpipe_context *lp,
|
||||
context_ptr = LLVMGetParam(function, 0);
|
||||
x = LLVMGetParam(function, 1);
|
||||
y = LLVMGetParam(function, 2);
|
||||
a0_ptr = LLVMGetParam(function, 3);
|
||||
dadx_ptr = LLVMGetParam(function, 4);
|
||||
dady_ptr = LLVMGetParam(function, 5);
|
||||
color_ptr_ptr = LLVMGetParam(function, 6);
|
||||
depth_ptr = LLVMGetParam(function, 7);
|
||||
c0 = LLVMGetParam(function, 8);
|
||||
c1 = LLVMGetParam(function, 9);
|
||||
c2 = LLVMGetParam(function, 10);
|
||||
step0_ptr = LLVMGetParam(function, 11);
|
||||
step1_ptr = LLVMGetParam(function, 12);
|
||||
step2_ptr = LLVMGetParam(function, 13);
|
||||
facing = LLVMGetParam(function, 3);
|
||||
a0_ptr = LLVMGetParam(function, 4);
|
||||
dadx_ptr = LLVMGetParam(function, 5);
|
||||
dady_ptr = LLVMGetParam(function, 6);
|
||||
color_ptr_ptr = LLVMGetParam(function, 7);
|
||||
depth_ptr = LLVMGetParam(function, 8);
|
||||
c0 = LLVMGetParam(function, 9);
|
||||
c1 = LLVMGetParam(function, 10);
|
||||
c2 = LLVMGetParam(function, 11);
|
||||
step0_ptr = LLVMGetParam(function, 12);
|
||||
step1_ptr = LLVMGetParam(function, 13);
|
||||
step2_ptr = LLVMGetParam(function, 14);
|
||||
|
||||
lp_build_name(context_ptr, "context");
|
||||
lp_build_name(x, "x");
|
||||
@@ -791,6 +797,7 @@ generate_fragment(struct llvmpipe_context *lp,
|
||||
&fs_mask[i], /* output */
|
||||
out_color,
|
||||
depth_ptr_i,
|
||||
facing,
|
||||
do_tri_test,
|
||||
c0, c1, c2,
|
||||
step0_ptr, step1_ptr, step2_ptr);
|
||||
|
||||
Reference in New Issue
Block a user