1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2015 Red Hat 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20b8e80941Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21b8e80941Smrg * SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg 24b8e80941Smrg#include "nir.h" 25b8e80941Smrg#include "nir_builder.h" 26b8e80941Smrg 27b8e80941Smrg/* Lower glBitmap(). 28b8e80941Smrg * 29b8e80941Smrg * This is based on the logic in st_get_bitmap_shader() in TGSI compiler. 30b8e80941Smrg * From st_cb_bitmap.c: 31b8e80941Smrg * 32b8e80941Smrg * glBitmaps are drawn as textured quads. The user's bitmap pattern 33b8e80941Smrg * is stored in a texture image. An alpha8 texture format is used. 34b8e80941Smrg * The fragment shader samples a bit (texel) from the texture, then 35b8e80941Smrg * discards the fragment if the bit is off. 36b8e80941Smrg * 37b8e80941Smrg * Note that we actually store the inverse image of the bitmap to 38b8e80941Smrg * simplify the fragment program. An "on" bit gets stored as texel=0x0 39b8e80941Smrg * and an "off" bit is stored as texel=0xff. Then we kill the 40b8e80941Smrg * fragment if the negated texel value is less than zero. 41b8e80941Smrg * 42b8e80941Smrg * Note that the texture format will be, according to what driver supports, 43b8e80941Smrg * in order of preference (with swizzle): 44b8e80941Smrg * 45b8e80941Smrg * I8_UNORM - .xxxx 46b8e80941Smrg * A8_UNORM - .000x 47b8e80941Smrg * L8_UNORM - .xxx1 48b8e80941Smrg * 49b8e80941Smrg * If L8_UNORM, options->swizzle_xxxx is true. Otherwise we can just use 50b8e80941Smrg * the .w comp. 51b8e80941Smrg * 52b8e80941Smrg * Run before nir_lower_io. 53b8e80941Smrg */ 54b8e80941Smrg 55b8e80941Smrgstatic nir_variable * 56b8e80941Smrgget_texcoord(nir_shader *shader) 57b8e80941Smrg{ 58b8e80941Smrg nir_variable *texcoord = NULL; 59b8e80941Smrg 60b8e80941Smrg /* find gl_TexCoord, if it exists: */ 61b8e80941Smrg nir_foreach_variable(var, &shader->inputs) { 62b8e80941Smrg if (var->data.location == VARYING_SLOT_TEX0) { 63b8e80941Smrg texcoord = var; 64b8e80941Smrg break; 65b8e80941Smrg } 66b8e80941Smrg } 67b8e80941Smrg 68b8e80941Smrg /* otherwise create it: */ 69b8e80941Smrg if (texcoord == NULL) { 70b8e80941Smrg texcoord = nir_variable_create(shader, 71b8e80941Smrg nir_var_shader_in, 72b8e80941Smrg glsl_vec4_type(), 73b8e80941Smrg "gl_TexCoord"); 74b8e80941Smrg texcoord->data.location = VARYING_SLOT_TEX0; 75b8e80941Smrg } 76b8e80941Smrg 77b8e80941Smrg return texcoord; 78b8e80941Smrg} 79b8e80941Smrg 80b8e80941Smrgstatic void 81b8e80941Smrglower_bitmap(nir_shader *shader, nir_builder *b, 82b8e80941Smrg const nir_lower_bitmap_options *options) 83b8e80941Smrg{ 84b8e80941Smrg nir_ssa_def *texcoord; 85b8e80941Smrg nir_tex_instr *tex; 86b8e80941Smrg nir_ssa_def *cond; 87b8e80941Smrg nir_intrinsic_instr *discard; 88b8e80941Smrg 89b8e80941Smrg texcoord = nir_load_var(b, get_texcoord(shader)); 90b8e80941Smrg 91b8e80941Smrg const struct glsl_type *sampler2D = 92b8e80941Smrg glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT); 93b8e80941Smrg 94b8e80941Smrg nir_variable *tex_var = 95b8e80941Smrg nir_variable_create(shader, nir_var_uniform, sampler2D, "bitmap_tex"); 96b8e80941Smrg tex_var->data.binding = options->sampler; 97b8e80941Smrg tex_var->data.explicit_binding = true; 98b8e80941Smrg tex_var->data.how_declared = nir_var_hidden; 99b8e80941Smrg 100b8e80941Smrg nir_deref_instr *tex_deref = nir_build_deref_var(b, tex_var); 101b8e80941Smrg 102b8e80941Smrg tex = nir_tex_instr_create(shader, 3); 103b8e80941Smrg tex->op = nir_texop_tex; 104b8e80941Smrg tex->sampler_dim = GLSL_SAMPLER_DIM_2D; 105b8e80941Smrg tex->coord_components = 2; 106b8e80941Smrg tex->dest_type = nir_type_float; 107b8e80941Smrg tex->src[0].src_type = nir_tex_src_texture_deref; 108b8e80941Smrg tex->src[0].src = nir_src_for_ssa(&tex_deref->dest.ssa); 109b8e80941Smrg tex->src[1].src_type = nir_tex_src_sampler_deref; 110b8e80941Smrg tex->src[1].src = nir_src_for_ssa(&tex_deref->dest.ssa); 111b8e80941Smrg tex->src[2].src_type = nir_tex_src_coord; 112b8e80941Smrg tex->src[2].src = 113b8e80941Smrg nir_src_for_ssa(nir_channels(b, texcoord, 114b8e80941Smrg (1 << tex->coord_components) - 1)); 115b8e80941Smrg 116b8e80941Smrg nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL); 117b8e80941Smrg nir_builder_instr_insert(b, &tex->instr); 118b8e80941Smrg 119b8e80941Smrg /* kill if tex != 0.0.. take .x or .w channel according to format: */ 120b8e80941Smrg cond = nir_f2b(b, nir_channel(b, &tex->dest.ssa, 121b8e80941Smrg options->swizzle_xxxx ? 0 : 3)); 122b8e80941Smrg 123b8e80941Smrg discard = nir_intrinsic_instr_create(shader, nir_intrinsic_discard_if); 124b8e80941Smrg discard->src[0] = nir_src_for_ssa(cond); 125b8e80941Smrg nir_builder_instr_insert(b, &discard->instr); 126b8e80941Smrg 127b8e80941Smrg shader->info.fs.uses_discard = true; 128b8e80941Smrg} 129b8e80941Smrg 130b8e80941Smrgstatic void 131b8e80941Smrglower_bitmap_impl(nir_function_impl *impl, 132b8e80941Smrg const nir_lower_bitmap_options *options) 133b8e80941Smrg{ 134b8e80941Smrg nir_builder b; 135b8e80941Smrg 136b8e80941Smrg nir_builder_init(&b, impl); 137b8e80941Smrg b.cursor = nir_before_cf_list(&impl->body); 138b8e80941Smrg 139b8e80941Smrg lower_bitmap(impl->function->shader, &b, options); 140b8e80941Smrg 141b8e80941Smrg nir_metadata_preserve(impl, nir_metadata_block_index | 142b8e80941Smrg nir_metadata_dominance); 143b8e80941Smrg} 144b8e80941Smrg 145b8e80941Smrgvoid 146b8e80941Smrgnir_lower_bitmap(nir_shader *shader, 147b8e80941Smrg const nir_lower_bitmap_options *options) 148b8e80941Smrg{ 149b8e80941Smrg assert(shader->info.stage == MESA_SHADER_FRAGMENT); 150b8e80941Smrg 151b8e80941Smrg lower_bitmap_impl(nir_shader_get_entrypoint(shader), options); 152b8e80941Smrg} 153