Reviewed-by: Bruce Cherniak <bruce.chern...@intel.com> > On Apr 13, 2017, at 3:30 PM, George Kyriazis <george.kyria...@intel.com> > wrote: > > Add polygon stipple functionality to the fragment shader. > > Explicitly turn off polygon stipple for lines and points, since we > do them using tris. > --- > src/gallium/drivers/swr/swr_context.h | 4 ++- > src/gallium/drivers/swr/swr_shader.cpp | 56 ++++++++++++++++++++++++++++++---- > src/gallium/drivers/swr/swr_shader.h | 1 + > src/gallium/drivers/swr/swr_state.cpp | 27 ++++++++++++++-- > src/gallium/drivers/swr/swr_state.h | 5 +++ > 5 files changed, 84 insertions(+), 9 deletions(-) > > diff --git a/src/gallium/drivers/swr/swr_context.h > b/src/gallium/drivers/swr/swr_context.h > index be65a20..9d80c70 100644 > --- a/src/gallium/drivers/swr/swr_context.h > +++ b/src/gallium/drivers/swr/swr_context.h > @@ -98,6 +98,8 @@ struct swr_draw_context { > > float userClipPlanes[PIPE_MAX_CLIP_PLANES][4]; > > + uint32_t polyStipple[32]; > + > SWR_SURFACE_STATE renderTargets[SWR_NUM_ATTACHMENTS]; > void *pStats; > }; > @@ -127,7 +129,7 @@ struct swr_context { > struct pipe_constant_buffer > constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; > struct pipe_framebuffer_state framebuffer; > - struct pipe_poly_stipple poly_stipple; > + struct swr_poly_stipple poly_stipple; > struct pipe_scissor_state scissor; > SWR_RECT swr_scissor; > struct pipe_sampler_view * > diff --git a/src/gallium/drivers/swr/swr_shader.cpp > b/src/gallium/drivers/swr/swr_shader.cpp > index 6fc0596..d8f5512 100644 > --- a/src/gallium/drivers/swr/swr_shader.cpp > +++ b/src/gallium/drivers/swr/swr_shader.cpp > @@ -165,6 +165,9 @@ swr_generate_fs_key(struct swr_jit_fs_key &key, > sizeof(key.vs_output_semantic_idx)); > > swr_generate_sampler_key(swr_fs->info, ctx, PIPE_SHADER_FRAGMENT, key); > + > + key.poly_stipple_enable = ctx->rasterizer->poly_stipple_enable && > + ctx->poly_stipple.prim_is_poly; > } > > void > @@ -1099,17 +1102,58 @@ BuilderSWR::CompileFS(struct swr_context *ctx, > swr_jit_fs_key &key) > memset(&system_values, 0, sizeof(system_values)); > > struct lp_build_mask_context mask; > + bool uses_mask = false; > > - if (swr_fs->info.base.uses_kill) { > - Value *mask_val = LOAD(pPS, {0, SWR_PS_CONTEXT_activeMask}, > "activeMask"); > + if (swr_fs->info.base.uses_kill || > + key.poly_stipple_enable) { > + Value *vActiveMask = NULL; > + if (swr_fs->info.base.uses_kill) { > + vActiveMask = LOAD(pPS, {0, SWR_PS_CONTEXT_activeMask}, > "activeMask"); > + } > + if (key.poly_stipple_enable) { > + // first get fragment xy coords and clip to stipple bounds > + Value *vXf = LOAD(pPS, {0, SWR_PS_CONTEXT_vX, PixelPositions_UL}); > + Value *vYf = LOAD(pPS, {0, SWR_PS_CONTEXT_vY, PixelPositions_UL}); > + Value *vXu = FP_TO_UI(vXf, mSimdInt32Ty); > + Value *vYu = FP_TO_UI(vYf, mSimdInt32Ty); > + > + // stipple pattern is 32x32, which means that one line of stipple > + // is stored in one word: > + // vXstipple is bit offset inside 32-bit stipple word > + // vYstipple is word index is stipple array > + Value *vXstipple = AND(vXu, VIMMED1(0x1f)); // & (32-1) > + Value *vYstipple = AND(vYu, VIMMED1(0x1f)); // & (32-1) > + > + // grab stipple pattern base address > + Value *stipplePtr = GEP(hPrivateData, {0, > swr_draw_context_polyStipple, 0}); > + stipplePtr = BITCAST(stipplePtr, mInt8PtrTy); > + > + // peform a gather to grab stipple words for each lane > + Value *vStipple = GATHERDD(VUNDEF_I(), stipplePtr, vYstipple, > + VIMMED1(0xffffffff), C((char)4)); > + > + // create a mask with one bit corresponding to the x stipple > + // and AND it with the pattern, to see if we have a bit > + Value *vBitMask = LSHR(VIMMED1(0x80000000), vXstipple); > + Value *vStippleMask = AND(vStipple, vBitMask); > + vStippleMask = ICMP_NE(vStippleMask, VIMMED1(0)); > + vStippleMask = VMASK(vStippleMask); > + > + if (swr_fs->info.base.uses_kill) { > + vActiveMask = AND(vActiveMask, vStippleMask); > + } else { > + vActiveMask = vStippleMask; > + } > + } > lp_build_mask_begin( > - &mask, gallivm, lp_type_float_vec(32, 32 * 8), wrap(mask_val)); > + &mask, gallivm, lp_type_float_vec(32, 32 * 8), wrap(vActiveMask)); > + uses_mask = true; > } > > lp_build_tgsi_soa(gallivm, > swr_fs->pipe.tokens, > lp_type_float_vec(32, 32 * 8), > - swr_fs->info.base.uses_kill ? &mask : NULL, // mask > + uses_mask ? &mask : NULL, // mask > wrap(consts_ptr), > wrap(const_sizes_ptr), > &system_values, > @@ -1172,13 +1216,13 @@ BuilderSWR::CompileFS(struct swr_context *ctx, > swr_jit_fs_key &key) > } > > LLVMValueRef mask_result = 0; > - if (swr_fs->info.base.uses_kill) { > + if (uses_mask) { > mask_result = lp_build_mask_end(&mask); > } > > IRB()->SetInsertPoint(unwrap(LLVMGetInsertBlock(gallivm->builder))); > > - if (swr_fs->info.base.uses_kill) { > + if (uses_mask) { > STORE(unwrap(mask_result), pPS, {0, SWR_PS_CONTEXT_activeMask}); > } > > diff --git a/src/gallium/drivers/swr/swr_shader.h > b/src/gallium/drivers/swr/swr_shader.h > index c9df5b0..1ab6846 100644 > --- a/src/gallium/drivers/swr/swr_shader.h > +++ b/src/gallium/drivers/swr/swr_shader.h > @@ -66,6 +66,7 @@ struct swr_jit_fs_key : swr_jit_sampler_key { > unsigned sprite_coord_enable; > ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; > ubyte vs_output_semantic_idx[PIPE_MAX_SHADER_OUTPUTS]; > + bool poly_stipple_enable; > }; > > struct swr_jit_vs_key : swr_jit_sampler_key { > diff --git a/src/gallium/drivers/swr/swr_state.cpp > b/src/gallium/drivers/swr/swr_state.cpp > index 5cc01dd..4f7ef66 100644 > --- a/src/gallium/drivers/swr/swr_state.cpp > +++ b/src/gallium/drivers/swr/swr_state.cpp > @@ -39,6 +39,7 @@ > #include "util/u_helpers.h" > #include "util/u_framebuffer.h" > #include "util/u_viewport.h" > +#include "util/u_prim.h" > > #include "swr_state.h" > #include "swr_context.h" > @@ -608,7 +609,7 @@ swr_set_polygon_stipple(struct pipe_context *pipe, > { > struct swr_context *ctx = swr_context(pipe); > > - ctx->poly_stipple = *stipple; /* struct copy */ > + ctx->poly_stipple.pipe = *stipple; /* struct copy */ > ctx->dirty |= SWR_NEW_STIPPLE; > } > > @@ -952,6 +953,17 @@ swr_user_vbuf_range(const struct pipe_draw_info *info, > } > } > > +static void > +swr_update_poly_stipple(struct swr_context *ctx) > +{ > + struct swr_draw_context *pDC = &ctx->swrDC; > + > + assert(sizeof(ctx->poly_stipple.pipe.stipple) == > sizeof(pDC->polyStipple)); > + memcpy(pDC->polyStipple, > + ctx->poly_stipple.pipe.stipple, > + sizeof(ctx->poly_stipple.pipe.stipple)); > +} > + > void > swr_update_derived(struct pipe_context *pipe, > const struct pipe_draw_info *p_draw_info) > @@ -1352,6 +1364,17 @@ swr_update_derived(struct pipe_context *pipe, > } > } > > + /* work around the fact that poly stipple also affects lines */ > + /* and points, since we rasterize them as triangles, too */ > + /* Has to be before fragment shader, since it sets SWR_NEW_FS */ > + if (p_draw_info) { > + bool new_prim_is_poly = (u_reduced_prim(p_draw_info->mode) == > PIPE_PRIM_TRIANGLES); > + if (new_prim_is_poly != ctx->poly_stipple.prim_is_poly) { > + ctx->dirty |= SWR_NEW_FS; > + ctx->poly_stipple.prim_is_poly = new_prim_is_poly; > + } > + } > + > /* FragmentShader */ > if (ctx->dirty & (SWR_NEW_FS | > SWR_NEW_VS | > @@ -1606,7 +1629,7 @@ swr_update_derived(struct pipe_context *pipe, > } > > if (ctx->dirty & SWR_NEW_STIPPLE) { > - /* XXX What to do with this one??? SWR doesn't stipple */ > + swr_update_poly_stipple(ctx); > } > > if (ctx->dirty & (SWR_NEW_VS | SWR_NEW_SO | SWR_NEW_RASTERIZER)) { > diff --git a/src/gallium/drivers/swr/swr_state.h > b/src/gallium/drivers/swr/swr_state.h > index c89e303..9a8c4e1 100644 > --- a/src/gallium/drivers/swr/swr_state.h > +++ b/src/gallium/drivers/swr/swr_state.h > @@ -92,6 +92,11 @@ struct swr_blend_state { > RENDER_TARGET_BLEND_COMPILE_STATE compileState[PIPE_MAX_COLOR_BUFS]; > }; > > +struct swr_poly_stipple { > + struct pipe_poly_stipple pipe; > + bool prim_is_poly; > +}; > + > /* > * Derived SWR API DrawState > * For convenience of making simple changes without re-deriving state. > -- > 2.7.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev