1 /************************************************************************** 2 * 3 * Copyright (C) 2015 Advanced Micro Devices, Inc. 4 * Copyright 2007 VMware, Inc. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 29 #include "st_cb_bitmap.h" 30 #include "tgsi/tgsi_transform.h" 31 #include "tgsi/tgsi_scan.h" 32 #include "tgsi/tgsi_dump.h" 33 #include "util/u_debug.h" 34 35 struct tgsi_bitmap_transform { 36 struct tgsi_transform_context base; 37 struct tgsi_shader_info info; 38 unsigned sampler_index; 39 unsigned tex_target; 40 bool use_texcoord; 41 bool swizzle_xxxx; 42 bool first_instruction_emitted; 43 }; 44 45 static inline struct tgsi_bitmap_transform * 46 tgsi_bitmap_transform(struct tgsi_transform_context *tctx) 47 { 48 return (struct tgsi_bitmap_transform *)tctx; 49 } 50 51 static void 52 transform_instr(struct tgsi_transform_context *tctx, 53 struct tgsi_full_instruction *current_inst) 54 { 55 struct tgsi_bitmap_transform *ctx = tgsi_bitmap_transform(tctx); 56 struct tgsi_full_instruction inst; 57 unsigned tgsi_tex_target = ctx->tex_target == PIPE_TEXTURE_2D 58 ? TGSI_TEXTURE_2D : TGSI_TEXTURE_RECT; 59 unsigned i, semantic; 60 int texcoord_index = -1; 61 62 if (ctx->first_instruction_emitted) { 63 tctx->emit_instruction(tctx, current_inst); 64 return; 65 } 66 67 ctx->first_instruction_emitted = true; 68 69 /* Add TEMP[0] if it's missing. */ 70 if (ctx->info.file_max[TGSI_FILE_TEMPORARY] == -1) { 71 tgsi_transform_temp_decl(tctx, 0); 72 } 73 74 /* Add TEXCOORD[0] if it's missing. */ 75 semantic = ctx->use_texcoord ? TGSI_SEMANTIC_TEXCOORD : 76 TGSI_SEMANTIC_GENERIC; 77 for (i = 0; i < ctx->info.num_inputs; i++) { 78 if (ctx->info.input_semantic_name[i] == semantic && 79 ctx->info.input_semantic_index[i] == 0) { 80 texcoord_index = i; 81 break; 82 } 83 } 84 85 if (texcoord_index == -1) { 86 texcoord_index = ctx->info.num_inputs; 87 tgsi_transform_input_decl(tctx, texcoord_index, 88 semantic, 0, TGSI_INTERPOLATE_PERSPECTIVE); 89 } 90 91 /* Declare the sampler. */ 92 tgsi_transform_sampler_decl(tctx, ctx->sampler_index); 93 94 /* Declare the sampler view. */ 95 tgsi_transform_sampler_view_decl(tctx, ctx->sampler_index, 96 tgsi_tex_target, TGSI_RETURN_TYPE_FLOAT); 97 98 /* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */ 99 tgsi_transform_tex_inst(tctx, 100 TGSI_FILE_TEMPORARY, 0, 101 TGSI_FILE_INPUT, texcoord_index, 102 tgsi_tex_target, ctx->sampler_index); 103 104 /* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */ 105 inst = tgsi_default_full_instruction(); 106 inst.Instruction.Opcode = TGSI_OPCODE_KILL_IF; 107 inst.Instruction.NumDstRegs = 0; 108 inst.Instruction.NumSrcRegs = 1; 109 110 inst.Src[0].Register.File = TGSI_FILE_TEMPORARY; 111 inst.Src[0].Register.Index = 0; 112 inst.Src[0].Register.Negate = 1; 113 inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X; 114 if (ctx->swizzle_xxxx) { 115 inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X; 116 inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X; 117 inst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_X; 118 } else { 119 inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_Y; 120 inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_Z; 121 inst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_W; 122 } 123 tctx->emit_instruction(tctx, &inst); 124 125 /* And emit the instruction we got. */ 126 tctx->emit_instruction(tctx, current_inst); 127 } 128 129 const struct tgsi_token * 130 st_get_bitmap_shader(const struct tgsi_token *tokens, 131 unsigned tex_target, unsigned sampler_index, 132 bool use_texcoord, bool swizzle_xxxx) 133 { 134 struct tgsi_bitmap_transform ctx; 135 struct tgsi_token *newtoks; 136 int newlen; 137 138 assert(tex_target == PIPE_TEXTURE_2D || 139 tex_target == PIPE_TEXTURE_RECT); 140 141 memset(&ctx, 0, sizeof(ctx)); 142 ctx.base.transform_instruction = transform_instr; 143 ctx.tex_target = tex_target; 144 ctx.sampler_index = sampler_index; 145 ctx.use_texcoord = use_texcoord; 146 ctx.swizzle_xxxx = swizzle_xxxx; 147 tgsi_scan_shader(tokens, &ctx.info); 148 149 newlen = tgsi_num_tokens(tokens) + 20; 150 newtoks = tgsi_alloc_tokens(newlen); 151 if (!newtoks) 152 return NULL; 153 154 tgsi_transform_shader(tokens, newtoks, newlen, &ctx.base); 155 return newtoks; 156 } 157