diff options
author | George Kyriazis <[email protected]> | 2017-12-20 13:56:45 -0600 |
---|---|---|
committer | George Kyriazis <[email protected]> | 2018-01-10 14:02:17 -0600 |
commit | 5c4081d66d4a45d20e7520c6b6411135780b6bdd (patch) | |
tree | bacc2499659b5b0fee3da20b2542a4b7dfb733df /src/gallium/drivers/swr | |
parent | 41c36c4549e12b2627d8eb6599caa1e7bd61103f (diff) |
swr: Handle indirect indices in GS
BuilderSWR::swr_gs_llvm_fetch_input() (and consequently
swr_gs_llvm_fetch_input()), did not handle the case where
is_vindex_indirect or is_aindex_direct is set.
Implement it, using the code in draw_llvm.c as a guideline.
Fixes the following piglit tests:
dynamic_input_array_index (crash)
gs-input-array-vec4-index-rd
vs-output-array-vec4-index-wr-before-gs
Reviewed-by: Bruce Cherniak <[email protected]>
Diffstat (limited to 'src/gallium/drivers/swr')
-rw-r--r-- | src/gallium/drivers/swr/swr_shader.cpp | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp index 599dc43698a..257a6aae307 100644 --- a/src/gallium/drivers/swr/swr_shader.cpp +++ b/src/gallium/drivers/swr/swr_shader.cpp @@ -339,22 +339,53 @@ BuilderSWR::swr_gs_llvm_fetch_input(const struct lp_build_tgsi_gs_iface *gs_ifac LLVMValueRef swizzle_index) { swr_gs_llvm_iface *iface = (swr_gs_llvm_iface*)gs_iface; + Value *vert_index = unwrap(vertex_index); + Value *attr_index = unwrap(attrib_index); IRB()->SetInsertPoint(unwrap(LLVMGetInsertBlock(gallivm->builder))); - assert(is_vindex_indirect == false && is_aindex_indirect == false); + if (is_vindex_indirect || is_aindex_indirect) { + int i; + Value *res = unwrap(bld_base->base.zero); + struct lp_type type = bld_base->base.type; - Value *attrib = - LOAD(GEP(iface->pVtxAttribMap, {C(0), unwrap(attrib_index)})); + for (i = 0; i < type.length; i++) { + Value *vert_chan_index = vert_index; + Value *attr_chan_index = attr_index; - Value *pVertex = LOAD(iface->pGsCtx, {0, SWR_GS_CONTEXT_pVerts}); - Value *pInputVertStride = LOAD(iface->pGsCtx, {0, SWR_GS_CONTEXT_inputVertStride}); + if (is_vindex_indirect) { + vert_chan_index = VEXTRACT(vert_index, C(i)); + } + if (is_aindex_indirect) { + attr_chan_index = VEXTRACT(attr_index, C(i)); + } + + Value *attrib = + LOAD(GEP(iface->pVtxAttribMap, {C(0), attr_chan_index})); + + Value *pVertex = LOAD(iface->pGsCtx, {0, SWR_GS_CONTEXT_pVerts}); + Value *pInputVertStride = LOAD(iface->pGsCtx, {0, SWR_GS_CONTEXT_inputVertStride}); + + Value *pVector = ADD(MUL(vert_chan_index, pInputVertStride), attrib); + Value *pInput = LOAD(GEP(pVertex, {pVector, unwrap(swizzle_index)})); - Value *pVector = ADD(MUL(unwrap(vertex_index), pInputVertStride), attrib); + Value *value = VEXTRACT(pInput, C(i)); + res = VINSERT(res, value, C(i)); + } + + return wrap(res); + } else { + Value *attrib = LOAD(GEP(iface->pVtxAttribMap, {C(0), attr_index})); + + Value *pVertex = LOAD(iface->pGsCtx, {0, SWR_GS_CONTEXT_pVerts}); + Value *pInputVertStride = LOAD(iface->pGsCtx, {0, SWR_GS_CONTEXT_inputVertStride}); - Value *pInput = LOAD(GEP(pVertex, {pVector, unwrap(swizzle_index)})); + Value *pVector = ADD(MUL(vert_index, pInputVertStride), attrib); - return wrap(pInput); + Value *pInput = LOAD(GEP(pVertex, {pVector, unwrap(swizzle_index)})); + + return wrap(pInput); + } } // GS output stream layout |