diff options
author | Tim Rowley <[email protected]> | 2016-05-25 18:49:34 -0500 |
---|---|---|
committer | Tim Rowley <[email protected]> | 2016-06-09 13:28:35 -0500 |
commit | 2c85128e015a401550046f47ce3e2dc0c0049540 (patch) | |
tree | b21cb0ab258192b5375ddf067d4ee7553c18562d /src/gallium/drivers/swr/swr_shader.cpp | |
parent | cf804b4455fac9e585b3600a8318caaced9c23de (diff) |
swr: implement clipPlanes/clipVertex/clipDistance/cullDistance
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)
Reviewed-by: Bruce Cherniak <[email protected]>
Diffstat (limited to 'src/gallium/drivers/swr/swr_shader.cpp')
-rw-r--r-- | src/gallium/drivers/swr/swr_shader.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp index f26467e078e..8af0700cb04 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)); |