summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorGeorge Kyriazis <[email protected]>2017-12-20 13:56:45 -0600
committerGeorge Kyriazis <[email protected]>2018-01-10 14:02:17 -0600
commit5c4081d66d4a45d20e7520c6b6411135780b6bdd (patch)
treebacc2499659b5b0fee3da20b2542a4b7dfb733df /src/gallium
parent41c36c4549e12b2627d8eb6599caa1e7bd61103f (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')
-rw-r--r--src/gallium/drivers/swr/swr_shader.cpp47
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