Reviewed-by: Bruce Cherniak <bruce.chern...@intel.com> > On Jun 8, 2016, at 9:59 AM, Tim Rowley <timothy.o.row...@intel.com> wrote: > > v2: only load the clip vertex once > > v3: fix clip enable logic, add cullDistance > > v4: remove duplicate fields in vs jit key, fix test of clip fixup needed > > v5: fix clipdistance linkage for slot!=0,4 > > v6: support clip+cull; passes most piglit clip (failures understood) > --- > docs/GL3.txt | 2 +- > src/gallium/drivers/swr/swr_context.h | 2 ++ > src/gallium/drivers/swr/swr_screen.cpp | 3 +- > src/gallium/drivers/swr/swr_shader.cpp | 65 ++++++++++++++++++++++++++++++++++ > src/gallium/drivers/swr/swr_shader.h | 1 + > src/gallium/drivers/swr/swr_state.cpp | 25 ++++++++++++- > 6 files changed, 95 insertions(+), 3 deletions(-) > > diff --git a/docs/GL3.txt b/docs/GL3.txt > index e8d401d..4ba0366 100644 > --- a/docs/GL3.txt > +++ b/docs/GL3.txt > @@ -211,7 +211,7 @@ GL 4.5, GLSL 4.50: > GL_ARB_ES3_1_compatibility DONE (nvc0, radeonsi) > GL_ARB_clip_control DONE (i965, nv50, > nvc0, r600, radeonsi, llvmpipe, softpipe, swr) > GL_ARB_conditional_render_inverted DONE (i965, nv50, > nvc0, r600, radeonsi, llvmpipe, softpipe, swr) > - GL_ARB_cull_distance DONE (i965, nv50, > nvc0, llvmpipe, softpipe) > + GL_ARB_cull_distance DONE (i965, nv50, > nvc0, llvmpipe, softpipe, swr) > GL_ARB_derivative_control DONE (i965, nv50, > nvc0, r600, radeonsi) > GL_ARB_direct_state_access DONE (all drivers) > GL_ARB_get_texture_sub_image DONE (all drivers) > diff --git a/src/gallium/drivers/swr/swr_context.h > b/src/gallium/drivers/swr/swr_context.h > index a7383bb..75ecae3 100644 > --- a/src/gallium/drivers/swr/swr_context.h > +++ b/src/gallium/drivers/swr/swr_context.h > @@ -89,6 +89,8 @@ struct swr_draw_context { > swr_jit_texture texturesFS[PIPE_MAX_SHADER_SAMPLER_VIEWS]; > swr_jit_sampler samplersFS[PIPE_MAX_SAMPLERS]; > > + float userClipPlanes[PIPE_MAX_CLIP_PLANES][4]; > + > SWR_SURFACE_STATE renderTargets[SWR_NUM_ATTACHMENTS]; > }; > > diff --git a/src/gallium/drivers/swr/swr_screen.cpp > b/src/gallium/drivers/swr/swr_screen.cpp > index ca39202..af82c93 100644 > --- a/src/gallium/drivers/swr/swr_screen.cpp > +++ b/src/gallium/drivers/swr/swr_screen.cpp > @@ -333,6 +333,8 @@ swr_get_param(struct pipe_screen *screen, enum pipe_cap > param) > case PIPE_CAP_TEXTURE_FLOAT_LINEAR: > case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: > return 1; > + case PIPE_CAP_CULL_DISTANCE: > + return 1; > case PIPE_CAP_TGSI_TXQS: > case PIPE_CAP_FORCE_PERSAMPLE_INTERP: > case PIPE_CAP_SHAREABLE_SHADERS: > @@ -358,7 +360,6 @@ swr_get_param(struct pipe_screen *screen, enum pipe_cap > param) > case PIPE_CAP_PCI_DEVICE: > case PIPE_CAP_PCI_FUNCTION: > case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: > - case PIPE_CAP_CULL_DISTANCE: > case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES: > case PIPE_CAP_TGSI_VOTE: > return 0; > diff --git a/src/gallium/drivers/swr/swr_shader.cpp > b/src/gallium/drivers/swr/swr_shader.cpp > index f26467e..8af0700 100644 > --- a/src/gallium/drivers/swr/swr_shader.cpp > +++ b/src/gallium/drivers/swr/swr_shader.cpp > @@ -40,6 +40,9 @@ > #include "swr_state.h" > #include "swr_screen.h" > > +static unsigned > +locate_linkage(ubyte name, ubyte index, struct tgsi_shader_info *info); > + > bool operator==(const swr_jit_fs_key &lhs, const swr_jit_fs_key &rhs) > { > return !memcmp(&lhs, &rhs, sizeof(lhs)); > @@ -119,6 +122,11 @@ swr_generate_vs_key(struct swr_jit_vs_key &key, > { > memset(&key, 0, sizeof(key)); > > + key.clip_plane_mask = > + swr_vs->info.base.clipdist_writemask ? > + swr_vs->info.base.clipdist_writemask & > ctx->rasterizer->clip_plane_enable : > + ctx->rasterizer->clip_plane_enable; > + > swr_generate_sampler_key(swr_vs->info, ctx, PIPE_SHADER_VERTEX, key); > } > > @@ -251,6 +259,63 @@ BuilderSWR::CompileVS(struct swr_context *ctx, > swr_jit_vs_key &key) > } > } > > + if (ctx->rasterizer->clip_plane_enable || > + swr_vs->info.base.culldist_writemask) { > + unsigned clip_mask = ctx->rasterizer->clip_plane_enable; > + > + unsigned cv = 0; > + if (swr_vs->info.base.writes_clipvertex) { > + cv = 1 + locate_linkage(TGSI_SEMANTIC_CLIPVERTEX, 0, > + &swr_vs->info.base); > + } else { > + for (int i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) { > + if (swr_vs->info.base.output_semantic_name[i] == > TGSI_SEMANTIC_POSITION && > + swr_vs->info.base.output_semantic_index[i] == 0) { > + cv = i; > + break; > + } > + } > + } > + LLVMValueRef cx = LLVMBuildLoad(gallivm->builder, outputs[cv][0], ""); > + LLVMValueRef cy = LLVMBuildLoad(gallivm->builder, outputs[cv][1], ""); > + LLVMValueRef cz = LLVMBuildLoad(gallivm->builder, outputs[cv][2], ""); > + LLVMValueRef cw = LLVMBuildLoad(gallivm->builder, outputs[cv][3], ""); > + > + for (unsigned val = 0; val < PIPE_MAX_CLIP_PLANES; val++) { > + // clip distance overrides user clip planes > + if ((swr_vs->info.base.clipdist_writemask & clip_mask & (1 << val)) > || > + ((swr_vs->info.base.culldist_writemask << > swr_vs->info.base.num_written_clipdistance) & (1 << val))) { > + unsigned cv = 1 + locate_linkage(TGSI_SEMANTIC_CLIPDIST, val < 4 > ? 0 : 1, > + &swr_vs->info.base); > + if (val < 4) { > + LLVMValueRef dist = LLVMBuildLoad(gallivm->builder, > outputs[cv][val], ""); > + STORE(unwrap(dist), vtxOutput, {0, 0, > VERTEX_CLIPCULL_DIST_LO_SLOT, val}); > + } else { > + LLVMValueRef dist = LLVMBuildLoad(gallivm->builder, > outputs[cv][val - 4], ""); > + STORE(unwrap(dist), vtxOutput, {0, 0, > VERTEX_CLIPCULL_DIST_HI_SLOT, val - 4}); > + } > + continue; > + } > + > + if (!(clip_mask & (1 << val))) > + continue; > + > + Value *px = LOAD(GEP(hPrivateData, {0, > swr_draw_context_userClipPlanes, val, 0})); > + Value *py = LOAD(GEP(hPrivateData, {0, > swr_draw_context_userClipPlanes, val, 1})); > + Value *pz = LOAD(GEP(hPrivateData, {0, > swr_draw_context_userClipPlanes, val, 2})); > + Value *pw = LOAD(GEP(hPrivateData, {0, > swr_draw_context_userClipPlanes, val, 3})); > + Value *dist = FADD(FMUL(unwrap(cx), VBROADCAST(px)), > + FADD(FMUL(unwrap(cy), VBROADCAST(py)), > + FADD(FMUL(unwrap(cz), VBROADCAST(pz)), > + FMUL(unwrap(cw), VBROADCAST(pw))))); > + > + if (val < 4) > + STORE(dist, vtxOutput, {0, 0, VERTEX_CLIPCULL_DIST_LO_SLOT, > val}); > + else > + STORE(dist, vtxOutput, {0, 0, VERTEX_CLIPCULL_DIST_HI_SLOT, val > - 4}); > + } > + } > + > RET_VOID(); > > gallivm_verify_function(gallivm, wrap(pFunction)); > diff --git a/src/gallium/drivers/swr/swr_shader.h > b/src/gallium/drivers/swr/swr_shader.h > index 1b604b5..ccdda44 100644 > --- a/src/gallium/drivers/swr/swr_shader.h > +++ b/src/gallium/drivers/swr/swr_shader.h > @@ -56,6 +56,7 @@ struct swr_jit_fs_key : swr_jit_sampler_key { > }; > > struct swr_jit_vs_key : swr_jit_sampler_key { > + unsigned clip_plane_mask; // from rasterizer state & vs_info > }; > > namespace std > diff --git a/src/gallium/drivers/swr/swr_state.cpp > b/src/gallium/drivers/swr/swr_state.cpp > index f50537f..3eeb98d 100644 > --- a/src/gallium/drivers/swr/swr_state.cpp > +++ b/src/gallium/drivers/swr/swr_state.cpp > @@ -849,7 +849,9 @@ swr_update_derived(struct pipe_context *pipe, > } > > /* Raster state */ > - if (ctx->dirty & (SWR_NEW_RASTERIZER | SWR_NEW_FRAMEBUFFER)) { > + if (ctx->dirty & (SWR_NEW_RASTERIZER | > + SWR_NEW_VS | // clipping > + SWR_NEW_FRAMEBUFFER)) { > pipe_rasterizer_state *rasterizer = ctx->rasterizer; > pipe_framebuffer_state *fb = &ctx->framebuffer; > > @@ -906,6 +908,14 @@ swr_update_derived(struct pipe_context *pipe, > > rastState->depthClipEnable = rasterizer->depth_clip; > > + rastState->clipDistanceMask = > + ctx->vs->info.base.num_written_clipdistance ? > + ctx->vs->info.base.clipdist_writemask & > rasterizer->clip_plane_enable : > + rasterizer->clip_plane_enable; > + > + rastState->cullDistanceMask = > + ctx->vs->info.base.culldist_writemask << > ctx->vs->info.base.num_written_clipdistance; > + > SwrSetRastState(ctx->swrContext, rastState); > } > > @@ -1067,6 +1077,7 @@ swr_update_derived(struct pipe_context *pipe, > > /* VertexShader */ > if (ctx->dirty & (SWR_NEW_VS | > + SWR_NEW_RASTERIZER | // for clip planes > SWR_NEW_SAMPLER | > SWR_NEW_SAMPLER_VIEW | > SWR_NEW_FRAMEBUFFER)) { > @@ -1341,6 +1352,18 @@ swr_update_derived(struct pipe_context *pipe, > } > } > > + if (ctx->dirty & SWR_NEW_CLIP) { > + // shader exporting clip distances overrides all user clip planes > + if (ctx->rasterizer->clip_plane_enable && > + !ctx->vs->info.base.num_written_clipdistance) > + { > + swr_draw_context *pDC = &ctx->swrDC; > + memcpy(pDC->userClipPlanes, > + ctx->clip.ucp, > + sizeof(pDC->userClipPlanes)); > + } > + } > + > uint32_t linkage = ctx->vs->linkageMask; > if (ctx->rasterizer->sprite_coord_enable) > linkage |= (1 << ctx->vs->info.base.num_outputs); > -- > 1.9.1 > > _______________________________________________ > 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