+static nir_ssa_def *
+sample_via_nir(nir_builder *b, nir_variable *texcoord,
+ const char *name, int sampler, enum glsl_base_type base_type,
+ nir_alu_type alu_type)
+{
+ const struct glsl_type *sampler2D =
+ glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, base_type);
+
+ nir_variable *var =
+ nir_variable_create(b->shader, nir_var_uniform, sampler2D, name);
+ var->data.binding = sampler;
+ var->data.explicit_binding = true;
+
+ nir_deref_instr *deref = nir_build_deref_var(b, var);
+
+ nir_tex_instr *tex = nir_tex_instr_create(b->shader, 3);
+ tex->op = nir_texop_tex;
+ tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
+ tex->coord_components = 2;
+ tex->dest_type = alu_type;
+ tex->src[0].src_type = nir_tex_src_texture_deref;
+ tex->src[0].src = nir_src_for_ssa(&deref->dest.ssa);
+ tex->src[1].src_type = nir_tex_src_sampler_deref;
+ tex->src[1].src = nir_src_for_ssa(&deref->dest.ssa);
+ tex->src[2].src_type = nir_tex_src_coord;
+ tex->src[2].src =
+ nir_src_for_ssa(nir_channels(b, nir_load_var(b, texcoord),
+ (1 << tex->coord_components) - 1));
+
+ nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL);
+ nir_builder_instr_insert(b, &tex->instr);
+ return nir_channel(b, &tex->dest.ssa, 0);
+}
+
+static void *
+make_drawpix_z_stencil_program_nir(struct st_context *st,
+ bool write_depth,
+ bool write_stencil)
+{
+ struct nir_builder b;
+ const nir_shader_compiler_options *options =
+ st->ctx->Const.ShaderCompilerOptions[MESA_SHADER_FRAGMENT].NirOptions;
+
+ nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, options);
+
+ nir_variable *texcoord =
+ nir_variable_create(b.shader, nir_var_shader_in, glsl_vec_type(2),
+ "texcoord");
+ texcoord->data.location = VARYING_SLOT_TEX0;
+
+ if (write_depth) {
+ nir_variable *out =
+ nir_variable_create(b.shader, nir_var_shader_out, glsl_float_type(),
+ "gl_FragDepth");
+ out->data.location = FRAG_RESULT_DEPTH;
+ nir_ssa_def *depth = sample_via_nir(&b, texcoord, "depth", 0,
+ GLSL_TYPE_FLOAT, nir_type_float);
+ nir_store_var(&b, out, depth, 0x1);
+
+ /* Also copy color */
+ nir_variable *color_in =
+ nir_variable_create(b.shader, nir_var_shader_in, glsl_vec_type(4),
+ "v_color");
+ color_in->data.location = VARYING_SLOT_COL0;
+
+ nir_variable *color_out =
+ nir_variable_create(b.shader, nir_var_shader_out, glsl_vec_type(4),
+ "gl_FragColor");
+ color_out->data.location = FRAG_RESULT_COLOR;
+ nir_copy_var(&b, color_out, color_in);
+ }
+
+ if (write_stencil) {
+ nir_variable *out =
+ nir_variable_create(b.shader, nir_var_shader_out, glsl_uint_type(),
+ "gl_FragStencilRefARB");
+ out->data.location = FRAG_RESULT_STENCIL;
+ nir_ssa_def *stencil = sample_via_nir(&b, texcoord, "stencil", 1,
+ GLSL_TYPE_UINT, nir_type_uint);
+ nir_store_var(&b, out, stencil, 0x1);
+ }
+
+ char name[14];
+ snprintf(name, 14, "drawpixels %s%s",
+ write_depth ? "Z" : "", write_stencil ? "S" : "");
+
+ return st_nir_finish_builtin_shader(st, b.shader, name);
+}