On Thu, Jul 23, 2015 at 3:17 AM, Eduardo Lima Mitev <el...@igalia.com> wrote: > From: Alejandro Piñeiro <apinhe...@igalia.com> > > Uses the nir structure to get all the info needed (sources, > dest reg, etc), and then it uses the common > vec4_visitor::emit_texture to emit the final code. > --- > src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 184 > ++++++++++++++++++++++++++++- > 1 file changed, 183 insertions(+), 1 deletion(-) > > diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp > b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp > index 2771116..83a91b7 100644 > --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp > +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp > @@ -1286,10 +1286,192 @@ vec4_visitor::nir_emit_jump(nir_jump_instr *instr) > } > } > > +enum ir_texture_opcode > +ir_texture_opcode_for_nir_texop(nir_texop texop) > +{ > + enum ir_texture_opcode op; > + > + switch (texop) { > + case nir_texop_lod: op = ir_lod; break; > + case nir_texop_query_levels: op = ir_query_levels; 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 nir_texop_txd: op = ir_txd; break; > + case nir_texop_txf: op = ir_txf; break; > + 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; > + default: > + unreachable("unknown texture opcode"); > + } > + > + return op; > +} > + > void > vec4_visitor::nir_emit_texture(nir_tex_instr *instr) > { > - /* @TODO: Not yet implemented */ > + unsigned sampler = instr->sampler_index; > + src_reg sampler_reg = src_reg(sampler); > + src_reg coordinate; > + const glsl_type *coord_type = NULL; > + src_reg shadow_comparitor; > + int shadow_compare = 0; > + bool has_nonconstant_offset = false; > + src_reg offset_value; > + src_reg lod, lod2; > + src_reg sample_index; > + src_reg mcs; > + > + enum glsl_base_type dest_base_type = > + brw_glsl_base_type_for_nir_type(instr->dest_type); > + const glsl_type *dest_type = > + glsl_type::get_instance(dest_base_type, > + nir_tex_instr_dest_size(instr), 1);
Why don't we just make a glsl_type_for_nir_alu_type that takes a nir_alu_type and a number of components. That seems easier than this two-step process. > + dst_reg dest = get_nir_dest(instr->dest, > + brw_type_for_base_type(dest_type)); Just use the version of get_nir_dest() that takes a nir_alu_type > + > + /* When tg4 is used with the degenerate ZERO/ONE swizzles, don't bother > + * emitting anything other than setting up the constant result. > + */ > + if (instr->op == nir_texop_tg4) { > + int swiz = GET_SWZ(key->tex.swizzles[sampler], instr->component); > + if (swiz == SWIZZLE_ZERO || swiz == SWIZZLE_ONE) { > + emit(MOV(dest, src_reg(swiz == SWIZZLE_ONE ? 1.0f : 0.0f))); > + return; > + } > + } > + > + /* Load the texture operation sources */ > + for (unsigned i = 0; i < instr->num_srcs; i++) { > + switch (instr->src[i].src_type) { > + case nir_tex_src_comparitor: > + shadow_comparitor = get_nir_src(instr->src[i].src, > + BRW_REGISTER_TYPE_F, 4); I don't think the shadow comparison value is a vec4. I'm pretty sure it's just a float. Use 1 component. > + shadow_comparitor.swizzle = BRW_SWIZZLE_XXXX; > + shadow_compare = 1; > + break; > + > + case nir_tex_src_coord: > + switch (instr->op) { > + case nir_texop_txf: > + case nir_texop_txf_ms: > + coordinate = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_D, > 4); > + coord_type = glsl_type::get_instance(GLSL_TYPE_INT, > + instr->coord_components, 1); Just use glsl_type::ivec(instr->coord_components); > + break; > + > + default: > + coordinate = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_F, > 4); > + coord_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, > + instr->coord_components, 1); Just use glsl_type::vec(instr->coord_components); > + break; > + } > + break; > + > + case nir_tex_src_ddx: > + lod = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_F, 4); > + break; > + > + case nir_tex_src_ddy: > + lod2 = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_F, 4); > + break; > + > + case nir_tex_src_lod: > + switch (instr->op) { > + case nir_texop_txs: > + lod = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_UD, 4); > + break; > + > + case nir_texop_txf: > + lod = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_D, 4); > + lod.swizzle = BRW_SWIZZLE_XXXX; > + break; > + > + default: > + lod = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_F, 4); Also, I don't think any of the above get_nir_src calls should be for 4 components. lod in txf is obviously only for 1 from what you've written. Let's call get_nir_src with the right number of components. > + break; > + } > + break; > + > + case nir_tex_src_ms_index: { > + sample_index = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_D, > 4); Again, index looks like a single component. > + > + assert(coord_type != NULL); > + if (devinfo->gen >= 7 && > + key->tex.compressed_multisample_layout_mask & (1<<sampler)) { > + mcs = emit_mcs_fetch(coord_type, coordinate, sampler_reg); > + } else { > + mcs = src_reg(0u); > + } > + mcs = retype(mcs, BRW_REGISTER_TYPE_UD); > + break; > + } > + > + case nir_tex_src_offset: > + offset_value = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_D, > 4); again > + has_nonconstant_offset = true; > + break; > + > + case nir_tex_src_sampler_offset: { > + /* The highest sampler which may be used by this operation is > + * the last element of the array. Mark it here, because the > generator > + * doesn't have enough information to determine the bound. > + */ > + uint32_t array_size = instr->sampler_array_size; > + src_reg src = get_nir_src(instr->src[i].src, 4); Again, not 4 components. > + uint32_t max_used = sampler + array_size - 1; > + if (instr->op == nir_texop_tg4) { > + max_used += prog_data->base.binding_table.gather_texture_start; > + } else { > + max_used += prog_data->base.binding_table.texture_start; > + } > + > + brw_mark_surface_used(&prog_data->base, max_used); > + > + /* Emit code to evaluate the actual indexing expression */ > + src_reg temp(this, glsl_type::uint_type); > + emit(ADD(dst_reg(temp), src, src_reg(sampler))); > + sampler_reg = emit_uniformize(temp); > + break; > + } > + > + case nir_tex_src_projector: > + unreachable("Should be lowered by do_lower_texture_projection"); > + > + case nir_tex_src_bias: > + unreachable("LOD bias is not valid for vertex shaders.\n"); > + > + default: > + unreachable("unknown texture source"); > + } > + } > + > + uint32_t constant_offset = 0; > + for (unsigned i = 0; i < 3; i++) { > + if (instr->const_offset[i] != 0) { > + constant_offset = brw_texture_offset(instr->const_offset, 3); > + break; > + } > + } > + > + /* Stuff the channel select bits in the top of the texture offset */ > + if (instr->op == nir_texop_tg4) > + constant_offset |= gather_channel(instr->component, sampler) << 16; > + > + ir_texture_opcode op = ir_texture_opcode_for_nir_texop(instr->op); > + > + bool is_cube_array = > + instr->op == nir_texop_txs && > + instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE && > + instr->is_array; > + > + emit_texture(op, dest, dest_type, coordinate, instr->coord_components, > + shadow_compare, shadow_comparitor, > + lod, lod2, sample_index, > + has_nonconstant_offset, constant_offset, offset_value, > + mcs, is_cube_array, sampler, sampler_reg); > } > > } > -- > 2.1.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev