v2: only load the clip vertex once --- src/gallium/drivers/swr/swr_context.h | 2 ++ src/gallium/drivers/swr/swr_shader.cpp | 65 ++++++++++++++++++++++++++++++++++ src/gallium/drivers/swr/swr_shader.h | 4 +++ src/gallium/drivers/swr/swr_state.cpp | 22 +++++++++++- 4 files changed, 92 insertions(+), 1 deletion(-)
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_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp index f693f51..0c5787e 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)); @@ -120,6 +123,11 @@ swr_generate_vs_key(struct swr_jit_vs_key &key, { memset(&key, 0, sizeof(key)); + key.clip_plane_mask = ctx->rasterizer->clip_plane_enable; + key.clip_distance_mask = swr_vs->info.base.clipdist_writemask; + key.cull_distance_mask = swr_vs->info.base.culldist_writemask; + key.writes_clipvertex = swr_vs->info.base.writes_clipvertex; + swr_generate_sampler_key(swr_vs->info, ctx, PIPE_SHADER_VERTEX, key); } @@ -252,6 +260,63 @@ BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key) } } + if (ctx->rasterizer->clip_plane_enable) { + unsigned clip_mask = ctx->rasterizer->clip_plane_enable; + + unsigned cv; + 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++) { + if (!(clip_mask & (1 << val))) + continue; + + // clip distance overrides user clip planes + if (swr_vs->info.base.num_written_clipdistance) { + if (!(swr_vs->info.base.clipdist_writemask & (1 << val))) + continue; + + unsigned cv = 1 + locate_linkage(TGSI_SEMANTIC_CLIPDIST, val, + &swr_vs->info.base); + LLVMValueRef dist = LLVMBuildLoad(gallivm->builder, outputs[cv][0], ""); + + if (val < 4) + STORE(unwrap(dist), vtxOutput, {0, 0, VERTEX_CLIPCULL_DIST_LO_SLOT, val}); + else + STORE(unwrap(dist), vtxOutput, {0, 0, VERTEX_CLIPCULL_DIST_HI_SLOT, val - 4}); + 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 11d50c3..5f5b232 100644 --- a/src/gallium/drivers/swr/swr_shader.h +++ b/src/gallium/drivers/swr/swr_shader.h @@ -57,6 +57,10 @@ 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 + unsigned clip_distance_mask; // from vs outputs (direct) + unsigned cull_distance_mask; // from vs outputs (direct) + bool writes_clipvertex; // from vs_info }; namespace std diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index f9326f3..f8d10ac 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,11 @@ 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; + SwrSetRastState(ctx->swrContext, rastState); } @@ -1067,6 +1074,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 +1349,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