101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2015 Red Hat 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2001e04c3fSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2101e04c3fSmrg * SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include "nir.h" 2501e04c3fSmrg#include "nir_builder.h" 2601e04c3fSmrg 2701e04c3fSmrg/* Lower glBitmap(). 2801e04c3fSmrg * 2901e04c3fSmrg * This is based on the logic in st_get_bitmap_shader() in TGSI compiler. 3001e04c3fSmrg * From st_cb_bitmap.c: 3101e04c3fSmrg * 3201e04c3fSmrg * glBitmaps are drawn as textured quads. The user's bitmap pattern 3301e04c3fSmrg * is stored in a texture image. An alpha8 texture format is used. 3401e04c3fSmrg * The fragment shader samples a bit (texel) from the texture, then 3501e04c3fSmrg * discards the fragment if the bit is off. 3601e04c3fSmrg * 3701e04c3fSmrg * Note that we actually store the inverse image of the bitmap to 3801e04c3fSmrg * simplify the fragment program. An "on" bit gets stored as texel=0x0 3901e04c3fSmrg * and an "off" bit is stored as texel=0xff. Then we kill the 4001e04c3fSmrg * fragment if the negated texel value is less than zero. 4101e04c3fSmrg * 4201e04c3fSmrg * Note that the texture format will be, according to what driver supports, 4301e04c3fSmrg * in order of preference (with swizzle): 4401e04c3fSmrg * 4501e04c3fSmrg * I8_UNORM - .xxxx 4601e04c3fSmrg * A8_UNORM - .000x 4701e04c3fSmrg * L8_UNORM - .xxx1 4801e04c3fSmrg * 4901e04c3fSmrg * If L8_UNORM, options->swizzle_xxxx is true. Otherwise we can just use 5001e04c3fSmrg * the .w comp. 5101e04c3fSmrg * 5201e04c3fSmrg * Run before nir_lower_io. 5301e04c3fSmrg */ 5401e04c3fSmrg 5501e04c3fSmrgstatic nir_variable * 5601e04c3fSmrgget_texcoord(nir_shader *shader) 5701e04c3fSmrg{ 587ec681f3Smrg nir_variable *texcoord = 597ec681f3Smrg nir_find_variable_with_location(shader, nir_var_shader_in, 607ec681f3Smrg VARYING_SLOT_TEX0); 6101e04c3fSmrg /* otherwise create it: */ 6201e04c3fSmrg if (texcoord == NULL) { 6301e04c3fSmrg texcoord = nir_variable_create(shader, 6401e04c3fSmrg nir_var_shader_in, 6501e04c3fSmrg glsl_vec4_type(), 6601e04c3fSmrg "gl_TexCoord"); 6701e04c3fSmrg texcoord->data.location = VARYING_SLOT_TEX0; 6801e04c3fSmrg } 6901e04c3fSmrg 7001e04c3fSmrg return texcoord; 7101e04c3fSmrg} 7201e04c3fSmrg 7301e04c3fSmrgstatic void 7401e04c3fSmrglower_bitmap(nir_shader *shader, nir_builder *b, 7501e04c3fSmrg const nir_lower_bitmap_options *options) 7601e04c3fSmrg{ 7701e04c3fSmrg nir_ssa_def *texcoord; 7801e04c3fSmrg nir_tex_instr *tex; 7901e04c3fSmrg nir_ssa_def *cond; 8001e04c3fSmrg 8101e04c3fSmrg texcoord = nir_load_var(b, get_texcoord(shader)); 8201e04c3fSmrg 8301e04c3fSmrg const struct glsl_type *sampler2D = 8401e04c3fSmrg glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT); 8501e04c3fSmrg 8601e04c3fSmrg nir_variable *tex_var = 8701e04c3fSmrg nir_variable_create(shader, nir_var_uniform, sampler2D, "bitmap_tex"); 8801e04c3fSmrg tex_var->data.binding = options->sampler; 897e102996Smaya tex_var->data.explicit_binding = true; 907e102996Smaya tex_var->data.how_declared = nir_var_hidden; 9101e04c3fSmrg 927e102996Smaya nir_deref_instr *tex_deref = nir_build_deref_var(b, tex_var); 937e102996Smaya 947e102996Smaya tex = nir_tex_instr_create(shader, 3); 9501e04c3fSmrg tex->op = nir_texop_tex; 9601e04c3fSmrg tex->sampler_dim = GLSL_SAMPLER_DIM_2D; 9701e04c3fSmrg tex->coord_components = 2; 987ec681f3Smrg tex->dest_type = nir_type_float32; 997e102996Smaya tex->src[0].src_type = nir_tex_src_texture_deref; 1007e102996Smaya tex->src[0].src = nir_src_for_ssa(&tex_deref->dest.ssa); 1017e102996Smaya tex->src[1].src_type = nir_tex_src_sampler_deref; 1027e102996Smaya tex->src[1].src = nir_src_for_ssa(&tex_deref->dest.ssa); 1037e102996Smaya tex->src[2].src_type = nir_tex_src_coord; 1047e102996Smaya tex->src[2].src = 10501e04c3fSmrg nir_src_for_ssa(nir_channels(b, texcoord, 10601e04c3fSmrg (1 << tex->coord_components) - 1)); 10701e04c3fSmrg 10801e04c3fSmrg nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL); 10901e04c3fSmrg nir_builder_instr_insert(b, &tex->instr); 11001e04c3fSmrg 11101e04c3fSmrg /* kill if tex != 0.0.. take .x or .w channel according to format: */ 11201e04c3fSmrg cond = nir_f2b(b, nir_channel(b, &tex->dest.ssa, 11301e04c3fSmrg options->swizzle_xxxx ? 0 : 3)); 11401e04c3fSmrg 1157ec681f3Smrg nir_discard_if(b, cond); 11601e04c3fSmrg 11701e04c3fSmrg shader->info.fs.uses_discard = true; 11801e04c3fSmrg} 11901e04c3fSmrg 12001e04c3fSmrgstatic void 12101e04c3fSmrglower_bitmap_impl(nir_function_impl *impl, 12201e04c3fSmrg const nir_lower_bitmap_options *options) 12301e04c3fSmrg{ 12401e04c3fSmrg nir_builder b; 12501e04c3fSmrg 12601e04c3fSmrg nir_builder_init(&b, impl); 12701e04c3fSmrg b.cursor = nir_before_cf_list(&impl->body); 12801e04c3fSmrg 12901e04c3fSmrg lower_bitmap(impl->function->shader, &b, options); 13001e04c3fSmrg 13101e04c3fSmrg nir_metadata_preserve(impl, nir_metadata_block_index | 13201e04c3fSmrg nir_metadata_dominance); 13301e04c3fSmrg} 13401e04c3fSmrg 13501e04c3fSmrgvoid 13601e04c3fSmrgnir_lower_bitmap(nir_shader *shader, 13701e04c3fSmrg const nir_lower_bitmap_options *options) 13801e04c3fSmrg{ 13901e04c3fSmrg assert(shader->info.stage == MESA_SHADER_FRAGMENT); 14001e04c3fSmrg 14101e04c3fSmrg lower_bitmap_impl(nir_shader_get_entrypoint(shader), options); 14201e04c3fSmrg} 143