diff options
author | Dave Airlie <[email protected]> | 2015-12-18 12:25:53 +0000 |
---|---|---|
committer | Emil Velikov <[email protected]> | 2015-12-18 12:26:23 +0000 |
commit | e7960ad1949b3cff9b2020eaecc9ed88bee15857 (patch) | |
tree | d9baa2cbb3a3db84354fde0dd98a26c2fcc72d5b /src/gallium/drivers/r600 | |
parent | e86c612691c6fe0ac830e646dd90f8bf2b3a277d (diff) |
r600g: fix geom shader input indirect indexing.
This fixes:
gs-input-array-vec4-index-rd
The others run out of gprs unfortunately.
Cc: "11.0 11.1" <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
(cherry picked from commit 38542921c785efb37bae88db409d278990684fa4)
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index ebd2616136d..0847c647462 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -1229,6 +1229,7 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi unsigned vtx_id = src->Dimension.Index; int offset_reg = vtx_id / 3; int offset_chan = vtx_id % 3; + int t2 = 0; /* offsets of per-vertex data in ESGS ring are passed to GS in R0.x, R0.y, * R0.w, R1.x, R1.y, R1.z (it seems R0.z is used for PrimitiveID) */ @@ -1236,9 +1237,11 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi if (offset_reg == 0 && offset_chan == 2) offset_chan = 3; + if (src->Dimension.Indirect || src->Register.Indirect) + t2 = r600_get_temp(ctx); + if (src->Dimension.Indirect) { int treg[3]; - int t2; struct r600_bytecode_alu alu; int r, i; @@ -1250,7 +1253,6 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi } r600_add_gpr_array(ctx->shader, treg[0], 3, 0x0F); - t2 = r600_get_temp(ctx); for (i = 0; i < 3; i++) { memset(&alu, 0, sizeof(struct r600_bytecode_alu)); alu.op = ALU_OP1_MOV; @@ -1275,8 +1277,33 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi if (r) return r; offset_reg = t2; + offset_chan = 0; } + if (src->Register.Indirect) { + int addr_reg; + unsigned first = ctx->info.input_array_first[src->Indirect.ArrayID]; + + addr_reg = get_address_file_reg(ctx, src->Indirect.Index); + + /* pull the value from index_reg */ + r = single_alu_op2(ctx, ALU_OP2_ADD_INT, + t2, 1, + addr_reg, 0, + V_SQ_ALU_SRC_LITERAL, first); + if (r) + return r; + r = single_alu_op3(ctx, ALU_OP3_MULADD_UINT24, + t2, 0, + t2, 1, + V_SQ_ALU_SRC_LITERAL, 4, + offset_reg, offset_chan); + if (r) + return r; + offset_reg = t2; + offset_chan = 0; + index = src->Register.Index - first; + } memset(&vtx, 0, sizeof(vtx)); vtx.buffer_id = R600_GS_RING_CONST_BUFFER; @@ -1322,6 +1349,7 @@ static int tgsi_split_gs_inputs(struct r600_shader_ctx *ctx) fetch_gs_input(ctx, src, treg); ctx->src[i].sel = treg; + ctx->src[i].rel = 0; } } return 0; |