SHADER_OPCODE_TG4_LOGICAL,
SHADER_OPCODE_TG4_OFFSET,
SHADER_OPCODE_TG4_OFFSET_LOGICAL,
+ SHADER_OPCODE_SAMPLEINFO,
/**
* Combines multiple sources of size 1 into a larger virtual GRF.
#define GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4 8
#define GEN5_SAMPLER_MESSAGE_LOD 9
#define GEN5_SAMPLER_MESSAGE_SAMPLE_RESINFO 10
+#define GEN6_SAMPLER_MESSAGE_SAMPLE_SAMPLEINFO 11
#define GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_C 16
#define GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO 17
#define GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_C 18
[GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4] = "gather4",
[GEN5_SAMPLER_MESSAGE_LOD] = "lod",
[GEN5_SAMPLER_MESSAGE_SAMPLE_RESINFO] = "resinfo",
+ [GEN6_SAMPLER_MESSAGE_SAMPLE_SAMPLEINFO] = "sampleinfo",
[GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_C] = "gather4_c",
[GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO] = "gather4_po",
[GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_C] = "gather4_po_c",
case SHADER_OPCODE_TXL:
case SHADER_OPCODE_TXS:
case SHADER_OPCODE_LOD:
+ case SHADER_OPCODE_SAMPLEINFO:
return 1;
case FS_OPCODE_FB_WRITE:
return 2;
msg_type = GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO;
}
break;
+ case SHADER_OPCODE_SAMPLEINFO:
+ msg_type = GEN6_SAMPLER_MESSAGE_SAMPLE_SAMPLEINFO;
+ break;
default:
unreachable("not reached");
}
case SHADER_OPCODE_LOD:
case SHADER_OPCODE_TG4:
case SHADER_OPCODE_TG4_OFFSET:
+ case SHADER_OPCODE_SAMPLEINFO:
generate_tex(inst, dst, src[0], src[1]);
break;
case FS_OPCODE_DDX_COARSE:
case nir_texop_txf_ms: op = ir_txf_ms; break;
case nir_texop_txl: op = ir_txl; break;
case nir_texop_txs: op = ir_txs; break;
+ case nir_texop_texture_samples: {
+ fs_reg dst = retype(get_nir_dest(instr->dest), BRW_REGISTER_TYPE_D);
+ fs_inst *inst = bld.emit(SHADER_OPCODE_SAMPLEINFO, dst,
+ bld.vgrf(BRW_REGISTER_TYPE_D, 1),
+ sampler_reg);
+ inst->mlen = 1;
+ inst->header_size = 1;
+ inst->base_mrf = -1;
+ return;
+ }
default:
unreachable("unknown texture opcode");
}
return "tg4_offset";
case SHADER_OPCODE_TG4_OFFSET_LOGICAL:
return "tg4_offset_logical";
+ case SHADER_OPCODE_SAMPLEINFO:
+ return "sampleinfo";
case SHADER_OPCODE_SHADER_TIME_ADD:
return "shader_time_add";
case SHADER_OPCODE_TXS:
case SHADER_OPCODE_TG4:
case SHADER_OPCODE_TG4_OFFSET:
+ case SHADER_OPCODE_SAMPLEINFO:
return inst->header_size;
default:
unreachable("not reached");
msg_type = GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO;
}
break;
+ case SHADER_OPCODE_SAMPLEINFO:
+ msg_type = GEN6_SAMPLER_MESSAGE_SAMPLE_SAMPLEINFO;
+ break;
default:
unreachable("should not get here: invalid vec4 texture opcode");
}
case SHADER_OPCODE_TXS:
case SHADER_OPCODE_TG4:
case SHADER_OPCODE_TG4_OFFSET:
+ case SHADER_OPCODE_SAMPLEINFO:
generate_tex(inst, dst, src[0], src[1]);
break;
switch (texop) {
case nir_texop_lod: op = ir_lod; break;
case nir_texop_query_levels: op = ir_query_levels; break;
+ case nir_texop_texture_samples: op = ir_texture_samples; break;
case nir_texop_tex: op = ir_tex; break;
case nir_texop_tg4: op = ir_tg4; break;
case nir_texop_txb: op = ir_txb; break;
case ir_tg4: opcode = offset_value.file != BAD_FILE
? SHADER_OPCODE_TG4_OFFSET : SHADER_OPCODE_TG4; break;
case ir_query_levels: opcode = SHADER_OPCODE_TXS; break;
+ case ir_texture_samples: opcode = SHADER_OPCODE_SAMPLEINFO; break;
case ir_txb:
unreachable("TXB is not valid for vertex shaders.");
case ir_lod:
* - Texel offsets
* - Gather channel selection
* - Sampler indices too large to fit in a 4-bit value.
+ * - Sampleinfo message - takes no parameters, but mlen = 0 is illegal
*/
inst->header_size =
(devinfo->gen < 5 || devinfo->gen >= 9 ||
inst->offset != 0 || op == ir_tg4 ||
+ op == ir_texture_samples ||
is_high_sampler(sampler_reg)) ? 1 : 0;
inst->base_mrf = 2;
- inst->mlen = inst->header_size + 1; /* always at least one */
+ inst->mlen = inst->header_size;
inst->dst.writemask = WRITEMASK_XYZW;
inst->shadow_compare = shadow_comparitor.file != BAD_FILE;
if (op == ir_txs || op == ir_query_levels) {
int writemask = devinfo->gen == 4 ? WRITEMASK_W : WRITEMASK_X;
emit(MOV(dst_reg(MRF, param_base, lod.type, writemask), lod));
+ inst->mlen++;
+ } else if (op == ir_texture_samples) {
+ inst->dst.writemask = WRITEMASK_X;
} else {
/* Load the coordinate */
/* FINISHME: gl_clamp_mask and saturate */
emit(MOV(dst_reg(MRF, param_base, coordinate.type, coord_mask),
coordinate));
+ inst->mlen++;
if (zero_mask != 0) {
emit(MOV(dst_reg(MRF, param_base, coordinate.type, zero_mask),
case ir_txb:
case ir_lod:
case ir_tg4:
+ case ir_texture_samples:
break;
}