Home | History | Annotate | Download | only in state_tracker
      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