From c3c33756ff828ba7ae065c224943aeb48b8ed2ba Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sat, 2 Aug 2014 01:49:39 +0200 Subject: [PATCH] gallivm: fix cube map array (and cube map shadow with bias) handling In particular need to handle TEX2/TXB2/TXL2 opcodes. cube map shadow with bias already used TXB2 which didn't work before at all, despite that there's by default no piglit change (but using no_quad_lod and no_rho_opt indeed passes some more tex-miplevel-selection tests). The actual sampling code still won't handle cube map arrays. Reviewed-by: Brian Paul --- .../auxiliary/gallivm/lp_bld_tgsi_info.c | 20 +++ .../auxiliary/gallivm/lp_bld_tgsi_soa.c | 134 ++++++++++++++---- 2 files changed, 125 insertions(+), 29 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c index 48d1c52f128..3bbf2603a68 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c @@ -137,10 +137,21 @@ analyse_tex(struct analysis_context *ctx, case TGSI_TEXTURE_SHADOWCUBE: readmask = TGSI_WRITEMASK_XYZW; break; + case TGSI_TEXTURE_CUBE_ARRAY: + readmask = TGSI_WRITEMASK_XYZW; + break; + case TGSI_TEXTURE_SHADOWCUBE_ARRAY: + readmask = TGSI_WRITEMASK_XYZW; + break; default: assert(0); return; } + /* XXX + * For cube map arrays, this will not analyze lod or shadow argument. + * For shadow cube, this will not analyze lod bias argument. + * "Indirect" really has no meaning for such textures anyway though. + */ if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) { /* We don't track explicit derivatives, although we could */ @@ -296,6 +307,15 @@ analyse_instruction(struct analysis_context *ctx, case TGSI_OPCODE_TXP: analyse_tex(ctx, inst, LP_BLD_TEX_MODIFIER_PROJECTED); break; + case TGSI_OPCODE_TEX2: + analyse_tex(ctx, inst, LP_BLD_TEX_MODIFIER_NONE); + break; + case TGSI_OPCODE_TXB2: + analyse_tex(ctx, inst, LP_BLD_TEX_MODIFIER_LOD_BIAS); + break; + case TGSI_OPCODE_TXL2: + analyse_tex(ctx, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD); + break; case TGSI_OPCODE_SAMPLE: analyse_sample(ctx, inst, LP_BLD_TEX_MODIFIER_NONE, FALSE); break; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 3d7df3ec912..02a4a526bb2 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -1938,9 +1938,10 @@ static void emit_tex( struct lp_build_tgsi_soa_context *bld, const struct tgsi_full_instruction *inst, enum lp_build_tex_modifier modifier, - LLVMValueRef *texel) + LLVMValueRef *texel, + unsigned sampler_reg) { - unsigned unit; + unsigned unit = inst->Src[sampler_reg].Register.Index; LLVMValueRef lod_bias, explicit_lod; LLVMValueRef oow = NULL; LLVMValueRef coords[5]; @@ -2010,7 +2011,16 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, num_derivs = 3; break; case TGSI_TEXTURE_CUBE_ARRAY: + num_offsets = 2; + num_derivs = 3; + layer_coord = 3; + break; case TGSI_TEXTURE_SHADOWCUBE_ARRAY: + num_offsets = 2; + num_derivs = 3; + layer_coord = 3; + shadow_coord = 4; /* shadow coord special different reg */ + break; case TGSI_TEXTURE_2D_MSAA: case TGSI_TEXTURE_2D_ARRAY_MSAA: default: @@ -2021,7 +2031,15 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, /* Note lod and especially projected are illegal in a LOT of cases */ if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS || modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) { - LLVMValueRef lod = lp_build_emit_fetch(&bld->bld_base, inst, 0, 3); + LLVMValueRef lod; + if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE || + inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY) { + /* note that shadow cube array with bias/explicit lod does not exist */ + lod = lp_build_emit_fetch(&bld->bld_base, inst, 1, 0); + } + else { + lod = lp_build_emit_fetch(&bld->bld_base, inst, 0, 3); + } if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) { lod_bias = lod; explicit_lod = NULL; @@ -2053,13 +2071,23 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, /* Layer coord always goes into 3rd slot, except for cube map arrays */ if (layer_coord) { - coords[2] = lp_build_emit_fetch(&bld->bld_base, inst, 0, layer_coord); + if (layer_coord == 3) { + coords[3] = lp_build_emit_fetch(&bld->bld_base, inst, 0, layer_coord); + } + else { + coords[2] = lp_build_emit_fetch(&bld->bld_base, inst, 0, layer_coord); + } if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) coords[2] = lp_build_mul(&bld->bld_base.base, coords[2], oow); } /* Shadow coord occupies always 5th slot. */ if (shadow_coord) { - coords[4] = lp_build_emit_fetch(&bld->bld_base, inst, 0, shadow_coord); + if (shadow_coord == 4) { + coords[4] = lp_build_emit_fetch(&bld->bld_base, inst, 1, 0); + } + else { + coords[4] = lp_build_emit_fetch(&bld->bld_base, inst, 0, shadow_coord); + } if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) coords[4] = lp_build_mul(&bld->bld_base.base, coords[4], oow); } @@ -2071,7 +2099,6 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, derivs.ddy[dim] = lp_build_emit_fetch(&bld->bld_base, inst, 2, dim); } deriv_ptr = &derivs; - unit = inst->Src[3].Register.Index; /* * could also check all src regs if constant but I doubt such * cases exist in practice. @@ -2087,8 +2114,6 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, else { lod_property = LP_SAMPLER_LOD_PER_ELEMENT; } - } else { - unit = inst->Src[1].Register.Index; } /* some advanced gather instructions (txgo) would require 4 offsets */ @@ -2453,7 +2478,7 @@ emit_size_query( struct lp_build_tgsi_soa_context *bld, static boolean near_end_of_shader(struct lp_build_tgsi_soa_context *bld, - int pc) + int pc) { int i; @@ -2461,27 +2486,38 @@ near_end_of_shader(struct lp_build_tgsi_soa_context *bld, unsigned opcode; if (pc + i >= bld->bld_base.info->num_instructions) - return TRUE; + return TRUE; opcode = bld->bld_base.instructions[pc + i].Instruction.Opcode; if (opcode == TGSI_OPCODE_END) - return TRUE; + return TRUE; if (opcode == TGSI_OPCODE_TEX || - opcode == TGSI_OPCODE_TXP || - opcode == TGSI_OPCODE_TXD || - opcode == TGSI_OPCODE_TXB || - opcode == TGSI_OPCODE_TXL || - opcode == TGSI_OPCODE_TXF || - opcode == TGSI_OPCODE_TXQ || - opcode == TGSI_OPCODE_CAL || - opcode == TGSI_OPCODE_CALLNZ || - opcode == TGSI_OPCODE_IF || - opcode == TGSI_OPCODE_UIF || - opcode == TGSI_OPCODE_BGNLOOP || - opcode == TGSI_OPCODE_SWITCH) - return FALSE; + opcode == TGSI_OPCODE_TXP || + opcode == TGSI_OPCODE_TXD || + opcode == TGSI_OPCODE_TXB || + opcode == TGSI_OPCODE_TXL || + opcode == TGSI_OPCODE_TXF || + opcode == TGSI_OPCODE_TXQ || + opcode == TGSI_OPCODE_TEX2 || + opcode == TGSI_OPCODE_TXB2 || + opcode == TGSI_OPCODE_TXL2 || + opcode == TGSI_OPCODE_SAMPLE || + opcode == TGSI_OPCODE_SAMPLE_B || + opcode == TGSI_OPCODE_SAMPLE_C || + opcode == TGSI_OPCODE_SAMPLE_C_LZ || + opcode == TGSI_OPCODE_SAMPLE_D || + opcode == TGSI_OPCODE_SAMPLE_I || + opcode == TGSI_OPCODE_SAMPLE_L || + opcode == TGSI_OPCODE_SVIEWINFO || + opcode == TGSI_OPCODE_CAL || + opcode == TGSI_OPCODE_CALLNZ || + opcode == TGSI_OPCODE_IF || + opcode == TGSI_OPCODE_UIF || + opcode == TGSI_OPCODE_BGNLOOP || + opcode == TGSI_OPCODE_SWITCH) + return FALSE; } return TRUE; @@ -2888,7 +2924,20 @@ tex_emit( { struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); - emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_NONE, emit_data->output); + emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_NONE, + emit_data->output, 1); +} + +static void +tex2_emit( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); + + emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_NONE, + emit_data->output, 2); } static void @@ -2900,7 +2949,19 @@ txb_emit( struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_LOD_BIAS, - emit_data->output); + emit_data->output, 1); +} + +static void +txb2_emit( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); + + emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_LOD_BIAS, + emit_data->output, 2); } static void @@ -2912,7 +2973,7 @@ txd_emit( struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV, - emit_data->output); + emit_data->output, 3); } static void @@ -2924,7 +2985,19 @@ txl_emit( struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD, - emit_data->output); + emit_data->output, 1); +} + +static void +txl2_emit( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); + + emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD, + emit_data->output, 2); } static void @@ -2936,7 +3009,7 @@ txp_emit( struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_PROJECTED, - emit_data->output); + emit_data->output, 1); } static void @@ -3745,6 +3818,9 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, bld.bld_base.op_actions[TGSI_OPCODE_TXP].emit = txp_emit; bld.bld_base.op_actions[TGSI_OPCODE_TXQ].emit = txq_emit; bld.bld_base.op_actions[TGSI_OPCODE_TXF].emit = txf_emit; + bld.bld_base.op_actions[TGSI_OPCODE_TEX2].emit = tex2_emit; + bld.bld_base.op_actions[TGSI_OPCODE_TXB2].emit = txb2_emit; + bld.bld_base.op_actions[TGSI_OPCODE_TXL2].emit = txl2_emit; /* DX10 sampling ops */ bld.bld_base.op_actions[TGSI_OPCODE_SAMPLE].emit = sample_emit; bld.bld_base.op_actions[TGSI_OPCODE_SAMPLE_B].emit = sample_b_emit; -- 2.30.2