From 0b91bcea98c0fe201bba89abe1ca3aee4d04c56c Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Tue, 11 Aug 2015 20:37:32 -0400 Subject: [PATCH] i965: add support for textureSamples function Signed-off-by: Ilia Mirkin [v2: kayden-supplied code in fs_nir replacing need for logical opcode] Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/brw_defines.h | 2 ++ src/mesa/drivers/dri/i965/brw_disasm.c | 1 + src/mesa/drivers/dri/i965/brw_fs.cpp | 1 + src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 4 ++++ src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 10 ++++++++++ src/mesa/drivers/dri/i965/brw_shader.cpp | 2 ++ src/mesa/drivers/dri/i965/brw_vec4.cpp | 1 + src/mesa/drivers/dri/i965/brw_vec4_generator.cpp | 4 ++++ src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 1 + src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 10 +++++++++- 10 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index a8594af..d18f7ca 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -979,6 +979,7 @@ enum opcode { 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. @@ -1511,6 +1512,7 @@ enum brw_message_target { #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 diff --git a/src/mesa/drivers/dri/i965/brw_disasm.c b/src/mesa/drivers/dri/i965/brw_disasm.c index 7401e32..db23a18 100644 --- a/src/mesa/drivers/dri/i965/brw_disasm.c +++ b/src/mesa/drivers/dri/i965/brw_disasm.c @@ -617,6 +617,7 @@ static const char *const gen5_sampler_msg_type[] = { [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", diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index d240371..17cbdf4 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -877,6 +877,7 @@ fs_visitor::implied_mrf_writes(fs_inst *inst) 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; diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index c86ca04..90805e4 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -646,6 +646,9 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src 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"); } @@ -1920,6 +1923,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) 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: diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index a6c6a2f..0902e1c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -1842,6 +1842,16 @@ fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr) 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"); } diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index de1a7fe..d353591 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -618,6 +618,8 @@ brw_instruction_name(enum opcode op) 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"; diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp index 85dc372..893ff35 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp @@ -331,6 +331,7 @@ vec4_visitor::implied_mrf_writes(vec4_instruction *inst) 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"); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp index 92050b9..1950333 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp @@ -286,6 +286,9 @@ vec4_generator::generate_tex(vec4_instruction *inst, 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"); } @@ -1374,6 +1377,7 @@ vec4_generator::generate_code(const cfg_t *cfg) 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; diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index 751ec73..c21fd02 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -1337,6 +1337,7 @@ ir_texture_opcode_for_nir_texop(nir_texop texop) 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; diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index f6e59ce..0465770 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -2550,6 +2550,7 @@ vec4_visitor::emit_texture(ir_texture_opcode op, 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: @@ -2569,13 +2570,15 @@ vec4_visitor::emit_texture(ir_texture_opcode op, * - 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; @@ -2587,6 +2590,9 @@ vec4_visitor::emit_texture(ir_texture_opcode op, 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 */ @@ -2595,6 +2601,7 @@ vec4_visitor::emit_texture(ir_texture_opcode op, 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), @@ -2817,6 +2824,7 @@ vec4_visitor::visit(ir_texture *ir) case ir_txb: case ir_lod: case ir_tg4: + case ir_texture_samples: break; } -- 2.7.4