static nir_ssa_def * sample_plane(nir_builder *b, nir_tex_instr *tex, int plane) { assert(tex->dest.is_ssa); assert(nir_tex_instr_dest_size(tex) == 4); assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float); assert(tex->op == nir_texop_tex); assert(tex->coord_components == 2); nir_tex_instr *plane_tex = nir_tex_instr_create(b->shader, 2); nir_src_copy(&plane_tex->src[0].src, &tex->src[0].src, plane_tex); plane_tex->src[0].src_type = nir_tex_src_coord; plane_tex->src[1].src = nir_src_for_ssa(nir_imm_int(b, plane)); plane_tex->src[1].src_type = nir_tex_src_plane; plane_tex->op = nir_texop_tex; plane_tex->sampler_dim = 2; plane_tex->dest_type = nir_type_float; plane_tex->coord_components = 2; plane_tex->texture_index = tex->texture_index; plane_tex->texture = (nir_deref_var *) nir_copy_deref(plane_tex, &tex->texture->deref); plane_tex->sampler_index = tex->sampler_index; plane_tex->sampler = (nir_deref_var *) nir_copy_deref(plane_tex, &tex->sampler->deref); nir_ssa_dest_init(&plane_tex->instr, &plane_tex->dest, 4, 32, NULL); nir_builder_instr_insert(b, &plane_tex->instr); return &plane_tex->dest.ssa; }
static nir_ssa_def * sample_plane(nir_builder *b, nir_tex_instr *tex, int plane) { assert(tex->dest.is_ssa); assert(nir_tex_instr_dest_size(tex) == 4); assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float); assert(tex->op == nir_texop_tex); assert(tex->coord_components == 2); nir_tex_instr *plane_tex = nir_tex_instr_create(b->shader, tex->num_srcs + 1); for (unsigned i = 0; i < tex->num_srcs; i++) { nir_src_copy(&plane_tex->src[i].src, &tex->src[i].src, plane_tex); plane_tex->src[i].src_type = tex->src[i].src_type; } plane_tex->src[tex->num_srcs].src = nir_src_for_ssa(nir_imm_int(b, plane)); plane_tex->src[tex->num_srcs].src_type = nir_tex_src_plane; plane_tex->op = nir_texop_tex; plane_tex->sampler_dim = GLSL_SAMPLER_DIM_2D; plane_tex->dest_type = nir_type_float; plane_tex->coord_components = 2; plane_tex->texture_index = tex->texture_index; plane_tex->sampler_index = tex->sampler_index; nir_ssa_dest_init(&plane_tex->instr, &plane_tex->dest, 4, 32, NULL); nir_builder_instr_insert(b, &plane_tex->instr); return &plane_tex->dest.ssa; }
static nir_ssa_def * get_texture_size(nir_builder *b, nir_tex_instr *tex) { b->cursor = nir_before_instr(&tex->instr); nir_tex_instr *txs; unsigned num_srcs = 1; /* One for the LOD */ for (unsigned i = 0; i < tex->num_srcs; i++) { if (tex->src[i].src_type == nir_tex_src_texture_deref || tex->src[i].src_type == nir_tex_src_sampler_deref || tex->src[i].src_type == nir_tex_src_texture_offset || tex->src[i].src_type == nir_tex_src_sampler_offset || tex->src[i].src_type == nir_tex_src_texture_handle || tex->src[i].src_type == nir_tex_src_sampler_handle) num_srcs++; } txs = nir_tex_instr_create(b->shader, num_srcs); txs->op = nir_texop_txs; txs->sampler_dim = tex->sampler_dim; txs->is_array = tex->is_array; txs->is_shadow = tex->is_shadow; txs->is_new_style_shadow = tex->is_new_style_shadow; txs->texture_index = tex->texture_index; txs->sampler_index = tex->sampler_index; txs->dest_type = nir_type_int; unsigned idx = 0; for (unsigned i = 0; i < tex->num_srcs; i++) { if (tex->src[i].src_type == nir_tex_src_texture_deref || tex->src[i].src_type == nir_tex_src_sampler_deref || tex->src[i].src_type == nir_tex_src_texture_offset || tex->src[i].src_type == nir_tex_src_sampler_offset || tex->src[i].src_type == nir_tex_src_texture_handle || tex->src[i].src_type == nir_tex_src_sampler_handle) { nir_src_copy(&txs->src[idx].src, &tex->src[i].src, txs); txs->src[idx].src_type = tex->src[i].src_type; idx++; } } /* Add in an LOD because some back-ends require it */ txs->src[idx].src = nir_src_for_ssa(nir_imm_int(b, 0)); txs->src[idx].src_type = nir_tex_src_lod; nir_ssa_dest_init(&txs->instr, &txs->dest, nir_tex_instr_dest_size(txs), 32, NULL); nir_builder_instr_insert(b, &txs->instr); return nir_i2f32(b, &txs->dest.ssa); }
static void validate_tex_instr(nir_tex_instr *instr, validate_state *state) { bool src_type_seen[nir_num_tex_src_types]; for (unsigned i = 0; i < nir_num_tex_src_types; i++) src_type_seen[i] = false; for (unsigned i = 0; i < instr->num_srcs; i++) { validate_assert(state, !src_type_seen[instr->src[i].src_type]); src_type_seen[instr->src[i].src_type] = true; validate_src(&instr->src[i].src, state, 0, nir_tex_instr_src_size(instr, i)); } if (instr->texture != NULL) validate_deref_var(instr, instr->texture, state); if (instr->sampler != NULL) validate_deref_var(instr, instr->sampler, state); validate_dest(&instr->dest, state, 0, nir_tex_instr_dest_size(instr)); }
static void swizzle_result(nir_builder *b, nir_tex_instr *tex, const uint8_t swizzle[4]) { assert(tex->dest.is_ssa); b->cursor = nir_after_instr(&tex->instr); nir_ssa_def *swizzled; if (tex->op == nir_texop_tg4) { if (swizzle[tex->component] < 4) { /* This one's easy */ tex->component = swizzle[tex->component]; return; } else { swizzled = get_zero_or_one(b, tex->dest_type, swizzle[tex->component]); } } else { assert(nir_tex_instr_dest_size(tex) == 4); if (swizzle[0] < 4 && swizzle[1] < 4 && swizzle[2] < 4 && swizzle[3] < 4) { unsigned swiz[4] = { swizzle[0], swizzle[1], swizzle[2], swizzle[3] }; /* We have no 0's or 1's, just emit a swizzling MOV */ swizzled = nir_swizzle(b, &tex->dest.ssa, swiz, 4, false); } else { nir_ssa_def *srcs[4]; for (unsigned i = 0; i < 4; i++) { if (swizzle[i] < 4) { srcs[i] = nir_channel(b, &tex->dest.ssa, swizzle[i]); } else { srcs[i] = get_zero_or_one(b, tex->dest_type, swizzle[i]); } } swizzled = nir_vec(b, srcs, 4); } } nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, nir_src_for_ssa(swizzled), swizzled->parent_instr); }