Path: blob/21.2-virgl/src/compiler/nir/nir_lower_bitmap.c
4545 views
/*1* Copyright © 2015 Red Hat2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*/2223#include "nir.h"24#include "nir_builder.h"2526/* Lower glBitmap().27*28* This is based on the logic in st_get_bitmap_shader() in TGSI compiler.29* From st_cb_bitmap.c:30*31* glBitmaps are drawn as textured quads. The user's bitmap pattern32* is stored in a texture image. An alpha8 texture format is used.33* The fragment shader samples a bit (texel) from the texture, then34* discards the fragment if the bit is off.35*36* Note that we actually store the inverse image of the bitmap to37* simplify the fragment program. An "on" bit gets stored as texel=0x038* and an "off" bit is stored as texel=0xff. Then we kill the39* fragment if the negated texel value is less than zero.40*41* Note that the texture format will be, according to what driver supports,42* in order of preference (with swizzle):43*44* I8_UNORM - .xxxx45* A8_UNORM - .000x46* L8_UNORM - .xxx147*48* If L8_UNORM, options->swizzle_xxxx is true. Otherwise we can just use49* the .w comp.50*51* Run before nir_lower_io.52*/5354static nir_variable *55get_texcoord(nir_shader *shader)56{57nir_variable *texcoord =58nir_find_variable_with_location(shader, nir_var_shader_in,59VARYING_SLOT_TEX0);60/* otherwise create it: */61if (texcoord == NULL) {62texcoord = nir_variable_create(shader,63nir_var_shader_in,64glsl_vec4_type(),65"gl_TexCoord");66texcoord->data.location = VARYING_SLOT_TEX0;67}6869return texcoord;70}7172static void73lower_bitmap(nir_shader *shader, nir_builder *b,74const nir_lower_bitmap_options *options)75{76nir_ssa_def *texcoord;77nir_tex_instr *tex;78nir_ssa_def *cond;7980texcoord = nir_load_var(b, get_texcoord(shader));8182const struct glsl_type *sampler2D =83glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT);8485nir_variable *tex_var =86nir_variable_create(shader, nir_var_uniform, sampler2D, "bitmap_tex");87tex_var->data.binding = options->sampler;88tex_var->data.explicit_binding = true;89tex_var->data.how_declared = nir_var_hidden;9091nir_deref_instr *tex_deref = nir_build_deref_var(b, tex_var);9293tex = nir_tex_instr_create(shader, 3);94tex->op = nir_texop_tex;95tex->sampler_dim = GLSL_SAMPLER_DIM_2D;96tex->coord_components = 2;97tex->dest_type = nir_type_float32;98tex->src[0].src_type = nir_tex_src_texture_deref;99tex->src[0].src = nir_src_for_ssa(&tex_deref->dest.ssa);100tex->src[1].src_type = nir_tex_src_sampler_deref;101tex->src[1].src = nir_src_for_ssa(&tex_deref->dest.ssa);102tex->src[2].src_type = nir_tex_src_coord;103tex->src[2].src =104nir_src_for_ssa(nir_channels(b, texcoord,105(1 << tex->coord_components) - 1));106107nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL);108nir_builder_instr_insert(b, &tex->instr);109110/* kill if tex != 0.0.. take .x or .w channel according to format: */111cond = nir_f2b(b, nir_channel(b, &tex->dest.ssa,112options->swizzle_xxxx ? 0 : 3));113114nir_discard_if(b, cond);115116shader->info.fs.uses_discard = true;117}118119static void120lower_bitmap_impl(nir_function_impl *impl,121const nir_lower_bitmap_options *options)122{123nir_builder b;124125nir_builder_init(&b, impl);126b.cursor = nir_before_cf_list(&impl->body);127128lower_bitmap(impl->function->shader, &b, options);129130nir_metadata_preserve(impl, nir_metadata_block_index |131nir_metadata_dominance);132}133134void135nir_lower_bitmap(nir_shader *shader,136const nir_lower_bitmap_options *options)137{138assert(shader->info.stage == MESA_SHADER_FRAGMENT);139140lower_bitmap_impl(nir_shader_get_entrypoint(shader), options);141}142143144