135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**********************************************************
235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Copyright 1998-2013 VMware, Inc.  All rights reserved.
335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Permission is hereby granted, free of charge, to any person
535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * obtaining a copy of this software and associated documentation
635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * files (the "Software"), to deal in the Software without
735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * restriction, including without limitation the rights to use, copy,
835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * modify, merge, publish, distribute, sublicense, and/or sell copies
935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * of the Software, and to permit persons to whom the Software is
1035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * furnished to do so, subject to the following conditions:
1135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
1235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * The above copyright notice and this permission notice shall be
1335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * included in all copies or substantial portions of the Software.
1435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
1535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * SOFTWARE.
2335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
2435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul **********************************************************/
2535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
2635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
2735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * @file svga_tgsi_vgpu10.c
2835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
2935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * TGSI -> VGPU10 shader translation.
3035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
3135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \author Mingcheng Chen
3235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \author Brian Paul
3335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
3435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
3535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "pipe/p_compiler.h"
3635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "pipe/p_shader_tokens.h"
3735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "pipe/p_defines.h"
3835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "tgsi/tgsi_build.h"
3935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "tgsi/tgsi_dump.h"
4035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "tgsi/tgsi_info.h"
4135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "tgsi/tgsi_parse.h"
4235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "tgsi/tgsi_scan.h"
4335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "tgsi/tgsi_two_side.h"
4435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "tgsi/tgsi_aa_point.h"
4535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "tgsi/tgsi_util.h"
4635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "util/u_math.h"
4735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "util/u_memory.h"
4835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "util/u_bitmask.h"
4935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "util/u_debug.h"
5035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "util/u_pstipple.h"
5135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
5235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "svga_context.h"
5335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "svga_debug.h"
5435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "svga_link.h"
5535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "svga_shader.h"
5635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "svga_tgsi.h"
5735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
5835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#include "VGPU10ShaderTokens.h"
5935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
6035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
6135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#define INVALID_INDEX 99999
6235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#define MAX_INTERNAL_TEMPS 3
6335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#define MAX_SYSTEM_VALUES 4
6435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#define MAX_IMMEDIATE_COUNT \
6535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul        (VGPU10_MAX_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT/4)
6635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#define MAX_TEMP_ARRAYS 64  /* Enough? */
6735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
6835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
6935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
7035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Clipping is complicated.  There's four different cases which we
7135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * handle during VS/GS shader translation:
7235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
7335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulenum clipping_mode
7435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
7535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   CLIP_NONE,     /**< No clipping enabled */
7635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   CLIP_LEGACY,   /**< The shader has no clipping declarations or code but
7735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   * one or more user-defined clip planes are enabled.  We
7835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   * generate extra code to emit clip distances.
7935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   */
8035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   CLIP_DISTANCE, /**< The shader already declares clip distance output
8135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   * registers and has code to write to them.
8235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   */
8335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   CLIP_VERTEX    /**< The shader declares a clip vertex output register and
8435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  * has code that writes to the register.  We convert the
8535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  * clipvertex position into one or more clip distances.
8635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  */
8735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul};
8835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
8935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
9035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstruct svga_shader_emitter_v10
9135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
9235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* The token output buffer */
9335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned size;
9435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   char *buf;
9535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   char *ptr;
9635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
9735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Information about the shader and state (does not change) */
9835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct svga_compile_key key;
9935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_shader_info info;
10035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned unit;
10135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
10235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned inst_start_token;
10335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   boolean discard_instruction; /**< throw away current instruction? */
10435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
10535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   union tgsi_immediate_data immediates[MAX_IMMEDIATE_COUNT][4];
10635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned num_immediates;      /**< Number of immediates emitted */
10735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned common_immediate_pos[8];  /**< literals for common immediates */
10835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned num_common_immediates;
10935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   boolean immediates_emitted;
11035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
11135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned num_outputs;      /**< include any extra outputs */
11235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              /**  The first extra output is reserved for
11335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                               *   non-adjusted vertex position for
11435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                               *   stream output purpose
11535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                               */
11635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
11735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Temporary Registers */
11835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned num_shader_temps; /**< num of temps used by original shader */
11935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned internal_temp_count;  /**< currently allocated internal temps */
12035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct {
12135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned start, size;
12235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } temp_arrays[MAX_TEMP_ARRAYS];
12335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned num_temp_arrays;
12435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
12535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /** Map TGSI temp registers to VGPU10 temp array IDs and indexes */
12635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct {
12735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned arrayId, index;
12835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } temp_map[VGPU10_MAX_TEMPS]; /**< arrayId, element */
12935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
13035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /** Number of constants used by original shader for each constant buffer.
13135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * The size should probably always match with that of svga_state.constbufs.
13235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
13335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned num_shader_consts[SVGA_MAX_CONST_BUFS];
13435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
13535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Samplers */
13635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned num_samplers;
137dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   ubyte sampler_target[PIPE_MAX_SAMPLERS];  /**< TGSI_TEXTURE_x */
138dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   ubyte sampler_return_type[PIPE_MAX_SAMPLERS];  /**< TGSI_RETURN_TYPE_x */
13935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
14035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Address regs (really implemented with temps) */
14135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned num_address_regs;
14235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned address_reg_index[MAX_VGPU10_ADDR_REGS];
14335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
14435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Output register usage masks */
14535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   ubyte output_usage_mask[PIPE_MAX_SHADER_OUTPUTS];
14635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
14735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* To map TGSI system value index to VGPU shader input indexes */
14835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   ubyte system_value_indexes[MAX_SYSTEM_VALUES];
14935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
15035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct {
15135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* vertex position scale/translation */
15235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned out_index;  /**< the real position output reg */
15335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned tmp_index;  /**< the fake/temp position output reg */
15435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned so_index;   /**< the non-adjusted position output reg */
15535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned prescale_scale_index, prescale_trans_index;
15635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      boolean  need_prescale;
15735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } vposition;
15835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
15935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* For vertex shaders only */
16035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct {
16135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* viewport constant */
16235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned viewport_index;
16335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
16435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* temp index of adjusted vertex attributes */
16535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned adjusted_input[PIPE_MAX_SHADER_INPUTS];
16635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } vs;
16735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
16835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* For fragment shaders only */
16935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct {
17035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* apha test */
17135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned color_out_index[PIPE_MAX_COLOR_BUFS];  /**< the real color output regs */
17235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned color_tmp_index;  /**< fake/temp color output reg */
17335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned alpha_ref_index;  /**< immediate constant for alpha ref */
17435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
17535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* front-face */
17635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned face_input_index; /**< real fragment shader face reg (bool) */
17735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned face_tmp_index;   /**< temp face reg converted to -1 / +1 */
17835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
17935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned pstipple_sampler_unit;
18035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
18135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned fragcoord_input_index;  /**< real fragment position input reg */
18235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned fragcoord_tmp_index;    /**< 1/w modified position temp reg */
18335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } fs;
18435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
18535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* For geometry shaders only */
18635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct {
18735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE prim_type;/**< VGPU10 primitive type */
18835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY prim_topology; /**< VGPU10 primitive topology */
18935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned input_size;       /**< size of input arrays */
19035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned prim_id_index;    /**< primitive id register index */
19135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned max_out_vertices; /**< maximum number of output vertices */
19235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } gs;
19335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
19435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* For vertex or geometry shaders */
19535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   enum clipping_mode clip_mode;
19635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned clip_dist_out_index; /**< clip distance output register index */
19735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned clip_dist_tmp_index; /**< clip distance temporary register */
19835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned clip_dist_so_index;  /**< clip distance shadow copy */
19935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
20035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /** Index of temporary holding the clipvertex coordinate */
20135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned clip_vertex_out_index; /**< clip vertex output register index */
20235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned clip_vertex_tmp_index; /**< clip vertex temporary index */
20335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
20435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* user clip plane constant slot indexes */
20535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned clip_plane_const[PIPE_MAX_CLIP_PLANES];
20635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
2071082735bb69e9f64cb3991a52f0e270902917855Brian Paul   unsigned num_output_writes;
2081082735bb69e9f64cb3991a52f0e270902917855Brian Paul   boolean constant_color_output;
2091082735bb69e9f64cb3991a52f0e270902917855Brian Paul
21035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   boolean uses_flat_interp;
21135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
21235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* For all shaders: const reg index for RECT coord scaling */
21335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned texcoord_scale_index[PIPE_MAX_SAMPLERS];
21435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
21535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* For all shaders: const reg index for texture buffer size */
21635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned texture_buffer_size_index[PIPE_MAX_SAMPLERS];
21735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
21835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* VS/GS/FS Linkage info */
21935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct shader_linkage linkage;
22035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
22135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   bool register_overflow;  /**< Set if we exceed a VGPU10 register limit */
22235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul};
22335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
22435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
22535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
22635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_post_helpers(struct svga_shader_emitter_v10 *emit);
22735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
22835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
22935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vertex(struct svga_shader_emitter_v10 *emit,
23035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            const struct tgsi_full_instruction *inst);
23135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
23235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic char err_buf[128];
23335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
23435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
23535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulexpand(struct svga_shader_emitter_v10 *emit)
23635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
23735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   char *new_buf;
23835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned newsize = emit->size * 2;
23935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
24035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->buf != err_buf)
24135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      new_buf = REALLOC(emit->buf, emit->size, newsize);
24235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else
24335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      new_buf = NULL;
24435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
24513eb5f596bc8ece3d1805b388aa53917e6158d7bEdward O'Callaghan   if (!new_buf) {
24635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->ptr = err_buf;
24735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->buf = err_buf;
24835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->size = sizeof(err_buf);
24935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
25035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
25135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
25235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->size = newsize;
25335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->ptr = new_buf + (emit->ptr - emit->buf);
25435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->buf = new_buf;
25535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
25635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
25735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
25835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
25935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create and initialize a new svga_shader_emitter_v10 object.
26035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
26135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct svga_shader_emitter_v10 *
26235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulalloc_emitter(void)
26335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
26435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct svga_shader_emitter_v10 *emit = CALLOC(1, sizeof(*emit));
26535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
26635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!emit)
26735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return NULL;
26835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
26935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* to initialize the output buffer */
27035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->size = 512;
27135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!expand(emit)) {
27235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      FREE(emit);
27335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return NULL;
27435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
27535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return emit;
27635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
27735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
27835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
27935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Free an svga_shader_emitter_v10 object.
28035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
28135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
28235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulfree_emitter(struct svga_shader_emitter_v10 *emit)
28335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
28435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit);
28535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   FREE(emit->buf);    /* will be NULL if translation succeeded */
28635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   FREE(emit);
28735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
28835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
289e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulstatic inline boolean
29035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulreserve(struct svga_shader_emitter_v10 *emit,
29135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul        unsigned nr_dwords)
29235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
29335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   while (emit->ptr - emit->buf + nr_dwords * sizeof(uint32) >= emit->size) {
29435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (!expand(emit))
29535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         return FALSE;
29635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
29735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
29835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
29935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
30035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
30135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
30235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_dword(struct svga_shader_emitter_v10 *emit, uint32 dword)
30335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
30435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!reserve(emit, 1))
30535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
30635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
30735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   *(uint32 *)emit->ptr = dword;
30835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->ptr += sizeof dword;
30935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
31035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
31135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
31235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
31335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_dwords(struct svga_shader_emitter_v10 *emit,
31435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            const uint32 *dwords,
31535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            unsigned nr)
31635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
31735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!reserve(emit, nr))
31835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
31935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
32035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   memcpy(emit->ptr, dwords, nr * sizeof *dwords);
32135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->ptr += nr * sizeof *dwords;
32235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
32335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
32435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
32535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/** Return the number of tokens in the emitter's buffer */
32635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
32735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_get_num_tokens(const struct svga_shader_emitter_v10 *emit)
32835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
32935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return (emit->ptr - emit->buf) / sizeof(unsigned);
33035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
33135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
33235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
33335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
33435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Check for register overflow.  If we overflow we'll set an
33535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * error flag.  This function can be called for register declarations
33635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * or use as src/dst instruction operands.
33735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param type  register type.  One of VGPU10_OPERAND_TYPE_x
33835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                or VGPU10_OPCODE_DCL_x
33935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param index  the register index
34035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
34135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
34235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulcheck_register_index(struct svga_shader_emitter_v10 *emit,
34335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     unsigned operandType, unsigned index)
34435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
34535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   bool overflow_before = emit->register_overflow;
34635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
34735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (operandType) {
34835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPERAND_TYPE_TEMP:
34935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPERAND_TYPE_INDEXABLE_TEMP:
35035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_TEMPS:
35135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (index >= VGPU10_MAX_TEMPS) {
35235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->register_overflow = TRUE;
35335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
35435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
35535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPERAND_TYPE_CONSTANT_BUFFER:
35635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_CONSTANT_BUFFER:
35735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (index >= VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT) {
35835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->register_overflow = TRUE;
35935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
36035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
36135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPERAND_TYPE_INPUT:
36235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID:
36335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_INPUT:
36435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_INPUT_SGV:
36535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_INPUT_SIV:
36635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_INPUT_PS:
36735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_INPUT_PS_SGV:
36835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_INPUT_PS_SIV:
36935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if ((emit->unit == PIPE_SHADER_VERTEX &&
37035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul           index >= VGPU10_MAX_VS_INPUTS) ||
37135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          (emit->unit == PIPE_SHADER_GEOMETRY &&
37235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul           index >= VGPU10_MAX_GS_INPUTS) ||
37335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          (emit->unit == PIPE_SHADER_FRAGMENT &&
37435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul           index >= VGPU10_MAX_FS_INPUTS)) {
37535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->register_overflow = TRUE;
37635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
37735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
37835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPERAND_TYPE_OUTPUT:
37935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_OUTPUT:
38035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_OUTPUT_SGV:
38135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_OUTPUT_SIV:
38235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if ((emit->unit == PIPE_SHADER_VERTEX &&
38335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul           index >= VGPU10_MAX_VS_OUTPUTS) ||
38435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          (emit->unit == PIPE_SHADER_GEOMETRY &&
38535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul           index >= VGPU10_MAX_GS_OUTPUTS) ||
38635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          (emit->unit == PIPE_SHADER_FRAGMENT &&
38735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul           index >= VGPU10_MAX_FS_OUTPUTS)) {
38835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->register_overflow = TRUE;
38935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
39035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
39135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPERAND_TYPE_SAMPLER:
39235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_SAMPLER:
39335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (index >= VGPU10_MAX_SAMPLERS) {
39435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->register_overflow = TRUE;
39535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
39635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
39735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPERAND_TYPE_RESOURCE:
39835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPCODE_DCL_RESOURCE:
39935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (index >= VGPU10_MAX_RESOURCES) {
40035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->register_overflow = TRUE;
40135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
40235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
40335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case VGPU10_OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER:
40435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (index >= MAX_IMMEDIATE_COUNT) {
40535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->register_overflow = TRUE;
40635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
40735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
40835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
40935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(0);
41035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      ; /* nothing */
41135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
41235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
41335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->register_overflow && !overflow_before) {
41435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("svga: vgpu10 register overflow (reg %u, index %u)\n",
41535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   operandType, index);
41635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
41735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
41835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
41935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
42035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
42135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Examine misc state to determine the clipping mode.
42235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
42335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
42435bb29d4994efadd1719a147731afa34e78a0be1Brian Pauldetermine_clipping_mode(struct svga_shader_emitter_v10 *emit)
42535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
42635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->info.num_written_clipdistance > 0) {
42735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->clip_mode = CLIP_DISTANCE;
42835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
42935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (emit->info.writes_clipvertex) {
43035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->clip_mode = CLIP_VERTEX;
43135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
43235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (emit->key.clip_plane_enable) {
43335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->clip_mode = CLIP_LEGACY;
43435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
43535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
43635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->clip_mode = CLIP_NONE;
43735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
43835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
43935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
44035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
44135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
44235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * For clip distance register declarations and clip distance register
44335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * writes we need to mask the declaration usage or instruction writemask
44435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * (respectively) against the set of the really-enabled clipping planes.
44535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
44635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * The piglit test spec/glsl-1.30/execution/clipping/vs-clip-distance-enables
44735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * has a VS that writes to all 8 clip distance registers, but the plane enable
44835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * flags are a subset of that.
44935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
45035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * This function is used to apply the plane enable flags to the register
45135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * declaration or instruction writemask.
45235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
45335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param writemask  the declaration usage mask or instruction writemask
45435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param clip_reg_index  which clip plane register is being declared/written.
45535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *                        The legal values are 0 and 1 (two clip planes per
45635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *                        register, for a total of 8 clip planes)
45735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
45835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
45935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulapply_clip_plane_mask(struct svga_shader_emitter_v10 *emit,
46035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      unsigned writemask, unsigned clip_reg_index)
46135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
46235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned shift;
46335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
46435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(clip_reg_index < 2);
46535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
46635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* four clip planes per clip register: */
46735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   shift = clip_reg_index * 4;
46835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   writemask &= ((emit->key.clip_plane_enable >> shift) & 0xf);
46935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
47035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return writemask;
47135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
47235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
47335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
47435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
47535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate gallium shader type into VGPU10 type.
47635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
47735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic VGPU10_PROGRAM_TYPE
47835bb29d4994efadd1719a147731afa34e78a0be1Brian Paultranslate_shader_type(unsigned type)
47935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
48035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (type) {
48135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case PIPE_SHADER_VERTEX:
48235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_VERTEX_SHADER;
48335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case PIPE_SHADER_GEOMETRY:
48435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_GEOMETRY_SHADER;
48535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case PIPE_SHADER_FRAGMENT:
48635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_PIXEL_SHADER;
48735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
48835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"Unexpected shader type");
48935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_VERTEX_SHADER;
49035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
49135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
49235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
49335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
49435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
49535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate a TGSI_OPCODE_x into a VGPU10_OPCODE_x
49635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Note: we only need to translate the opcodes for "simple" instructions,
49735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * as seen below.  All other opcodes are handled/translated specially.
49835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
49935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic VGPU10_OPCODE_TYPE
50035bb29d4994efadd1719a147731afa34e78a0be1Brian Paultranslate_opcode(unsigned opcode)
50135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
50235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (opcode) {
50335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MOV:
50435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_MOV;
50535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MUL:
50635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_MUL;
50735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ADD:
50835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ADD;
50935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DP3:
51035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_DP3;
51135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DP4:
51235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_DP4;
51335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MIN:
51435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_MIN;
51535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MAX:
51635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_MAX;
51735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MAD:
51835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_MAD;
51935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SQRT:
52035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_SQRT;
52135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FRC:
52235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_FRC;
52335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FLR:
52435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ROUND_NI;
52535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FSEQ:
52635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_EQ;
52735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FSGE:
52835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_GE;
52935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FSNE:
53035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_NE;
53135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DDX:
53235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_DERIV_RTX;
53335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DDY:
53435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_DERIV_RTY;
53535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_RET:
53635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_RET;
53735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DIV:
53835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_DIV;
53935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IDIV:
54035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_IDIV;
54135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DP2:
54235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_DP2;
54335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_BRK:
54435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_BREAK;
54535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IF:
54635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_IF;
54735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ELSE:
54835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ELSE;
54935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ENDIF:
55035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ENDIF;
55135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_CEIL:
55235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ROUND_PI;
55335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_I2F:
55435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ITOF;
55535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_NOT:
55635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_NOT;
55735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TRUNC:
55835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ROUND_Z;
55935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SHL:
56035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ISHL;
56135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_AND:
56235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_AND;
56335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_OR:
56435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_OR;
56535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_XOR:
56635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_XOR;
56735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_CONT:
56835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_CONTINUE;
56935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_EMIT:
57035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_EMIT;
57135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ENDPRIM:
57235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_CUT;
57335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_BGNLOOP:
57435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_LOOP;
57535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ENDLOOP:
57635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ENDLOOP;
57735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ENDSUB:
57835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_RET;
57935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_NOP:
58035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_NOP;
58135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_BREAKC:
58235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_BREAKC;
58335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_END:
58435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_RET;
58535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_F2I:
58635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_FTOI;
58735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IMAX:
58835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_IMAX;
58935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IMIN:
59035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_IMIN;
59135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UDIV:
59235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMOD:
59335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MOD:
59435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_UDIV;
59535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IMUL_HI:
59635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_IMUL;
59735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_INEG:
59835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_INEG;
59935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ISHR:
60035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ISHR;
60135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ISGE:
60235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_IGE;
60335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ISLT:
60435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ILT;
60535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_F2U:
60635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_FTOU;
60735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UADD:
60835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_IADD;
60935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_U2F:
61035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_UTOF;
61135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UCMP:
61235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_MOVC;
61335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMAD:
61435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_UMAD;
61535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMAX:
61635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_UMAX;
61735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMIN:
61835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_UMIN;
61935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMUL:
62035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMUL_HI:
62135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_UMUL;
62235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USEQ:
62335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_IEQ;
62435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USGE:
62535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_UGE;
62635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USHR:
62735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_USHR;
62835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USLT:
62935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ULT;
63035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USNE:
63135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_INE;
63235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SWITCH:
63335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_SWITCH;
63435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_CASE:
63535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_CASE;
63635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DEFAULT:
63735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_DEFAULT;
63835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ENDSWITCH:
63935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ENDSWITCH;
64035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FSLT:
64135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_LT;
64235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ROUND:
64335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_ROUND_NE;
64435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
64535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"Unexpected TGSI opcode in translate_opcode()");
64635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPCODE_NOP;
64735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
64835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
64935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
65035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
65135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
65235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate a TGSI register file type into a VGPU10 operand type.
65335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param array  is the TGSI_FILE_TEMPORARY register an array?
65435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
65535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic VGPU10_OPERAND_TYPE
65635bb29d4994efadd1719a147731afa34e78a0be1Brian Paultranslate_register_file(enum tgsi_file_type file, boolean array)
65735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
65835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (file) {
65935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_CONSTANT:
66035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPERAND_TYPE_CONSTANT_BUFFER;
66135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_INPUT:
66235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPERAND_TYPE_INPUT;
66335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_OUTPUT:
66435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPERAND_TYPE_OUTPUT;
66535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_TEMPORARY:
66635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return array ? VGPU10_OPERAND_TYPE_INDEXABLE_TEMP
66735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   : VGPU10_OPERAND_TYPE_TEMP;
66835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_IMMEDIATE:
66935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* all immediates are 32-bit values at this time so
67035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * VGPU10_OPERAND_TYPE_IMMEDIATE64 is not possible at this time.
67135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
67235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER;
67335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_SAMPLER:
67435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPERAND_TYPE_SAMPLER;
67535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_SYSTEM_VALUE:
67635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPERAND_TYPE_INPUT;
67735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
67835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* XXX TODO more cases to finish */
67935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
68035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
68135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"Bad tgsi register file!");
68235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_OPERAND_TYPE_NULL;
68335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
68435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
68535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
68635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
68735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
68835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit a null dst register
68935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
69035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
69135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_null_dst_register(struct svga_shader_emitter_v10 *emit)
69235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
69335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand;
69435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
69535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand.value = 0;
69635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand.operandType = VGPU10_OPERAND_TYPE_NULL;
69735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand.numComponents = VGPU10_OPERAND_0_COMPONENT;
69835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
69935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, operand.value);
70035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
70135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
70235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
70335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
70435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * If the given register is a temporary, return the array ID.
70535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Else return zero.
70635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
70735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
70835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulget_temp_array_id(const struct svga_shader_emitter_v10 *emit,
70935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  unsigned file, unsigned index)
71035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
71135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (file == TGSI_FILE_TEMPORARY) {
71235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit->temp_map[index].arrayId;
71335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
71435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
71535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return 0;
71635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
71735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
71835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
71935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
72035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
72135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * If the given register is a temporary, convert the index from a TGSI
72235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * TEMPORARY index to a VGPU10 temp index.
72335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
72435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
72535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulremap_temp_index(const struct svga_shader_emitter_v10 *emit,
72635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                 unsigned file, unsigned index)
72735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
72835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (file == TGSI_FILE_TEMPORARY) {
72935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit->temp_map[index].index;
73035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
73135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
73235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return index;
73335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
73435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
73535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
73635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
73735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
73835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Setup the operand0 fields related to indexing (1D, 2D, relative, etc).
73935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Note: the operandType field must already be initialized.
74035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
74135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic VGPU10OperandToken0
74235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulsetup_operand0_indexing(struct svga_shader_emitter_v10 *emit,
74335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        VGPU10OperandToken0 operand0,
74435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        unsigned file,
74535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        boolean indirect, boolean index2D,
74635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        unsigned tempArrayID)
74735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
748b09e4ab13cdde9b0d465c214e6e30452c690eeb1Brian Paul   unsigned indexDim, index0Rep, index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
74935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
75035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
75135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Compute index dimensions
75235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
75335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (operand0.operandType == VGPU10_OPERAND_TYPE_IMMEDIATE32 ||
75435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       operand0.operandType == VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID) {
75535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* there's no swizzle for in-line immediates */
75635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      indexDim = VGPU10_OPERAND_INDEX_0D;
75735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(operand0.selectionMode == 0);
75835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
75935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
76035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (index2D ||
76135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          tempArrayID > 0 ||
76235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          operand0.operandType == VGPU10_OPERAND_TYPE_CONSTANT_BUFFER) {
76335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         indexDim = VGPU10_OPERAND_INDEX_2D;
76435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
76535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else {
76635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         indexDim = VGPU10_OPERAND_INDEX_1D;
76735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
76835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
76935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
77035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
77135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Compute index representations (immediate, relative, etc).
77235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
77335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (tempArrayID > 0) {
77435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(file == TGSI_FILE_TEMPORARY);
77535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* First index is the array ID, second index is the array element */
77635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      index0Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
77735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (indirect) {
77835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE;
77935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
78035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else {
78135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
78235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
78335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
78435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (indirect) {
78535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (file == TGSI_FILE_CONSTANT) {
78635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* index[0] indicates which constant buffer while index[1] indicates
78735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * the position in the constant buffer.
78835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          */
78935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         index0Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
79035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE;
79135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
79235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else {
79335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* All other register files are 1-dimensional */
79435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         index0Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE;
79535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
79635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
79735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
79835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      index0Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
79935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
80035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
80135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
80235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.indexDimension = indexDim;
80335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.index0Representation = index0Rep;
80435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.index1Representation = index1Rep;
80535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
80635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return operand0;
80735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
80835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
80935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
81035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
81135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the operand for expressing an address register for indirect indexing.
81235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Note that the address register is really just a temp register.
81335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param addr_reg_index  which address register to use
81435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
81535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
81635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_indirect_register(struct svga_shader_emitter_v10 *emit,
81735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       unsigned addr_reg_index)
81835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
81935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp_reg_index;
82035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
82135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
82235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(addr_reg_index < MAX_VGPU10_ADDR_REGS);
82335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
82435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tmp_reg_index = emit->address_reg_index[addr_reg_index];
82535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
82635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* operand0 is a simple temporary register, selecting one component */
82735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.value = 0;
82835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.operandType = VGPU10_OPERAND_TYPE_TEMP;
82935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
83035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
83135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
83235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SELECT_1_MODE;
83335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleX = 0;
83435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleY = 1;
83535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleZ = 2;
83635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleW = 3;
83735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
83835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, operand0.value);
83935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, remap_temp_index(emit, TGSI_FILE_TEMPORARY, tmp_reg_index));
84035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
84135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
84235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
84335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
84435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate the dst register of a TGSI instruction and emit VGPU10 tokens.
84535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param emit  the emitter context
84635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param reg  the TGSI dst register to translate
84735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
84835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
84935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_dst_register(struct svga_shader_emitter_v10 *emit,
85035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  const struct tgsi_full_dst_register *reg)
85135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
85235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned file = reg->Register.File;
85335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned index = reg->Register.Index;
85435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned sem_name = emit->info.output_semantic_name[index];
85535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned sem_index = emit->info.output_semantic_index[index];
85635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned writemask = reg->Register.WriteMask;
85735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned indirect = reg->Register.Indirect;
85835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned tempArrayId = get_temp_array_id(emit, file, index);
85935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned index2d = reg->Register.Dimension;
86035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
86135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
86235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (file == TGSI_FILE_OUTPUT) {
86335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->unit == PIPE_SHADER_VERTEX ||
86435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          emit->unit == PIPE_SHADER_GEOMETRY) {
86535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (index == emit->vposition.out_index &&
86635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             emit->vposition.tmp_index != INVALID_INDEX) {
86735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* replace OUTPUT[POS] with TEMP[POS].  We need to store the
86835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * vertex position result in a temporary so that we can modify
86935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * it in the post_helper() code.
87035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             */
87135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            file = TGSI_FILE_TEMPORARY;
87235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            index = emit->vposition.tmp_index;
87335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
87435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (sem_name == TGSI_SEMANTIC_CLIPDIST &&
87535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  emit->clip_dist_tmp_index != INVALID_INDEX) {
87635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* replace OUTPUT[CLIPDIST] with TEMP[CLIPDIST].
87735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * We store the clip distance in a temporary first, then
87835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * we'll copy it to the shadow copy and to CLIPDIST with the
87935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * enabled planes mask in emit_clip_distance_instructions().
88035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             */
88135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            file = TGSI_FILE_TEMPORARY;
88235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            index = emit->clip_dist_tmp_index + sem_index;
88335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
88435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (sem_name == TGSI_SEMANTIC_CLIPVERTEX &&
88535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  emit->clip_vertex_tmp_index != INVALID_INDEX) {
88635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* replace the CLIPVERTEX output register with a temporary */
88735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            assert(emit->clip_mode == CLIP_VERTEX);
88835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            assert(sem_index == 0);
88935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            file = TGSI_FILE_TEMPORARY;
89035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            index = emit->clip_vertex_tmp_index;
89135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
89235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
89335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else if (emit->unit == PIPE_SHADER_FRAGMENT) {
89435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (sem_name == TGSI_SEMANTIC_POSITION) {
89535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* Fragment depth output register */
89635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            operand0.value = 0;
89735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            operand0.operandType = VGPU10_OPERAND_TYPE_OUTPUT_DEPTH;
89835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            operand0.indexDimension = VGPU10_OPERAND_INDEX_0D;
89935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            operand0.numComponents = VGPU10_OPERAND_1_COMPONENT;
90035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_dword(emit, operand0.value);
90135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            return;
90235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
90335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (index == emit->fs.color_out_index[0] &&
90435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             emit->fs.color_tmp_index != INVALID_INDEX) {
90535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* replace OUTPUT[COLOR] with TEMP[COLOR].  We need to store the
90635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * fragment color result in a temporary so that we can read it
90735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * it in the post_helper() code.
90835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             */
90935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            file = TGSI_FILE_TEMPORARY;
91035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            index = emit->fs.color_tmp_index;
91135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
91235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else {
91335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* Typically, for fragment shaders, the output register index
91435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * matches the color semantic index.  But not when we write to
91535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * the fragment depth register.  In that case, OUT[0] will be
91635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * fragdepth and OUT[1] will be the 0th color output.  We need
91735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * to use the semantic index for color outputs.
91835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             */
91935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            assert(sem_name == TGSI_SEMANTIC_COLOR);
92035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            index = emit->info.output_semantic_index[index];
9211082735bb69e9f64cb3991a52f0e270902917855Brian Paul
9221082735bb69e9f64cb3991a52f0e270902917855Brian Paul            emit->num_output_writes++;
92335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
92435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
92535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
92635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
92735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* init operand tokens to all zero */
92835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.value = 0;
92935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
93035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
93135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
93235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* the operand has a writemask */
93335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_MASK_MODE;
93435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
93535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Which of the four dest components to write to. Note that we can use a
93635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * simple assignment here since TGSI writemasks match VGPU10 writemasks.
93735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
93835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   STATIC_ASSERT(TGSI_WRITEMASK_X == VGPU10_OPERAND_4_COMPONENT_MASK_X);
93935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.mask = writemask;
94035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
94135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* translate TGSI register file type to VGPU10 operand type */
94235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.operandType = translate_register_file(file, tempArrayId > 0);
94335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
94435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   check_register_index(emit, operand0.operandType, index);
94535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
94635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0 = setup_operand0_indexing(emit, operand0, file, indirect,
94735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                      index2d, tempArrayId);
94835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
94935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Emit tokens */
95035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, operand0.value);
95135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (tempArrayId > 0) {
95235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, tempArrayId);
95335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
95435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
95535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, remap_temp_index(emit, file, index));
95635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
95735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (indirect) {
95835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_indirect_register(emit, reg->Indirect.Index);
95935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
96035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
96135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
96235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
96335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
96435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate a src register of a TGSI instruction and emit VGPU10 tokens.
96535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
96635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
96735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_src_register(struct svga_shader_emitter_v10 *emit,
96835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  const struct tgsi_full_src_register *reg)
96935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
97035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned file = reg->Register.File;
97135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned index = reg->Register.Index;
97235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned indirect = reg->Register.Indirect;
97335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned tempArrayId = get_temp_array_id(emit, file, index);
97435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned index2d = reg->Register.Dimension;
97535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned swizzleX = reg->Register.SwizzleX;
97635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned swizzleY = reg->Register.SwizzleY;
97735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned swizzleZ = reg->Register.SwizzleZ;
97835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned swizzleW = reg->Register.SwizzleW;
97935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned absolute = reg->Register.Absolute;
98035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned negate = reg->Register.Negate;
98135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   bool is_prim_id = FALSE;
98235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
98335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
98435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken1 operand1;
98535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
98635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->unit == PIPE_SHADER_FRAGMENT &&
98735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      file == TGSI_FILE_INPUT) {
98835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (index == emit->fs.face_input_index) {
98935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* Replace INPUT[FACE] with TEMP[FACE] */
99035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         file = TGSI_FILE_TEMPORARY;
99135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         index = emit->fs.face_tmp_index;
99235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
99335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else if (index == emit->fs.fragcoord_input_index) {
99435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* Replace INPUT[POSITION] with TEMP[POSITION] */
99535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         file = TGSI_FILE_TEMPORARY;
99635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         index = emit->fs.fragcoord_tmp_index;
99735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
99835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else {
99935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* We remap fragment shader inputs to that FS input indexes
100035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * match up with VS/GS output indexes.
100135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          */
100235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         index = emit->linkage.input_map[index];
100335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
100435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
100535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (emit->unit == PIPE_SHADER_GEOMETRY &&
100635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            file == TGSI_FILE_INPUT) {
100735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      is_prim_id = (index == emit->gs.prim_id_index);
100835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      index = emit->linkage.input_map[index];
100935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
101035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (emit->unit == PIPE_SHADER_VERTEX) {
101135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (file == TGSI_FILE_INPUT) {
101235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* if input is adjusted... */
101335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if ((emit->key.vs.adjust_attrib_w_1 |
101435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul              emit->key.vs.adjust_attrib_itof |
101535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul              emit->key.vs.adjust_attrib_utof |
101635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul              emit->key.vs.attrib_is_bgra |
101735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul              emit->key.vs.attrib_puint_to_snorm |
101835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul              emit->key.vs.attrib_puint_to_uscaled |
101935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul              emit->key.vs.attrib_puint_to_sscaled) & (1 << index)) {
102035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            file = TGSI_FILE_TEMPORARY;
102135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            index = emit->vs.adjusted_input[index];
102235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
102335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
102435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else if (file == TGSI_FILE_SYSTEM_VALUE) {
1025e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul         assert(index < ARRAY_SIZE(emit->system_value_indexes));
102635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         index = emit->system_value_indexes[index];
102735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
102835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
102935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
103035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.value = operand1.value = 0;
103135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
103235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (is_prim_id) {
103335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.numComponents = VGPU10_OPERAND_0_COMPONENT;
103435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.operandType = VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID;
103535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
103635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
103735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
103835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.operandType = translate_register_file(file, tempArrayId > 0);
103935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
104035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
104135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0 = setup_operand0_indexing(emit, operand0, file, indirect,
104235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                      index2d, tempArrayId);
104335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
104435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (operand0.operandType != VGPU10_OPERAND_TYPE_IMMEDIATE32 &&
104535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       operand0.operandType != VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID) {
104635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* there's no swizzle for in-line immediates */
104735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (swizzleX == swizzleY &&
104835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          swizzleX == swizzleZ &&
104935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          swizzleX == swizzleW) {
105035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SELECT_1_MODE;
105135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
105235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else {
105335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SWIZZLE_MODE;
105435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
105535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
105635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.swizzleX = swizzleX;
105735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.swizzleY = swizzleY;
105835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.swizzleZ = swizzleZ;
105935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.swizzleW = swizzleW;
106035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
106135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (absolute || negate) {
106235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         operand0.extended = 1;
106335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         operand1.extendedOperandType = VGPU10_EXTENDED_OPERAND_MODIFIER;
106435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (absolute && !negate)
106535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            operand1.operandModifier = VGPU10_OPERAND_MODIFIER_ABS;
106635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (!absolute && negate)
106735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            operand1.operandModifier = VGPU10_OPERAND_MODIFIER_NEG;
106835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (absolute && negate)
106935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            operand1.operandModifier = VGPU10_OPERAND_MODIFIER_ABSNEG;
107035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
107135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
107235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
107335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Emit the operand tokens */
107435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, operand0.value);
107535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (operand0.extended)
107635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, operand1.value);
107735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
107835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (operand0.operandType == VGPU10_OPERAND_TYPE_IMMEDIATE32) {
107935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Emit the four float/int in-line immediate values */
108035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned *c;
1081e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul      assert(index < ARRAY_SIZE(emit->immediates));
108235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(file == TGSI_FILE_IMMEDIATE);
108335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(swizzleX < 4);
108435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(swizzleY < 4);
108535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(swizzleZ < 4);
108635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(swizzleW < 4);
108735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      c = (unsigned *) emit->immediates[index];
108835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, c[swizzleX]);
108935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, c[swizzleY]);
109035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, c[swizzleZ]);
109135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, c[swizzleW]);
109235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
109335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (operand0.indexDimension >= VGPU10_OPERAND_INDEX_1D) {
109435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Emit the register index(es) */
109535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (index2d ||
109635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          operand0.operandType == VGPU10_OPERAND_TYPE_CONSTANT_BUFFER) {
109735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, reg->Dimension.Index);
109835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
109935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
110035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (tempArrayId > 0) {
110135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, tempArrayId);
110235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
110335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
110435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, remap_temp_index(emit, file, index));
110535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
110635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (indirect) {
110735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_indirect_register(emit, reg->Indirect.Index);
110835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
110935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
111035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
111135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
111235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
111335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
111435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit a resource operand (for use with a SAMPLE instruction).
111535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
111635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
111735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_resource_register(struct svga_shader_emitter_v10 *emit,
111835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       unsigned resource_number)
111935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
112035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
112135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
112235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   check_register_index(emit, VGPU10_OPERAND_TYPE_RESOURCE, resource_number);
112335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
112435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* init */
112535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.value = 0;
112635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
112735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.operandType = VGPU10_OPERAND_TYPE_RESOURCE;
112835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
112935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
113035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SWIZZLE_MODE;
113135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleX = VGPU10_COMPONENT_X;
113235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleY = VGPU10_COMPONENT_Y;
113335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleZ = VGPU10_COMPONENT_Z;
113435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleW = VGPU10_COMPONENT_W;
113535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
113635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, operand0.value);
113735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, resource_number);
113835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
113935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
114035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
114135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
114235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit a sampler operand (for use with a SAMPLE instruction).
114335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
114435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
114535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_sampler_register(struct svga_shader_emitter_v10 *emit,
114635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      unsigned sampler_number)
114735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
114835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
114935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
115035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   check_register_index(emit, VGPU10_OPERAND_TYPE_SAMPLER, sampler_number);
115135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
115235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* init */
115335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.value = 0;
115435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
115535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.operandType = VGPU10_OPERAND_TYPE_SAMPLER;
115635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
115735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
115835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, operand0.value);
115935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, sampler_number);
116035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
116135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
116235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
116335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
116435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit an operand which reads the IS_FRONT_FACING register.
116535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
116635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
116735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_face_register(struct svga_shader_emitter_v10 *emit)
116835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
116935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
117035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned index = emit->linkage.input_map[emit->fs.face_input_index];
117135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
117235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* init */
117335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.value = 0;
117435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
117535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.operandType = VGPU10_OPERAND_TYPE_INPUT;
117635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
117735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SELECT_1_MODE;
117835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
117935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
118035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleX = VGPU10_COMPONENT_X;
118135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleY = VGPU10_COMPONENT_X;
118235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleZ = VGPU10_COMPONENT_X;
118335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleW = VGPU10_COMPONENT_X;
118435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
118535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, operand0.value);
118635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, index);
118735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
118835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
118935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
119035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
119135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the token for a VGPU10 opcode.
119235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param saturate   clamp result to [0,1]?
119335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
119435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
119535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_opcode(struct svga_shader_emitter_v10 *emit,
119635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            unsigned vgpu10_opcode, boolean saturate)
119735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
119835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 token0;
119935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
120035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.value = 0;  /* init all fields to zero */
120135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.opcodeType = vgpu10_opcode;
120235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.instructionLength = 0; /* Filled in by end_emit_instruction() */
120335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.saturate = saturate;
120435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
120535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, token0.value);
120635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
120735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
120835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
120935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
121035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the token for a VGPU10 resinfo instruction.
121135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param modifier   return type modifier, _uint or _rcpFloat.
121235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *                   TODO: We may want to remove this parameter if it will
121335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *                   only ever be used as _uint.
121435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
121535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
121635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_opcode_resinfo(struct svga_shader_emitter_v10 *emit,
121735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                    VGPU10_RESINFO_RETURN_TYPE modifier)
121835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
121935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 token0;
122035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
122135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.value = 0;  /* init all fields to zero */
122235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.opcodeType = VGPU10_OPCODE_RESINFO;
122335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.instructionLength = 0; /* Filled in by end_emit_instruction() */
122435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.resinfoReturnType = modifier;
122535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
122635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, token0.value);
122735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
122835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
122935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
123035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
123135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit opcode tokens for a texture sample instruction.  Texture instructions
123235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * can be rather complicated (texel offsets, etc) so we have this specialized
123335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * function.
123435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
123535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
123635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_sample_opcode(struct svga_shader_emitter_v10 *emit,
123735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   unsigned vgpu10_opcode, boolean saturate,
123835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   const int offsets[3])
123935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
124035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 token0;
124135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken1 token1;
124235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
124335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.value = 0;  /* init all fields to zero */
124435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.opcodeType = vgpu10_opcode;
124535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.instructionLength = 0; /* Filled in by end_emit_instruction() */
124635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token0.saturate = saturate;
124735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
124835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (offsets[0] || offsets[1] || offsets[2]) {
124935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(offsets[0] >= VGPU10_MIN_TEXEL_FETCH_OFFSET);
125035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(offsets[1] >= VGPU10_MIN_TEXEL_FETCH_OFFSET);
125135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(offsets[2] >= VGPU10_MIN_TEXEL_FETCH_OFFSET);
125235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(offsets[0] <= VGPU10_MAX_TEXEL_FETCH_OFFSET);
125335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(offsets[1] <= VGPU10_MAX_TEXEL_FETCH_OFFSET);
125435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(offsets[2] <= VGPU10_MAX_TEXEL_FETCH_OFFSET);
125535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
125635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      token0.extended = 1;
125735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      token1.value = 0;
125835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      token1.opcodeType = VGPU10_EXTENDED_OPCODE_SAMPLE_CONTROLS;
125935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      token1.offsetU = offsets[0];
126035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      token1.offsetV = offsets[1];
126135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      token1.offsetW = offsets[2];
126235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
126335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
126435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, token0.value);
126535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (token0.extended) {
126635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, token1.value);
126735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
126835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
126935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
127035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
127135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
127235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit a DISCARD opcode token.
127335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * If nonzero is set, we'll discard the fragment if the X component is not 0.
127435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Otherwise, we'll discard the fragment if the X component is 0.
127535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
127635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
127735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_discard_opcode(struct svga_shader_emitter_v10 *emit, boolean nonzero)
127835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
127935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 opcode0;
128035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
128135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = 0;
128235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.opcodeType = VGPU10_OPCODE_DISCARD;
128335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (nonzero)
128435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.testBoolean = VGPU10_INSTRUCTION_TEST_NONZERO;
128535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
128635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, opcode0.value);
128735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
128835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
128935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
129035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
129135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * We need to call this before we begin emitting a VGPU10 instruction.
129235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
129335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
129435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulbegin_emit_instruction(struct svga_shader_emitter_v10 *emit)
129535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
129635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->inst_start_token == 0);
129735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Save location of the instruction's VGPU10OpcodeToken0 token.
129835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Note, we can't save a pointer because it would become invalid if
129935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * we have to realloc the output buffer.
130035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
130135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->inst_start_token = emit_get_num_tokens(emit);
130235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
130335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
130435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
130535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
130635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * We need to call this after we emit the last token of a VGPU10 instruction.
130735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * This function patches in the opcode token's instructionLength field.
130835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
130935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
131035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulend_emit_instruction(struct svga_shader_emitter_v10 *emit)
131135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
131235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 *tokens = (VGPU10OpcodeToken0 *) emit->buf;
131335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned inst_length;
131435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
131535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->inst_start_token > 0);
131635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
131735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->discard_instruction) {
131835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Back up the emit->ptr to where this instruction started so
131935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * that we discard the current instruction.
132035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
132135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->ptr = (char *) (tokens + emit->inst_start_token);
132235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
132335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
132435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Compute instruction length and patch that into the start of
132535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * the instruction.
132635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
132735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      inst_length = emit_get_num_tokens(emit) - emit->inst_start_token;
132835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
132935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(inst_length > 0);
133035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
133135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tokens[emit->inst_start_token].instructionLength = inst_length;
133235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
133335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
133435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->inst_start_token = 0; /* reset to zero for error checking */
133535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->discard_instruction = FALSE;
133635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
133735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
133835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
133935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
134035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Return index for a free temporary register.
134135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
134235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
134335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulget_temp_index(struct svga_shader_emitter_v10 *emit)
134435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
134535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->internal_temp_count < MAX_INTERNAL_TEMPS);
134635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return emit->num_shader_temps + emit->internal_temp_count++;
134735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
134835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
134935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
135035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
135135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Release the temporaries which were generated by get_temp_index().
135235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
135335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
135435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulfree_temp_indexes(struct svga_shader_emitter_v10 *emit)
135535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
135635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->internal_temp_count = 0;
135735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
135835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
135935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
136035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
136135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create a tgsi_full_src_register.
136235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
136335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
136435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_src_reg(unsigned file, unsigned index)
136535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
136635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register reg;
136735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
136835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   memset(&reg, 0, sizeof(reg));
136935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.File = file;
137035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.Index = index;
137135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.SwizzleX = TGSI_SWIZZLE_X;
137235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.SwizzleY = TGSI_SWIZZLE_Y;
137335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.SwizzleZ = TGSI_SWIZZLE_Z;
137435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.SwizzleW = TGSI_SWIZZLE_W;
137535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return reg;
137635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
137735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
137835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
137935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
138035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create a tgsi_full_src_register for a temporary.
138135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
138235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
138335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_src_temp_reg(unsigned index)
138435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
138535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return make_src_reg(TGSI_FILE_TEMPORARY, index);
138635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
138735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
138835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
138935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
139035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create a tgsi_full_src_register for a constant.
139135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
139235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
139335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_src_const_reg(unsigned index)
139435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
139535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return make_src_reg(TGSI_FILE_CONSTANT, index);
139635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
139735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
139835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
139935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
140035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create a tgsi_full_src_register for an immediate constant.
140135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
140235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
140335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_src_immediate_reg(unsigned index)
140435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
140535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return make_src_reg(TGSI_FILE_IMMEDIATE, index);
140635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
140735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
140835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
140935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
141035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create a tgsi_full_dst_register.
141135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
141235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_dst_register
141335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_dst_reg(unsigned file, unsigned index)
141435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
141535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register reg;
141635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
141735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   memset(&reg, 0, sizeof(reg));
141835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.File = file;
141935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.Index = index;
142035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.WriteMask = TGSI_WRITEMASK_XYZW;
142135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return reg;
142235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
142335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
142435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
142535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
142635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create a tgsi_full_dst_register for a temporary.
142735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
142835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_dst_register
142935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_dst_temp_reg(unsigned index)
143035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
143135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return make_dst_reg(TGSI_FILE_TEMPORARY, index);
143235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
143335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
143435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
143535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
143635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create a tgsi_full_dst_register for an output.
143735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
143835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_dst_register
143935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_dst_output_reg(unsigned index)
144035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
144135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return make_dst_reg(TGSI_FILE_OUTPUT, index);
144235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
144335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
144435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
144535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
144635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create negated tgsi_full_src_register.
144735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
144835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
144935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulnegate_src(const struct tgsi_full_src_register *reg)
145035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
145135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register neg = *reg;
145235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   neg.Register.Negate = !reg->Register.Negate;
145335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return neg;
145435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
145535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
145635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
145735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create absolute value of a tgsi_full_src_register.
145835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
145935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
146035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulabsolute_src(const struct tgsi_full_src_register *reg)
146135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
146235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register absolute = *reg;
146335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   absolute.Register.Absolute = 1;
146435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return absolute;
146535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
146635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
146735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
146835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/** Return the named swizzle term from the src register */
1469e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulstatic inline unsigned
147035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulget_swizzle(const struct tgsi_full_src_register *reg, unsigned term)
147135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
147235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (term) {
147335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_SWIZZLE_X:
147435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return reg->Register.SwizzleX;
147535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_SWIZZLE_Y:
147635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return reg->Register.SwizzleY;
147735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_SWIZZLE_Z:
147835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return reg->Register.SwizzleZ;
147935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_SWIZZLE_W:
148035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return reg->Register.SwizzleW;
148135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
148235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"Bad swizzle");
148335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TGSI_SWIZZLE_X;
148435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
148535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
148635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
148735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
148835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
148935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create swizzled tgsi_full_src_register.
149035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
149135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
149235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulswizzle_src(const struct tgsi_full_src_register *reg,
149335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            unsigned swizzleX, unsigned swizzleY,
149435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            unsigned swizzleZ, unsigned swizzleW)
149535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
149635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register swizzled = *reg;
149735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Note: we swizzle the current swizzle */
149835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swizzled.Register.SwizzleX = get_swizzle(reg, swizzleX);
149935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swizzled.Register.SwizzleY = get_swizzle(reg, swizzleY);
150035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swizzled.Register.SwizzleZ = get_swizzle(reg, swizzleZ);
150135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swizzled.Register.SwizzleW = get_swizzle(reg, swizzleW);
150235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return swizzled;
150335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
150435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
150535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
150635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
150735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create swizzled tgsi_full_src_register where all the swizzle
150835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * terms are the same.
150935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
151035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
151135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulscalar_src(const struct tgsi_full_src_register *reg, unsigned swizzle)
151235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
151335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register swizzled = *reg;
151435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Note: we swizzle the current swizzle */
151535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swizzled.Register.SwizzleX =
151635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swizzled.Register.SwizzleY =
151735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swizzled.Register.SwizzleZ =
151835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swizzled.Register.SwizzleW = get_swizzle(reg, swizzle);
151935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return swizzled;
152035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
152135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
152235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
152335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
152435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Create new tgsi_full_dst_register with writemask.
152535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param mask  bitmask of TGSI_WRITEMASK_[XYZW]
152635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
152735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_dst_register
152835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulwritemask_dst(const struct tgsi_full_dst_register *reg, unsigned mask)
152935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
153035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register masked = *reg;
153135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   masked.Register.WriteMask = mask;
153235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return masked;
153335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
153435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
153535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
153635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
153735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Check if the register's swizzle is XXXX, YYYY, ZZZZ, or WWWW.
153835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
153935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
154035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulsame_swizzle_terms(const struct tgsi_full_src_register *reg)
154135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
154235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return (reg->Register.SwizzleX == reg->Register.SwizzleY &&
154335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul           reg->Register.SwizzleY == reg->Register.SwizzleZ &&
154435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul           reg->Register.SwizzleZ == reg->Register.SwizzleW);
154535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
154635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
154735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
154835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
154935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Search the vector for the value 'x' and return its position.
155035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
155135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic int
155235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulfind_imm_in_vec4(const union tgsi_immediate_data vec[4],
155335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                 union tgsi_immediate_data x)
155435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
155535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
155635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < 4; i++) {
155735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (vec[i].Int == x.Int)
155835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         return i;
155935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
156035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return -1;
156135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
156235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
156335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
156435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
156535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Helper used by make_immediate_reg(), make_immediate_reg_4().
156635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
156735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic int
156835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulfind_immediate(struct svga_shader_emitter_v10 *emit,
156935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               union tgsi_immediate_data x, unsigned startIndex)
157035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
157135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned endIndex = emit->num_immediates;
157235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
157335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
157435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->immediates_emitted);
157535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
157635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Search immediates for x, y, z, w */
157735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = startIndex; i < endIndex; i++) {
157835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (x.Int == emit->immediates[i][0].Int ||
157935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          x.Int == emit->immediates[i][1].Int ||
158035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          x.Int == emit->immediates[i][2].Int ||
158135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          x.Int == emit->immediates[i][3].Int) {
158235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         return i;
158335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
158435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
158535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Should never try to use an immediate value that wasn't pre-declared */
158635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(!"find_immediate() failed!");
158735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return -1;
158835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
158935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
159035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
159135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
159235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Return a tgsi_full_src_register for an immediate/literal
159335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * union tgsi_immediate_data[4] value.
159435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Note: the values must have been previously declared/allocated in
159535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * emit_pre_helpers().  And, all of x,y,z,w must be located in the same
159635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * vec4 immediate.
159735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
159835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
159935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_immediate_reg_4(struct svga_shader_emitter_v10 *emit,
160035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const union tgsi_immediate_data imm[4])
160135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
160235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register reg;
160335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
160435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
160535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < emit->num_common_immediates; i++) {
160635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* search for first component value */
160735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      int immpos = find_immediate(emit, imm[0], i);
160835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      int x, y, z, w;
160935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
161035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(immpos >= 0);
161135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
161235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* find remaining components within the immediate vector */
161335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      x = find_imm_in_vec4(emit->immediates[immpos], imm[0]);
161435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      y = find_imm_in_vec4(emit->immediates[immpos], imm[1]);
161535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      z = find_imm_in_vec4(emit->immediates[immpos], imm[2]);
161635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      w = find_imm_in_vec4(emit->immediates[immpos], imm[3]);
161735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
161835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (x >=0 &&  y >= 0 && z >= 0 && w >= 0) {
161935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* found them all */
162035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         memset(&reg, 0, sizeof(reg));
162135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         reg.Register.File = TGSI_FILE_IMMEDIATE;
162235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         reg.Register.Index = immpos;
162335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         reg.Register.SwizzleX = x;
162435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         reg.Register.SwizzleY = y;
162535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         reg.Register.SwizzleZ = z;
162635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         reg.Register.SwizzleW = w;
162735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         return reg;
162835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
162935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* else, keep searching */
163035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
163135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
163235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(!"Failed to find immediate register!");
163335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
163435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Just return IMM[0].xxxx */
163535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   memset(&reg, 0, sizeof(reg));
163635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.File = TGSI_FILE_IMMEDIATE;
163735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return reg;
163835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
163935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
164035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
164135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
164235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Return a tgsi_full_src_register for an immediate/literal
164335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * union tgsi_immediate_data value of the form {value, value, value, value}.
164435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \sa make_immediate_reg_4() regarding allowed values.
164535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
164635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
164735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_immediate_reg(struct svga_shader_emitter_v10 *emit,
164835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   union tgsi_immediate_data value)
164935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
165035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register reg;
165135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   int immpos = find_immediate(emit, value, 0);
165235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
165335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(immpos >= 0);
165435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
165535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   memset(&reg, 0, sizeof(reg));
165635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.File = TGSI_FILE_IMMEDIATE;
165735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.Index = immpos;
165835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.SwizzleX =
165935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.SwizzleY =
166035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.SwizzleZ =
166135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg.Register.SwizzleW = find_imm_in_vec4(emit->immediates[immpos], value);
166235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
166335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return reg;
166435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
166535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
166635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
166735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
166835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Return a tgsi_full_src_register for an immediate/literal float[4] value.
166935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \sa make_immediate_reg_4() regarding allowed values.
167035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
167135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
167235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_immediate_reg_float4(struct svga_shader_emitter_v10 *emit,
167335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                          float x, float y, float z, float w)
167435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
167535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   union tgsi_immediate_data imm[4];
167635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[0].Float = x;
167735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[1].Float = y;
167835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[2].Float = z;
167935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[3].Float = w;
168035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return make_immediate_reg_4(emit, imm);
168135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
168235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
168335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
168435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
168535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Return a tgsi_full_src_register for an immediate/literal float value
168635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * of the form {value, value, value, value}.
168735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \sa make_immediate_reg_4() regarding allowed values.
168835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
168935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
169035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_immediate_reg_float(struct svga_shader_emitter_v10 *emit, float value)
169135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
169235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   union tgsi_immediate_data imm;
169335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm.Float = value;
169435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return make_immediate_reg(emit, imm);
169535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
169635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
169735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
169835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
169935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Return a tgsi_full_src_register for an immediate/literal int[4] vector.
170035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
170135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
170235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_immediate_reg_int4(struct svga_shader_emitter_v10 *emit,
170335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        int x, int y, int z, int w)
170435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
170535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   union tgsi_immediate_data imm[4];
170635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[0].Int = x;
170735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[1].Int = y;
170835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[2].Int = z;
170935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[3].Int = w;
171035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return make_immediate_reg_4(emit, imm);
171135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
171235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
171335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
171435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
171535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Return a tgsi_full_src_register for an immediate/literal int value
171635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * of the form {value, value, value, value}.
171735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \sa make_immediate_reg_4() regarding allowed values.
171835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
171935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
172035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulmake_immediate_reg_int(struct svga_shader_emitter_v10 *emit, int value)
172135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
172235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   union tgsi_immediate_data imm;
172335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm.Int = value;
172435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return make_immediate_reg(emit, imm);
172535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
172635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
172735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
172835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
172935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Allocate space for a union tgsi_immediate_data[4] immediate.
173035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \return  the index/position of the immediate.
173135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
173235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
173335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulalloc_immediate_4(struct svga_shader_emitter_v10 *emit,
173435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  const union tgsi_immediate_data imm[4])
173535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
173635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned n = emit->num_immediates++;
173735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(!emit->immediates_emitted);
1738e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul   assert(n < ARRAY_SIZE(emit->immediates));
173935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->immediates[n][0] = imm[0];
174035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->immediates[n][1] = imm[1];
174135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->immediates[n][2] = imm[2];
174235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->immediates[n][3] = imm[3];
174335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return n;
174435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
174535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
174635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
174735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
174835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Allocate space for a float[4] immediate.
174935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \return  the index/position of the immediate.
175035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
175135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
175235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulalloc_immediate_float4(struct svga_shader_emitter_v10 *emit,
175335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       float x, float y, float z, float w)
175435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
175535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   union tgsi_immediate_data imm[4];
175635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[0].Float = x;
175735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[1].Float = y;
175835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[2].Float = z;
175935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[3].Float = w;
176035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return alloc_immediate_4(emit, imm);
176135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
176235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
176335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
176435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
176560a27ad122128145d28be37e9c0b0bc86a8e5181Giuseppe Bilotta * Allocate space for an int[4] immediate.
176635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \return  the index/position of the immediate.
176735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
176835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
176935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulalloc_immediate_int4(struct svga_shader_emitter_v10 *emit,
177035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       int x, int y, int z, int w)
177135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
177235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   union tgsi_immediate_data imm[4];
177335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[0].Int = x;
177435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[1].Int = y;
177535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[2].Int = z;
177635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   imm[3].Int = w;
177735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return alloc_immediate_4(emit, imm);
177835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
177935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
178035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
178135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
178235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Allocate a shader input to store a system value.
178335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
178435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
178535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulalloc_system_value_index(struct svga_shader_emitter_v10 *emit, unsigned index)
178635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
17872f3d06d9f95982b1dd9733260562e9b6484fc661Brian Paul   const unsigned n = emit->info.file_max[TGSI_FILE_INPUT] + 1 + index;
1788e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul   assert(index < ARRAY_SIZE(emit->system_value_indexes));
178935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->system_value_indexes[index] = n;
179035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return n;
179135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
179235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
179335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
179435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
179535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate a TGSI immediate value (union tgsi_immediate_data[4]) to VGPU10.
179635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
179735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
179835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vgpu10_immediate(struct svga_shader_emitter_v10 *emit,
179935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      const struct tgsi_full_immediate *imm)
180035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
180135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* We don't actually emit any code here.  We just save the
180235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * immediate values and emit them later.
180335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
180435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   alloc_immediate_4(emit, imm->u);
180535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
180635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
180735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
180835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
180935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
181035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit a VGPU10_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER block
181135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * containing all the immediate values previously allocated
181235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * with alloc_immediate_4().
181335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
181435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
181535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vgpu10_immediates_block(struct svga_shader_emitter_v10 *emit)
181635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
181735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 token;
181835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
181935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(!emit->immediates_emitted);
182035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
182135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token.value = 0;
182235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token.opcodeType = VGPU10_OPCODE_CUSTOMDATA;
182335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   token.customDataClass = VGPU10_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER;
182435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
182535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Note: no begin/end_emit_instruction() calls */
182635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, token.value);
182735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, 2 + 4 * emit->num_immediates);
182835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dwords(emit, (unsigned *) emit->immediates, 4 * emit->num_immediates);
182935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
183035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->immediates_emitted = TRUE;
183135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
183235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
183335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
183435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
183535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
183635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
183735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate a fragment shader's TGSI_INTERPOLATE_x mode to a vgpu10
183835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * interpolation mode.
183935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \return a VGPU10_INTERPOLATION_x value
184035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
184135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
184235bb29d4994efadd1719a147731afa34e78a0be1Brian Paultranslate_interpolation(const struct svga_shader_emitter_v10 *emit,
184335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        unsigned interp, unsigned interpolate_loc)
184435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
184535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (interp == TGSI_INTERPOLATE_COLOR) {
184635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      interp = emit->key.fs.flatshade ?
184735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE;
184835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
184935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
185035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (interp) {
185135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_INTERPOLATE_CONSTANT:
185235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_INTERPOLATION_CONSTANT;
185335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_INTERPOLATE_LINEAR:
185435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return interpolate_loc == TGSI_INTERPOLATE_LOC_CENTROID ?
185535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID :
185635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE;
185735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_INTERPOLATE_PERSPECTIVE:
185835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return interpolate_loc == TGSI_INTERPOLATE_LOC_CENTROID ?
185935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             VGPU10_INTERPOLATION_LINEAR_CENTROID :
186035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             VGPU10_INTERPOLATION_LINEAR;
186135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
186235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"Unexpected interpolation mode");
186335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_INTERPOLATION_CONSTANT;
186435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
186535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
186635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
186735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
186835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
186935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate a TGSI property to VGPU10.
187035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Don't emit any instructions yet, only need to gather the primitive property information.
187135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * The output primitive topology might be changed later. The final property instructions
187235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * will be emitted as part of the pre-helper code.
187335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
187435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
187535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vgpu10_property(struct svga_shader_emitter_v10 *emit,
187635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_property *prop)
187735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
187835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   static const VGPU10_PRIMITIVE primType[] = {
187935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_POINT,           /* PIPE_PRIM_POINTS */
188035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_LINE,            /* PIPE_PRIM_LINES */
188135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_LINE,            /* PIPE_PRIM_LINE_LOOP */
188235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_LINE,            /* PIPE_PRIM_LINE_STRIP */
188335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TRIANGLE,        /* PIPE_PRIM_TRIANGLES */
188435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TRIANGLE,        /* PIPE_PRIM_TRIANGLE_STRIP */
188535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TRIANGLE,        /* PIPE_PRIM_TRIANGLE_FAN */
188635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_UNDEFINED,       /* PIPE_PRIM_QUADS */
188735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_UNDEFINED,       /* PIPE_PRIM_QUAD_STRIP */
188835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_UNDEFINED,       /* PIPE_PRIM_POLYGON */
188935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_LINE_ADJ,        /* PIPE_PRIM_LINES_ADJACENCY */
189035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_LINE_ADJ,        /* PIPE_PRIM_LINE_STRIP_ADJACENCY */
189135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TRIANGLE_ADJ,    /* PIPE_PRIM_TRIANGLES_ADJACENCY */
189235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TRIANGLE_ADJ     /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */
189335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   };
189435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
189535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   static const VGPU10_PRIMITIVE_TOPOLOGY primTopology[] = {
189635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_POINTLIST,     /* PIPE_PRIM_POINTS */
189735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_LINELIST,      /* PIPE_PRIM_LINES */
189835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_LINELIST,      /* PIPE_PRIM_LINE_LOOP */
189935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_LINESTRIP,     /* PIPE_PRIM_LINE_STRIP */
190035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLELIST,  /* PIPE_PRIM_TRIANGLES */
190135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* PIPE_PRIM_TRIANGLE_STRIP */
190235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* PIPE_PRIM_TRIANGLE_FAN */
190335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_UNDEFINED,     /* PIPE_PRIM_QUADS */
190435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_UNDEFINED,     /* PIPE_PRIM_QUAD_STRIP */
190535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_UNDEFINED,     /* PIPE_PRIM_POLYGON */
190635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,  /* PIPE_PRIM_LINES_ADJACENCY */
190735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,  /* PIPE_PRIM_LINE_STRIP_ADJACENCY */
190835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, /* PIPE_PRIM_TRIANGLES_ADJACENCY */
190935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */
191035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   };
191135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
191235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   static const unsigned inputArraySize[] = {
191335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      0,       /* VGPU10_PRIMITIVE_UNDEFINED */
191435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      1,       /* VGPU10_PRIMITIVE_POINT */
191535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      2,       /* VGPU10_PRIMITIVE_LINE */
191635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      3,       /* VGPU10_PRIMITIVE_TRIANGLE */
191735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      0,
191835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      0,
191935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      4,       /* VGPU10_PRIMITIVE_LINE_ADJ */
192035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      6        /* VGPU10_PRIMITIVE_TRIANGLE_ADJ */
192135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   };
192235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
192335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (prop->Property.PropertyName) {
192435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_PROPERTY_GS_INPUT_PRIM:
1925e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul      assert(prop->u[0].Data < ARRAY_SIZE(primType));
192635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->gs.prim_type = primType[prop->u[0].Data];
192735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(emit->gs.prim_type != VGPU10_PRIMITIVE_UNDEFINED);
192835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->gs.input_size = inputArraySize[emit->gs.prim_type];
192935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
193035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
193135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_PROPERTY_GS_OUTPUT_PRIM:
1932e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul      assert(prop->u[0].Data < ARRAY_SIZE(primTopology));
193335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->gs.prim_topology = primTopology[prop->u[0].Data];
193435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(emit->gs.prim_topology != VGPU10_PRIMITIVE_TOPOLOGY_UNDEFINED);
193535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
193635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
193735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES:
193835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->gs.max_out_vertices = prop->u[0].Data;
193935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
194035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
194135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
194235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
194335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
194435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
194535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
194635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
194735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
194835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
194935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
195035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_property_instruction(struct svga_shader_emitter_v10 *emit,
195135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                          VGPU10OpcodeToken0 opcode0, unsigned nData,
195235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                          unsigned data)
195335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
195435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
195535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, opcode0.value);
195635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (nData)
195735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, data);
195835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
195935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
196035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
196135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
196235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
196335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit property instructions
196435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
196535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
196635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_property_instructions(struct svga_shader_emitter_v10 *emit)
196735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
196835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 opcode0;
196935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
197035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_GEOMETRY);
197135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
197235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* emit input primitive type declaration */
197335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = 0;
197435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.opcodeType = VGPU10_OPCODE_DCL_GS_INPUT_PRIMITIVE;
197535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.primitive = emit->gs.prim_type;
197635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_property_instruction(emit, opcode0, 0, 0);
197735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
197835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* emit output primitive topology declaration */
197935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = 0;
198035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.opcodeType = VGPU10_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY;
198135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.primitiveTopology = emit->gs.prim_topology;
198235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_property_instruction(emit, opcode0, 0, 0);
198335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
198435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* emit max output vertices */
198535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = 0;
198635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.opcodeType = VGPU10_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT;
198735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_property_instruction(emit, opcode0, 1, emit->gs.max_out_vertices);
198835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
198935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
199035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
199135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
199235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit a vgpu10 declaration "instruction".
199335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param index  the register index
199435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param size   array size of the operand. In most cases, it is 1,
199535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *               but for inputs to geometry shader, the array size varies
199635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *               depending on the primitive type.
199735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
199835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
199935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_decl_instruction(struct svga_shader_emitter_v10 *emit,
200035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      VGPU10OpcodeToken0 opcode0,
200135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      VGPU10OperandToken0 operand0,
200235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      VGPU10NameToken name_token,
200335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      unsigned index, unsigned size)
200435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
200535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(opcode0.opcodeType);
200635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(operand0.mask);
200735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
200835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
200935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, opcode0.value);
201035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
201135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, operand0.value);
201235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
201335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (operand0.indexDimension == VGPU10_OPERAND_INDEX_1D) {
201435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Next token is the index of the register to declare */
201535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, index);
201635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
201735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (operand0.indexDimension >= VGPU10_OPERAND_INDEX_2D) {
201835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Next token is the size of the register */
201935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, size);
202035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
202135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Followed by the index of the register */
202235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, index);
202335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
202435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
202535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (name_token.value) {
202635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, name_token.value);
202735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
202835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
202935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
203035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
203135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
203235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
203335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
203435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the declaration for a shader input.
203535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param opcodeType  opcode type, one of VGPU10_OPCODE_DCL_INPUTx
203635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param operandType operand type, one of VGPU10_OPERAND_TYPE_INPUT_x
203735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param dim         index dimension
203835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param index       the input register index
203935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param size        array size of the operand. In most cases, it is 1,
204035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *                    but for inputs to geometry shader, the array size varies
204135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *                    depending on the primitive type.
204235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param name        one of VGPU10_NAME_x
204335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \parma numComp     number of components
204435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param selMode     component selection mode
204535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param usageMask   bitfield of VGPU10_OPERAND_4_COMPONENT_MASK_x values
204635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param interpMode  interpolation mode
204735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
204835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
204935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_input_declaration(struct svga_shader_emitter_v10 *emit,
205035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       unsigned opcodeType, unsigned operandType,
205135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       unsigned dim, unsigned index, unsigned size,
205235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       unsigned name, unsigned numComp,
205335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       unsigned selMode, unsigned usageMask,
205435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       unsigned interpMode)
205535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
205635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 opcode0;
205735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
205835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10NameToken name_token;
205935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
206035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(usageMask <= VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
206135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(opcodeType == VGPU10_OPCODE_DCL_INPUT ||
206235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          opcodeType == VGPU10_OPCODE_DCL_INPUT_SIV ||
206335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          opcodeType == VGPU10_OPCODE_DCL_INPUT_PS ||
206435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          opcodeType == VGPU10_OPCODE_DCL_INPUT_PS_SGV);
206535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(operandType == VGPU10_OPERAND_TYPE_INPUT ||
206635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          operandType == VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID);
206735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(numComp <= VGPU10_OPERAND_4_COMPONENT);
206835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(selMode <= VGPU10_OPERAND_4_COMPONENT_MASK_MODE);
206935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(dim <= VGPU10_OPERAND_INDEX_3D);
207035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(name == VGPU10_NAME_UNDEFINED ||
207135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          name == VGPU10_NAME_POSITION ||
207235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          name == VGPU10_NAME_INSTANCE_ID ||
207335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          name == VGPU10_NAME_VERTEX_ID ||
207435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          name == VGPU10_NAME_PRIMITIVE_ID ||
207535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          name == VGPU10_NAME_IS_FRONT_FACE);
207635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(interpMode == VGPU10_INTERPOLATION_UNDEFINED ||
207735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          interpMode == VGPU10_INTERPOLATION_CONSTANT ||
207835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          interpMode == VGPU10_INTERPOLATION_LINEAR ||
207935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          interpMode == VGPU10_INTERPOLATION_LINEAR_CENTROID ||
208035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          interpMode == VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE ||
208135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          interpMode == VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID);
208235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
208335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   check_register_index(emit, opcodeType, index);
208435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
208535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = operand0.value = name_token.value = 0;
208635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
208735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.opcodeType = opcodeType;
208835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.interpolationMode = interpMode;
208935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
209035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.operandType = operandType;
209135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.numComponents = numComp;
209235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.selectionMode = selMode;
209335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.mask = usageMask;
209435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.indexDimension = dim;
209535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
209635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (dim == VGPU10_OPERAND_INDEX_2D)
209735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.index1Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
209835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
209935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   name_token.name = name;
210035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
210135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_decl_instruction(emit, opcode0, operand0, name_token, index, size);
210235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
210335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
210435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
210535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
210635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the declaration for a shader output.
210735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param type  one of VGPU10_OPCODE_DCL_OUTPUTx
210835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param index  the output register index
210935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param name  one of VGPU10_NAME_x
211035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param usageMask  bitfield of VGPU10_OPERAND_4_COMPONENT_MASK_x values
211135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
211235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
211335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_output_declaration(struct svga_shader_emitter_v10 *emit,
211435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        unsigned type, unsigned index,
211535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        unsigned name, unsigned usageMask)
211635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
211735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 opcode0;
211835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
211935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10NameToken name_token;
212035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
212135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(usageMask <= VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
212235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(type == VGPU10_OPCODE_DCL_OUTPUT ||
212335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          type == VGPU10_OPCODE_DCL_OUTPUT_SGV ||
212435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          type == VGPU10_OPCODE_DCL_OUTPUT_SIV);
212535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(name == VGPU10_NAME_UNDEFINED ||
212635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          name == VGPU10_NAME_POSITION ||
212735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          name == VGPU10_NAME_PRIMITIVE_ID ||
212835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          name == VGPU10_NAME_RENDER_TARGET_ARRAY_INDEX ||
212935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          name == VGPU10_NAME_CLIP_DISTANCE);
213035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
213135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   check_register_index(emit, type, index);
213235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
213335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = operand0.value = name_token.value = 0;
213435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
213535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.opcodeType = type;
213635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.operandType = VGPU10_OPERAND_TYPE_OUTPUT;
213735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
213835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_MASK_MODE;
213935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.mask = usageMask;
214035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
214135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
214235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
214335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   name_token.name = name;
214435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
214535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_decl_instruction(emit, opcode0, operand0, name_token, index, 1);
214635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
214735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
214835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
214935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
215035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the declaration for the fragment depth output.
215135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
215235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
215335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_fragdepth_output_declaration(struct svga_shader_emitter_v10 *emit)
215435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
215535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 opcode0;
215635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
215735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10NameToken name_token;
215835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
215935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_FRAGMENT);
216035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
216135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = operand0.value = name_token.value = 0;
216235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
216335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.opcodeType = VGPU10_OPCODE_DCL_OUTPUT;
216435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.operandType = VGPU10_OPERAND_TYPE_OUTPUT_DEPTH;
216535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.numComponents = VGPU10_OPERAND_1_COMPONENT;
216635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.indexDimension = VGPU10_OPERAND_INDEX_0D;
216735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.mask = VGPU10_OPERAND_4_COMPONENT_MASK_ALL;
216835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
216935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_decl_instruction(emit, opcode0, operand0, name_token, 0, 1);
217035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
217135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
217235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
217335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
217435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the declaration for a system value input/output.
217535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
217635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
217735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_system_value_declaration(struct svga_shader_emitter_v10 *emit,
217835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              unsigned semantic_name, unsigned index)
217935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
218035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (semantic_name) {
218135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_SEMANTIC_INSTANCEID:
218235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      index = alloc_system_value_index(emit, index);
218335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT_SIV,
218435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_TYPE_INPUT,
218535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_INDEX_1D,
218635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             index, 1,
218735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_NAME_INSTANCE_ID,
218835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_4_COMPONENT,
218935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
219035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_4_COMPONENT_MASK_X,
219135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_INTERPOLATION_UNDEFINED);
219235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
219335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_SEMANTIC_VERTEXID:
219435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      index = alloc_system_value_index(emit, index);
219535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT_SIV,
219635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_TYPE_INPUT,
219735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_INDEX_1D,
219835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             index, 1,
219935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_NAME_VERTEX_ID,
220035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_4_COMPONENT,
220135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
220235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_OPERAND_4_COMPONENT_MASK_X,
220335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             VGPU10_INTERPOLATION_UNDEFINED);
220435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
220535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
220635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      ; /* XXX */
220735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
220835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
220935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
221035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
221135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate a TGSI declaration to VGPU10.
221235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
221335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
221435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vgpu10_declaration(struct svga_shader_emitter_v10 *emit,
221535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        const struct tgsi_full_declaration *decl)
221635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
221735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (decl->Declaration.File) {
221835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_INPUT:
221935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* do nothing - see emit_input_declarations() */
222035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
222135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
222235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_OUTPUT:
222335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(decl->Range.First == decl->Range.Last);
222435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->output_usage_mask[decl->Range.First] = decl->Declaration.UsageMask;
222535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
222635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
222735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_TEMPORARY:
222835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Don't declare the temps here.  Just keep track of how many
222935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * and emit the declaration later.
223035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
223135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (decl->Declaration.Array) {
223235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* Indexed temporary array.  Save the start index of the array
223335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * and the size of the array.
223435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          */
223535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const unsigned arrayID = MIN2(decl->Array.ArrayID, MAX_TEMP_ARRAYS);
223635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned i;
223735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
223835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         assert(arrayID < ARRAY_SIZE(emit->temp_arrays));
223935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
224035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* Save this array so we can emit the declaration for it later */
224135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->temp_arrays[arrayID].start = decl->Range.First;
224235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->temp_arrays[arrayID].size =
224335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            decl->Range.Last - decl->Range.First + 1;
224435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
224535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->num_temp_arrays = MAX2(emit->num_temp_arrays, arrayID + 1);
224635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         assert(emit->num_temp_arrays <= MAX_TEMP_ARRAYS);
224735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->num_temp_arrays = MIN2(emit->num_temp_arrays, MAX_TEMP_ARRAYS);
224835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
224935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* Fill in the temp_map entries for this array */
225035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         for (i = decl->Range.First; i <= decl->Range.Last; i++) {
225135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->temp_map[i].arrayId = arrayID;
225235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->temp_map[i].index = i - decl->Range.First;
225335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
225435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
225535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
225635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* for all temps, indexed or not, keep track of highest index */
225735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->num_shader_temps = MAX2(emit->num_shader_temps,
225835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                    decl->Range.Last + 1);
225935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
226035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
226135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_CONSTANT:
226235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Don't declare constants here.  Just keep track and emit later. */
226335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      {
226435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned constbuf = 0, num_consts;
226535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (decl->Declaration.Dimension) {
226635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            constbuf = decl->Dim.Index2D;
226735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
226835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* We throw an assertion here when, in fact, the shader should never
226935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * have linked due to constbuf index out of bounds, so we shouldn't
227035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * have reached here.
227135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          */
2272e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul         assert(constbuf < ARRAY_SIZE(emit->num_shader_consts));
227335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
227435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         num_consts = MAX2(emit->num_shader_consts[constbuf],
227535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           decl->Range.Last + 1);
227635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
227735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (num_consts > VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT) {
227835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            debug_printf("Warning: constant buffer is declared to size [%u]"
227935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                         " but [%u] is the limit.\n",
228035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                         num_consts,
228135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                         VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT);
228235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
228335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* The linker doesn't enforce the max UBO size so we clamp here */
228435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->num_shader_consts[constbuf] =
228535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            MIN2(num_consts, VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT);
228635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
228735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
228835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
228935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_IMMEDIATE:
229035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"TGSI_FILE_IMMEDIATE not handled yet!");
229135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
229235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
229335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_SYSTEM_VALUE:
229435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_system_value_declaration(emit, decl->Semantic.Name,
229535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                    decl->Range.First);
229635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
229735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
229835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_SAMPLER:
229935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Don't declare samplers here.  Just keep track and emit later. */
230035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->num_samplers = MAX2(emit->num_samplers, decl->Range.Last + 1);
230135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
230235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
23038cc9a8aa2a97ca9e7a36a993954a3480d44c13d3Ilia Mirkin#if 0
230435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_RESOURCE:
230535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /*opcode0.opcodeType = VGPU10_OPCODE_DCL_RESOURCE;*/
230635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* XXX more, VGPU10_RETURN_TYPE_FLOAT */
230735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"TGSI_FILE_RESOURCE not handled yet");
230835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
23098cc9a8aa2a97ca9e7a36a993954a3480d44c13d3Ilia Mirkin#endif
231035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
231135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_ADDRESS:
231235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->num_address_regs = MAX2(emit->num_address_regs,
231335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                    decl->Range.Last + 1);
231435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
231535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
231635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_FILE_SAMPLER_VIEW:
2317dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      {
2318dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         unsigned unit = decl->Range.First;
2319dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         assert(decl->Range.First == decl->Range.Last);
2320dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         emit->sampler_target[unit] = decl->SamplerView.Resource;
2321dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         /* Note: we can ignore YZW return types for now */
2322dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         emit->sampler_return_type[unit] = decl->SamplerView.ReturnTypeX;
2323dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      }
232435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
232535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
232635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
232735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"Unexpected type of declaration");
232835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
232935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
233035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
233135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
233235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
233335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
233435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
233535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit all input declarations.
233635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
233735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
233835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_input_declarations(struct svga_shader_emitter_v10 *emit)
233935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
234035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
234135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
234235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->unit == PIPE_SHADER_FRAGMENT) {
234335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
234435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      for (i = 0; i < emit->linkage.num_inputs; i++) {
234535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned semantic_name = emit->info.input_semantic_name[i];
234635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned usage_mask = emit->info.input_usage_mask[i];
234735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned index = emit->linkage.input_map[i];
234835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned type, interpolationMode, name;
234935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
235035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (usage_mask == 0)
235135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            continue;  /* register is not actually used */
235235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
235335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (semantic_name == TGSI_SEMANTIC_POSITION) {
235435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* fragment position input */
235535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_INPUT_PS_SGV;
235635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            interpolationMode = VGPU10_INTERPOLATION_LINEAR;
235735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_POSITION;
235835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            if (usage_mask & TGSI_WRITEMASK_W) {
235935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               /* we need to replace use of 'w' with '1/w' */
236035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               emit->fs.fragcoord_input_index = i;
236135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            }
236235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
236335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (semantic_name == TGSI_SEMANTIC_FACE) {
236435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* fragment front-facing input */
236535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_INPUT_PS_SGV;
236635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            interpolationMode = VGPU10_INTERPOLATION_CONSTANT;
236735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_IS_FRONT_FACE;
236835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->fs.face_input_index = i;
236935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
237035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (semantic_name == TGSI_SEMANTIC_PRIMID) {
237135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* primitive ID */
237235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_INPUT_PS_SGV;
237335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            interpolationMode = VGPU10_INTERPOLATION_CONSTANT;
237435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_PRIMITIVE_ID;
237535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
237635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else {
237735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* general fragment input */
237835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_INPUT_PS;
237935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            interpolationMode =
238035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               translate_interpolation(emit,
238135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                       emit->info.input_interpolate[i],
238235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                       emit->info.input_interpolate_loc[i]);
238335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
238435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* keeps track if flat interpolation mode is being used */
238535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->uses_flat_interp = emit->uses_flat_interp ||
238635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               (interpolationMode == VGPU10_INTERPOLATION_CONSTANT);
238735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
238835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_UNDEFINED;
238935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
239035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
239135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_input_declaration(emit, type,
239235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_TYPE_INPUT,
239335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_INDEX_1D, index, 1,
239435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                name,
239535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_4_COMPONENT,
239635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
239735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
239835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                interpolationMode);
239935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
240035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
240135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (emit->unit == PIPE_SHADER_GEOMETRY) {
240235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
240335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      for (i = 0; i < emit->info.num_inputs; i++) {
240435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned semantic_name = emit->info.input_semantic_name[i];
240535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned usage_mask = emit->info.input_usage_mask[i];
240635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned index = emit->linkage.input_map[i];
240735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned opcodeType, operandType;
240835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned numComp, selMode;
240935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned name;
241035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned dim;
241135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
241235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (usage_mask == 0)
241335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            continue;  /* register is not actually used */
241435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
241535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         opcodeType = VGPU10_OPCODE_DCL_INPUT;
241635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         operandType = VGPU10_OPERAND_TYPE_INPUT;
241735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         numComp = VGPU10_OPERAND_4_COMPONENT;
241835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         selMode = VGPU10_OPERAND_4_COMPONENT_MASK_MODE;
241935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         name = VGPU10_NAME_UNDEFINED;
242035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
242135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* all geometry shader inputs are two dimensional except gl_PrimitiveID */
242235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         dim = VGPU10_OPERAND_INDEX_2D;
242335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
242435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (semantic_name == TGSI_SEMANTIC_PRIMID) {
242535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* Primitive ID */
242635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            operandType = VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID;
242735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            dim = VGPU10_OPERAND_INDEX_0D;
242835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            numComp = VGPU10_OPERAND_0_COMPONENT;
242935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            selMode = 0;
243035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
243135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* also save the register index so we can check for
243235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * primitive id when emit src register. We need to modify the
243335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             * operand type, index dimension when emit primitive id src reg.
243435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             */
243535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->gs.prim_id_index = i;
243635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
243735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (semantic_name == TGSI_SEMANTIC_POSITION) {
243835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* vertex position input */
243935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            opcodeType = VGPU10_OPCODE_DCL_INPUT_SIV;
244035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_POSITION;
244135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
244235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
244335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_input_declaration(emit, opcodeType, operandType,
244435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                dim, index,
244535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                emit->gs.input_size,
244635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                name,
244735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                numComp, selMode,
244835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
244935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_INTERPOLATION_UNDEFINED);
245035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
245135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
245235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
245335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(emit->unit == PIPE_SHADER_VERTEX);
245435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
24552f3d06d9f95982b1dd9733260562e9b6484fc661Brian Paul      for (i = 0; i < emit->info.file_max[TGSI_FILE_INPUT] + 1; i++) {
245635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned usage_mask = emit->info.input_usage_mask[i];
245735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned index = i;
245835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
245935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (usage_mask == 0)
246035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            continue;  /* register is not actually used */
246135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
246235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT,
246335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_TYPE_INPUT,
246435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_INDEX_1D, index, 1,
246535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_NAME_UNDEFINED,
246635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_4_COMPONENT,
246735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
246835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
246935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                VGPU10_INTERPOLATION_UNDEFINED);
247035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
247135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
247235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
247335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
247435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
247535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
247635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
247735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
247835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit all output declarations.
247935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
248035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
248135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_output_declarations(struct svga_shader_emitter_v10 *emit)
248235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
248335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
248435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
248535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < emit->info.num_outputs; i++) {
248635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /*const unsigned usage_mask = emit->info.output_usage_mask[i];*/
248735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      const unsigned semantic_name = emit->info.output_semantic_name[i];
248835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      const unsigned semantic_index = emit->info.output_semantic_index[i];
248935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned index = i;
249035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
249135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->unit == PIPE_SHADER_FRAGMENT) {
249235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (semantic_name == TGSI_SEMANTIC_COLOR) {
2493e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul            assert(semantic_index < ARRAY_SIZE(emit->fs.color_out_index));
249435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
249535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->fs.color_out_index[semantic_index] = index;
249635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
249735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* The semantic index is the shader's color output/buffer index */
249835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_output_declaration(emit,
249935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                    VGPU10_OPCODE_DCL_OUTPUT, semantic_index,
250035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                    VGPU10_NAME_UNDEFINED,
250135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                    VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
250235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
250335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            if (semantic_index == 0) {
250435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               if (emit->key.fs.write_color0_to_n_cbufs > 1) {
250535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  /* Emit declarations for the additional color outputs
250635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   * for broadcasting.
250735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   */
250835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  unsigned j;
250935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  for (j = 1; j < emit->key.fs.write_color0_to_n_cbufs; j++) {
251035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     /* Allocate a new output index */
251135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     unsigned idx = emit->info.num_outputs + j - 1;
251235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     emit->fs.color_out_index[j] = idx;
251335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     emit_output_declaration(emit,
251435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                        VGPU10_OPCODE_DCL_OUTPUT, idx,
251535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                        VGPU10_NAME_UNDEFINED,
251635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                        VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
251735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     emit->info.output_semantic_index[idx] = j;
251835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  }
251935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               }
252035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            }
252135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            else {
252235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               assert(!emit->key.fs.write_color0_to_n_cbufs);
252335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            }
252435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
252535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (semantic_name == TGSI_SEMANTIC_POSITION) {
252635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* Fragment depth output */
252735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_fragdepth_output_declaration(emit);
252835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
252935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else {
253035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            assert(!"Bad output semantic name");
253135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
253235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
253335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else {
253435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* VS or GS */
253535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned name, type;
253635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned writemask = VGPU10_OPERAND_4_COMPONENT_MASK_ALL;
253735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
253835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         switch (semantic_name) {
253935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_SEMANTIC_POSITION:
254035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            assert(emit->unit != PIPE_SHADER_FRAGMENT);
254135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_OUTPUT_SIV;
254235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_POSITION;
254335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* Save the index of the vertex position output register */
254435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->vposition.out_index = index;
254535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            break;
254635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_SEMANTIC_CLIPDIST:
254735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_OUTPUT_SIV;
254835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_CLIP_DISTANCE;
254935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* save the starting index of the clip distance output register */
255035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            if (semantic_index == 0)
255135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               emit->clip_dist_out_index = index;
255235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            writemask = emit->output_usage_mask[index];
255335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            writemask = apply_clip_plane_mask(emit, writemask, semantic_index);
255435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            if (writemask == 0x0) {
255535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               continue; /* discard this do-nothing declaration */
255635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            }
255735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            break;
255835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_SEMANTIC_PRIMID:
255935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            assert(emit->unit == PIPE_SHADER_GEOMETRY);
256035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_OUTPUT_SGV;
256135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_PRIMITIVE_ID;
256235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            break;
256335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_SEMANTIC_LAYER:
256435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            assert(emit->unit == PIPE_SHADER_GEOMETRY);
256535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_OUTPUT_SGV;
256635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_RENDER_TARGET_ARRAY_INDEX;
256735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            break;
256835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_SEMANTIC_CLIPVERTEX:
256935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_OUTPUT;
257035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_UNDEFINED;
257135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->clip_vertex_out_index = index;
257235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            break;
257335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         default:
257435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* generic output */
257535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            type = VGPU10_OPCODE_DCL_OUTPUT;
257635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            name = VGPU10_NAME_UNDEFINED;
257735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
257835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
257935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_output_declaration(emit, type, index, name, writemask);
258035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
258135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
258235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
258335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->vposition.so_index != INVALID_INDEX &&
258435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       emit->vposition.out_index != INVALID_INDEX) {
258535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
258635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(emit->unit != PIPE_SHADER_FRAGMENT);
258735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
258835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Emit the declaration for the non-adjusted vertex position
258935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * for stream output purpose
259035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
259135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT,
259235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              emit->vposition.so_index,
259335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              VGPU10_NAME_UNDEFINED,
259435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
259535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
259635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
259735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->clip_dist_so_index != INVALID_INDEX &&
259835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       emit->clip_dist_out_index != INVALID_INDEX) {
259935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
260035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(emit->unit != PIPE_SHADER_FRAGMENT);
260135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
260235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Emit the declaration for the clip distance shadow copy which
260335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * will be used for stream output purpose and for clip distance
260435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * varying variable
260535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
260635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT,
260735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              emit->clip_dist_so_index,
260835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              VGPU10_NAME_UNDEFINED,
260935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              emit->output_usage_mask[emit->clip_dist_out_index]);
261035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
261135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->info.num_written_clipdistance > 4) {
261235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* for the second clip distance register, each handles 4 planes */
261335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT,
261435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 emit->clip_dist_so_index + 1,
261535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 VGPU10_NAME_UNDEFINED,
261635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 emit->output_usage_mask[emit->clip_dist_out_index+1]);
261735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
261835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
261935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
262035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
262135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
262235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
262335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
262435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
262535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the declaration for the temporary registers.
262635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
262735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
262835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_temporaries_declaration(struct svga_shader_emitter_v10 *emit)
262935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
263035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned total_temps, reg, i;
263135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
263235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   total_temps = emit->num_shader_temps;
263335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
2634479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee   /* If there is indirect access to non-indexable temps in the shader,
2635479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee    * convert those temps to indexable temps. This works around a bug
2636479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee    * in the GLSL->TGSI translator exposed in piglit test
2637479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee    * glsl-1.20/execution/fs-const-array-of-struct-of-array.shader_test.
2638479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee    * Internal temps added by the driver remain as non-indexable temps.
2639479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee    */
2640479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee   if ((emit->info.indirect_files & (1 << TGSI_FILE_TEMPORARY)) &&
2641479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee       emit->num_temp_arrays == 0) {
2642479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee      unsigned arrayID;
2643479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee
2644479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee      arrayID = 1;
2645479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee      emit->num_temp_arrays = arrayID + 1;
2646479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee      emit->temp_arrays[arrayID].start = 0;
2647479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee      emit->temp_arrays[arrayID].size = total_temps;
2648479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee
2649479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee      /* Fill in the temp_map entries for this temp array */
2650479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee      for (i = 0; i < total_temps; i++) {
2651479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee         emit->temp_map[i].arrayId = arrayID;
2652479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee         emit->temp_map[i].index = i;
2653479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee      }
2654479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee   }
2655479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee
265635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Allocate extra temps for specially-implemented instructions,
265735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * such as LIT.
265835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
265935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   total_temps += MAX_INTERNAL_TEMPS;
266035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
266135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->unit == PIPE_SHADER_VERTEX || emit->unit == PIPE_SHADER_GEOMETRY) {
266235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->vposition.need_prescale || emit->key.vs.undo_viewport ||
266335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          emit->key.clip_plane_enable ||
266435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          emit->vposition.so_index != INVALID_INDEX) {
266535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->vposition.tmp_index = total_temps;
266635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         total_temps += 1;
266735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
266835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
266935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->unit == PIPE_SHADER_VERTEX) {
267035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned attrib_mask = (emit->key.vs.adjust_attrib_w_1 |
267135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 emit->key.vs.adjust_attrib_itof |
267235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 emit->key.vs.adjust_attrib_utof |
267335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 emit->key.vs.attrib_is_bgra |
267435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 emit->key.vs.attrib_puint_to_snorm |
267535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 emit->key.vs.attrib_puint_to_uscaled |
267635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 emit->key.vs.attrib_puint_to_sscaled);
267735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         while (attrib_mask) {
267835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            unsigned index = u_bit_scan(&attrib_mask);
267935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->vs.adjusted_input[index] = total_temps++;
268035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
268135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
268235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
268335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->clip_mode == CLIP_DISTANCE) {
268435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* We need to write the clip distance to a temporary register
268535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * first. Then it will be copied to the shadow copy for
268635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * the clip distance varying variable and stream output purpose.
268735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * It will also be copied to the actual CLIPDIST register
268835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * according to the enabled clip planes
268935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          */
269035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->clip_dist_tmp_index = total_temps++;
269135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (emit->info.num_written_clipdistance > 4)
269235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            total_temps++; /* second clip register */
269335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
269435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else if (emit->clip_mode == CLIP_VERTEX) {
269535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* We need to convert the TGSI CLIPVERTEX output to one or more
269635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * clip distances.  Allocate a temp reg for the clipvertex here.
269735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          */
269835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         assert(emit->info.writes_clipvertex > 0);
269935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->clip_vertex_tmp_index = total_temps;
270035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         total_temps++;
270135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
270235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
270335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (emit->unit == PIPE_SHADER_FRAGMENT) {
270435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->key.fs.alpha_func != SVGA3D_CMP_ALWAYS ||
2705d31481e70ab0da293d4c3010815f643f161b7168Brian Paul          emit->key.fs.white_fragments ||
270635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          emit->key.fs.write_color0_to_n_cbufs > 1) {
270735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* Allocate a temp to hold the output color */
270835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->fs.color_tmp_index = total_temps;
270935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         total_temps += 1;
271035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
271135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
271235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->fs.face_input_index != INVALID_INDEX) {
271335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* Allocate a temp for the +/-1 face register */
271435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->fs.face_tmp_index = total_temps;
271535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         total_temps += 1;
271635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
271735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
271835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->fs.fragcoord_input_index != INVALID_INDEX) {
271935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* Allocate a temp for modified fragment position register */
272035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->fs.fragcoord_tmp_index = total_temps;
272135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         total_temps += 1;
272235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
272335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
272435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
272535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < emit->num_address_regs; i++) {
272635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->address_reg_index[i] = total_temps++;
272735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
272835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
272935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Initialize the temp_map array which maps TGSI temp indexes to VGPU10
273035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * temp indexes.  Basically, we compact all the non-array temp register
273135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * indexes into a consecutive series.
273235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
273335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Before, we may have some TGSI declarations like:
273435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   DCL TEMP[0..1], LOCAL
273535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   DCL TEMP[2..4], ARRAY(1), LOCAL
273635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   DCL TEMP[5..7], ARRAY(2), LOCAL
273735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   plus, some extra temps, like TEMP[8], TEMP[9] for misc things
273835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
273935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * After, we'll have a map like this:
274035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[0] = { array 0, index 0 }
274135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[1] = { array 0, index 1 }
274235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[2] = { array 1, index 0 }
274335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[3] = { array 1, index 1 }
274435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[4] = { array 1, index 2 }
274535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[5] = { array 2, index 0 }
274635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[6] = { array 2, index 1 }
274735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[7] = { array 2, index 2 }
274835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[8] = { array 0, index 2 }
274935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   temp_map[9] = { array 0, index 3 }
275035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
275135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * We'll declare two arrays of 3 elements, plus a set of four non-indexed
275235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * temps numbered 0..3
275335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
275435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Any time we emit a temporary register index, we'll have to use the
275535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * temp_map[] table to convert the TGSI index to the VGPU10 index.
275635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
275735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Finally, we recompute the total_temps value here.
275835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
275935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   reg = 0;
276035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < total_temps; i++) {
276135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->temp_map[i].arrayId == 0) {
276235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->temp_map[i].index = reg++;
276335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
276435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
276535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
276635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (0) {
276735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("total_temps %u\n", total_temps);
2768479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee      for (i = 0; i < total_temps; i++) {
276935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         debug_printf("temp %u ->  array %u  index %u\n",
277035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      i, emit->temp_map[i].arrayId, emit->temp_map[i].index);
277135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
277235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
277335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
2774479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee   total_temps = reg;
2775479199180871432030d3eebc2822bd7cb3dc6fd6Charmaine Lee
277635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Emit declaration of ordinary temp registers */
277735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (total_temps > 0) {
277835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10OpcodeToken0 opcode0;
277935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
278035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.value = 0;
278135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_DCL_TEMPS;
278235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
278335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
278435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, opcode0.value);
278535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, total_temps);
278635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
278735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
278835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
278935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Emit declarations for indexable temp arrays.  Skip 0th entry since
279035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * it's unused.
279135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
279235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 1; i < emit->num_temp_arrays; i++) {
279335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned num_temps = emit->temp_arrays[i].size;
279435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
279535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (num_temps > 0) {
279635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         VGPU10OpcodeToken0 opcode0;
279735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
279835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         opcode0.value = 0;
279935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         opcode0.opcodeType = VGPU10_OPCODE_DCL_INDEXABLE_TEMP;
280035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
280135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         begin_emit_instruction(emit);
280235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, opcode0.value);
280335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, i); /* which array */
280435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, num_temps);
280535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, 4); /* num components */
280635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         end_emit_instruction(emit);
280735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
280835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         total_temps += num_temps;
280935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
281035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
281135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
281235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Check that the grand total of all regular and indexed temps is
281335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * under the limit.
281435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
281535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   check_register_index(emit, VGPU10_OPCODE_DCL_TEMPS, total_temps - 1);
281635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
281735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
281835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
281935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
282035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
282135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
282235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_constant_declaration(struct svga_shader_emitter_v10 *emit)
282335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
282435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 opcode0;
282535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand0;
282635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned total_consts, i;
282735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
282835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = 0;
282935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.opcodeType = VGPU10_OPCODE_DCL_CONSTANT_BUFFER;
283035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.accessPattern = VGPU10_CB_IMMEDIATE_INDEXED;
283135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* XXX or, access pattern = VGPU10_CB_DYNAMIC_INDEXED */
283235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
283335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.value = 0;
283435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
283535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.indexDimension = VGPU10_OPERAND_INDEX_2D;
283635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
283735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.index1Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
283835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.operandType = VGPU10_OPERAND_TYPE_CONSTANT_BUFFER;
283935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SWIZZLE_MODE;
284035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleX = 0;
284135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleY = 1;
284235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleZ = 2;
284335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand0.swizzleW = 3;
284435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
284535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /**
284635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Emit declaration for constant buffer [0].  We also allocate
284735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * room for the extra constants here.
284835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
284935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   total_consts = emit->num_shader_consts[0];
285035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
285135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Now, allocate constant slots for the "extra" constants */
285235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
285335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Vertex position scale/translation */
285435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->vposition.need_prescale) {
285535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->vposition.prescale_scale_index = total_consts++;
285635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->vposition.prescale_trans_index = total_consts++;
285735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
285835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
285935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->unit == PIPE_SHADER_VERTEX) {
286035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->key.vs.undo_viewport) {
286135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->vs.viewport_index = total_consts++;
286235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
286335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
286435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
286535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* user-defined clip planes */
286635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->key.clip_plane_enable) {
286735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned n = util_bitcount(emit->key.clip_plane_enable);
286835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(emit->unit == PIPE_SHADER_VERTEX ||
286935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             emit->unit == PIPE_SHADER_GEOMETRY);
287035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      for (i = 0; i < n; i++) {
287135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->clip_plane_const[i] = total_consts++;
287235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
287335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
287435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
287535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Texcoord scale factors for RECT textures */
287635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   {
287735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      for (i = 0; i < emit->num_samplers; i++) {
287835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (emit->key.tex[i].unnormalized) {
287935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->texcoord_scale_index[i] = total_consts++;
288035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
288135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
288235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
288335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
288435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Texture buffer sizes */
288535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < emit->num_samplers; i++) {
2886dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      if (emit->sampler_target[i] == TGSI_TEXTURE_BUFFER) {
288735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->texture_buffer_size_index[i] = total_consts++;
288835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
288935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
289035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
289135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (total_consts > 0) {
289235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
289335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, opcode0.value);
289435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, operand0.value);
289535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, 0);  /* which const buffer slot */
289635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, total_consts);
289735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
289835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
289935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
290035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Declare remaining constant buffers (UBOs) */
2901e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul   for (i = 1; i < ARRAY_SIZE(emit->num_shader_consts); i++) {
290235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->num_shader_consts[i] > 0) {
290335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         begin_emit_instruction(emit);
290435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, opcode0.value);
290535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, operand0.value);
290635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, i);  /* which const buffer slot */
290735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dword(emit, emit->num_shader_consts[i]);
290835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         end_emit_instruction(emit);
290935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
291035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
291135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
291235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
291335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
291435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
291535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
291635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
291735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit declarations for samplers.
291835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
291935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
292035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_sampler_declarations(struct svga_shader_emitter_v10 *emit)
292135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
292235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
292335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
292435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < emit->num_samplers; i++) {
292535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10OpcodeToken0 opcode0;
292635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10OperandToken0 operand0;
292735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
292835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.value = 0;
292935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_DCL_SAMPLER;
293035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.samplerMode = VGPU10_SAMPLER_MODE_DEFAULT;
293135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
293235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.value = 0;
293335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.numComponents = VGPU10_OPERAND_0_COMPONENT;
293435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.operandType = VGPU10_OPERAND_TYPE_SAMPLER;
293535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
293635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
293735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
293835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
293935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, opcode0.value);
294035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, operand0.value);
294135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, i);
294235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
294335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
294435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
294535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
294635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
294735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
294835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
294935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
2950dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul * Translate TGSI_TEXTURE_x to VGAPU10_RESOURCE_DIMENSION_x.
295135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
295235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic unsigned
2953dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paultgsi_texture_to_resource_dimension(unsigned target, boolean is_array)
295435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
295535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (target) {
2956dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_BUFFER:
295735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_RESOURCE_DIMENSION_BUFFER;
2958dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_1D:
295935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURE1D;
2960dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_2D:
2961dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_RECT:
2962dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
2963dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_3D:
296435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURE3D;
2965dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_CUBE:
2966dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURECUBE;
2967dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_SHADOW1D:
2968dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURE1D;
2969dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_SHADOW2D:
2970dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_SHADOWRECT:
2971dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
2972dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_1D_ARRAY:
2973dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_SHADOW1D_ARRAY:
2974dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      return is_array ? VGPU10_RESOURCE_DIMENSION_TEXTURE1DARRAY
2975dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         : VGPU10_RESOURCE_DIMENSION_TEXTURE1D;
2976dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_2D_ARRAY:
2977dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_SHADOW2D_ARRAY:
2978dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      return is_array ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DARRAY
2979dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         : VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
2980dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_SHADOWCUBE:
298135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURECUBE;
2982dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_2D_MSAA:
2983dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURE2DMS;
2984dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_2D_ARRAY_MSAA:
2985dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      return is_array ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DMSARRAY
2986dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         : VGPU10_RESOURCE_DIMENSION_TEXTURE2DMS;
2987dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   case TGSI_TEXTURE_CUBE_ARRAY:
298835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURECUBEARRAY;
298935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
299035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"Unexpected resource type");
299135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
299235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
299335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
299435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
299535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
299635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
299735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Given a tgsi_return_type, return true iff it is an integer type.
299835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
299935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
300035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulis_integer_type(enum tgsi_return_type type)
300135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
300235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (type) {
300335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_RETURN_TYPE_SINT:
300435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_RETURN_TYPE_UINT:
300535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         return TRUE;
300635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_RETURN_TYPE_FLOAT:
300735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_RETURN_TYPE_UNORM:
300835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_RETURN_TYPE_SNORM:
300935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         return FALSE;
301035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_RETURN_TYPE_COUNT:
301135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      default:
301235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         assert(!"is_integer_type: Unknown tgsi_return_type");
301335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         return FALSE;
301435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
301535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
301635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
301735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
301835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
301935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit declarations for resources.
302035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * XXX When we're sure that all TGSI shaders will be generated with
302135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * sampler view declarations (Ex: DCL SVIEW[n], 2D, UINT) we may
302235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * rework this code.
302335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
302435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
302535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_resource_declarations(struct svga_shader_emitter_v10 *emit)
302635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
302735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
302835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
302935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Emit resource decl for each sampler */
303035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < emit->num_samplers; i++) {
303135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10OpcodeToken0 opcode0;
303235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10OperandToken0 operand0;
303335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10ResourceReturnTypeToken return_type;
303435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      VGPU10_RESOURCE_RETURN_TYPE rt;
303535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
303635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.value = 0;
303735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_DCL_RESOURCE;
303835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.resourceDimension =
3039dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul         tgsi_texture_to_resource_dimension(emit->sampler_target[i],
3040dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul                                            emit->key.tex[i].is_array);
304135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.value = 0;
304235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.numComponents = VGPU10_OPERAND_0_COMPONENT;
304335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.operandType = VGPU10_OPERAND_TYPE_RESOURCE;
304435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
304535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
304635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
304735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#if 1
304835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* convert TGSI_RETURN_TYPE_x to VGPU10_RETURN_TYPE_x */
304935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      STATIC_ASSERT(VGPU10_RETURN_TYPE_UNORM == TGSI_RETURN_TYPE_UNORM + 1);
305035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      STATIC_ASSERT(VGPU10_RETURN_TYPE_SNORM == TGSI_RETURN_TYPE_SNORM + 1);
305135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      STATIC_ASSERT(VGPU10_RETURN_TYPE_SINT == TGSI_RETURN_TYPE_SINT + 1);
305235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      STATIC_ASSERT(VGPU10_RETURN_TYPE_UINT == TGSI_RETURN_TYPE_UINT + 1);
305335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      STATIC_ASSERT(VGPU10_RETURN_TYPE_FLOAT == TGSI_RETURN_TYPE_FLOAT + 1);
3054dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      assert(emit->sampler_return_type[i] <= TGSI_RETURN_TYPE_FLOAT);
3055dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      rt = emit->sampler_return_type[i] + 1;
305635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#else
3057dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      switch (emit->sampler_return_type[i]) {
305835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_RETURN_TYPE_UNORM: rt = VGPU10_RETURN_TYPE_UNORM; break;
305935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_RETURN_TYPE_SNORM: rt = VGPU10_RETURN_TYPE_SNORM; break;
306035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_RETURN_TYPE_SINT:  rt = VGPU10_RETURN_TYPE_SINT;  break;
306135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_RETURN_TYPE_UINT:  rt = VGPU10_RETURN_TYPE_UINT;  break;
306235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_RETURN_TYPE_FLOAT: rt = VGPU10_RETURN_TYPE_FLOAT; break;
306335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         case TGSI_RETURN_TYPE_COUNT:
306435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         default:
306535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            rt = VGPU10_RETURN_TYPE_FLOAT;
306635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            assert(!"emit_resource_declarations: Unknown tgsi_return_type");
306735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
306835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul#endif
306935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
307035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return_type.value = 0;
307135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return_type.component0 = rt;
307235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return_type.component1 = rt;
307335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return_type.component2 = rt;
307435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return_type.component3 = rt;
307535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
307635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
307735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, opcode0.value);
307835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, operand0.value);
307935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, i);
308035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, return_type.value);
308135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
308235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
308335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
308435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
308535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
308635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
308735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
308835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_instruction_op1(struct svga_shader_emitter_v10 *emit,
308935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     unsigned opcode,
309035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_dst_register *dst,
309135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_src_register *src,
309235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     boolean saturate)
309335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
309435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
309535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, opcode, saturate);
309635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, dst);
309735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, src);
309835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
309935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
310035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
310135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
310235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_instruction_op2(struct svga_shader_emitter_v10 *emit,
310335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     unsigned opcode,
310435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_dst_register *dst,
310535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_src_register *src1,
310635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_src_register *src2,
310735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     boolean saturate)
310835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
310935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
311035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, opcode, saturate);
311135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, dst);
311235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, src1);
311335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, src2);
311435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
311535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
311635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
311735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
311835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_instruction_op3(struct svga_shader_emitter_v10 *emit,
311935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     unsigned opcode,
312035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_dst_register *dst,
312135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_src_register *src1,
312235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_src_register *src2,
312335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_src_register *src3,
312435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     boolean saturate)
312535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
312635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
312735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, opcode, saturate);
312835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, dst);
312935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, src1);
313035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, src2);
313135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, src3);
313235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
313335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
313435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
313535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
313635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the actual clip distance instructions to be used for clipping
313735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * by copying the clip distance from the temporary registers to the
313835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * CLIPDIST registers written with the enabled planes mask.
313935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Also copy the clip distance from the temporary to the clip distance
314035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * shadow copy register which will be referenced by the input shader
314135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
314235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
314335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_clip_distance_instructions(struct svga_shader_emitter_v10 *emit)
314435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
314535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_clip_dist_src;
314635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register clip_dist_dst;
314735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
314835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
314935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned clip_plane_enable = emit->key.clip_plane_enable;
315035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned clip_dist_tmp_index = emit->clip_dist_tmp_index;
315118a631eb9056857a9ced477e7e3d1a435a906be2Brian Paul   int num_written_clipdist = emit->info.num_written_clipdistance;
315235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
315335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->clip_dist_out_index != INVALID_INDEX);
315435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->clip_dist_tmp_index != INVALID_INDEX);
315535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
315635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /**
315735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Temporary reset the temporary clip dist register index so
315835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * that the copy to the real clip dist register will not
315935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * attempt to copy to the temporary register again
316035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
316135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->clip_dist_tmp_index = INVALID_INDEX;
316235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
316318a631eb9056857a9ced477e7e3d1a435a906be2Brian Paul   for (i = 0; i < 2 && num_written_clipdist > 0; i++, num_written_clipdist-=4) {
316435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
316535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tmp_clip_dist_src = make_src_temp_reg(clip_dist_tmp_index + i);
316635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
316735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /**
316835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * copy to the shadow copy for use by varying variable and
316935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * stream output. All clip distances
317035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * will be written regardless of the enabled clipping planes.
317135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
317235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      clip_dist_dst = make_dst_reg(TGSI_FILE_OUTPUT,
317335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                   emit->clip_dist_so_index + i);
317435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
317535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV clip_dist_so, tmp_clip_dist */
317635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &clip_dist_dst,
317735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_clip_dist_src, FALSE);
317835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
317935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /**
318035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * copy those clip distances to enabled clipping planes
318135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * to CLIPDIST registers for clipping
318235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
318335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (clip_plane_enable & 0xf) {
318435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         clip_dist_dst = make_dst_reg(TGSI_FILE_OUTPUT,
318535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                      emit->clip_dist_out_index + i);
318635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         clip_dist_dst = writemask_dst(&clip_dist_dst, clip_plane_enable & 0xf);
318735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
318835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* MOV CLIPDIST, tmp_clip_dist */
318935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &clip_dist_dst,
319035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              &tmp_clip_dist_src, FALSE);
319135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
319235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* four clip planes per clip register */
319335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      clip_plane_enable >>= 4;
319435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
319535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /**
319635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * set the temporary clip dist register index back to the
319735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * temporary index for the next vertex
319835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
319935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->clip_dist_tmp_index = clip_dist_tmp_index;
320035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
320135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
320235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/* Declare clip distance output registers for user-defined clip planes
320335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * or the TGSI_CLIPVERTEX output.
320435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
320535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
320635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_clip_distance_declarations(struct svga_shader_emitter_v10 *emit)
320735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
320835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned num_clip_planes = util_bitcount(emit->key.clip_plane_enable);
320935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned index = emit->num_outputs;
321035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned plane_mask;
321135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
321235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_VERTEX ||
321335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          emit->unit == PIPE_SHADER_GEOMETRY);
321435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(num_clip_planes <= 8);
321535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
321635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->clip_mode != CLIP_LEGACY &&
321735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       emit->clip_mode != CLIP_VERTEX) {
321835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return;
321935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
322035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
322135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (num_clip_planes == 0)
322235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return;
322335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
322435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Declare one or two clip output registers.  The number of components
322535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * in the mask reflects the number of clip planes.  For example, if 5
322635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * clip planes are needed, we'll declare outputs similar to:
322735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dcl_output_siv o2.xyzw, clip_distance
322835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dcl_output_siv o3.x, clip_distance
322935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
323035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->clip_dist_out_index = index; /* save the starting clip dist reg index */
323135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
323235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   plane_mask = (1 << num_clip_planes) - 1;
323335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (plane_mask & 0xf) {
323435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned cmask = plane_mask & VGPU10_OPERAND_4_COMPONENT_MASK_ALL;
323535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT_SIV, index,
323635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              VGPU10_NAME_CLIP_DISTANCE, cmask);
323735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->num_outputs++;
323835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
323935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (plane_mask & 0xf0) {
324035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned cmask = (plane_mask >> 4) & VGPU10_OPERAND_4_COMPONENT_MASK_ALL;
324135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT_SIV, index + 1,
324235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              VGPU10_NAME_CLIP_DISTANCE, cmask);
324335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->num_outputs++;
324435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
324535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
324635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
324735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
324835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
324935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the instructions for writing to the clip distance registers
325035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * to handle legacy/automatic clip planes.
325135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * For each clip plane, the distance is the dot product of the vertex
325235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * position (found in TEMP[vpos_tmp_index]) and the clip plane coefficients.
325335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * This is not used when the shader has an explicit CLIPVERTEX or CLIPDISTANCE
325435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * output registers already declared.
325535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
325635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
325735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_clip_distance_from_vpos(struct svga_shader_emitter_v10 *emit,
325835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             unsigned vpos_tmp_index)
325935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
326035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i, num_clip_planes = util_bitcount(emit->key.clip_plane_enable);
326135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
326235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->clip_mode == CLIP_LEGACY);
326335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(num_clip_planes <= 8);
326435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
326535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_VERTEX ||
326635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          emit->unit == PIPE_SHADER_GEOMETRY);
326735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
326835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < num_clip_planes; i++) {
326935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst;
327035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register plane_src, vpos_src;
327135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned reg_index = emit->clip_dist_out_index + i / 4;
327235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned comp = i % 4;
327335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned writemask = VGPU10_OPERAND_4_COMPONENT_MASK_X << comp;
327435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
327535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* create dst, src regs */
327635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      dst = make_dst_reg(TGSI_FILE_OUTPUT, reg_index);
327735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      dst = writemask_dst(&dst, writemask);
327835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
327935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      plane_src = make_src_const_reg(emit->clip_plane_const[i]);
328035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      vpos_src = make_src_temp_reg(vpos_tmp_index);
328135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
328235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* DP4 clip_dist, plane, vpos */
328335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_DP4, &dst,
328435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &plane_src, &vpos_src, FALSE);
328535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
328635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
328735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
328835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
328935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
329035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the instructions for computing the clip distance results from
329135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * the clip vertex temporary.
329235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * For each clip plane, the distance is the dot product of the clip vertex
329335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * position (found in a temp reg) and the clip plane coefficients.
329435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
329535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
329635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_clip_vertex_instructions(struct svga_shader_emitter_v10 *emit)
329735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
329835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned num_clip = util_bitcount(emit->key.clip_plane_enable);
329935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
330035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register dst;
330135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register clipvert_src;
330235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned clip_vertex_tmp = emit->clip_vertex_tmp_index;
330335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
330435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_VERTEX ||
330535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          emit->unit == PIPE_SHADER_GEOMETRY);
330635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
330735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->clip_mode == CLIP_VERTEX);
330835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
330935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   clipvert_src = make_src_temp_reg(clip_vertex_tmp);
331035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
331135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < num_clip; i++) {
331235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register plane_src;
331335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned reg_index = emit->clip_dist_out_index + i / 4;
331435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned comp = i % 4;
331535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned writemask = VGPU10_OPERAND_4_COMPONENT_MASK_X << comp;
331635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
331735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* create dst, src regs */
331835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      dst = make_dst_reg(TGSI_FILE_OUTPUT, reg_index);
331935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      dst = writemask_dst(&dst, writemask);
332035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
332135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      plane_src = make_src_const_reg(emit->clip_plane_const[i]);
332235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
332335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* DP4 clip_dist, plane, vpos */
332435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_DP4, &dst,
332535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &plane_src, &clipvert_src, FALSE);
332635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
332735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
332835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* copy temporary clip vertex register to the clip vertex register */
332935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
333035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->clip_vertex_out_index != INVALID_INDEX);
333135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
333235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /**
333335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * temporary reset the temporary clip vertex register index so
333435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * that copy to the clip vertex register will not attempt
333535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * to copy to the temporary register again
333635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
333735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->clip_vertex_tmp_index = INVALID_INDEX;
333835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
333935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV clip_vertex, clip_vertex_tmp */
334035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   dst = make_dst_reg(TGSI_FILE_OUTPUT, emit->clip_vertex_out_index);
334135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
334235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &dst, &clipvert_src, FALSE);
334335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
334435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /**
334535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * set the temporary clip vertex register index back to the
334635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * temporary index for the next vertex
334735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
334835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->clip_vertex_tmp_index = clip_vertex_tmp;
334935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
335035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
335135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
335235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code to convert RGBA to BGRA
335335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
335435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
335535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_swap_r_b(struct svga_shader_emitter_v10 *emit,
335635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_dst_register *dst,
335735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     const struct tgsi_full_src_register *src)
335835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
335935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register bgra_src =
336035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swizzle_src(src, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, TGSI_SWIZZLE_W);
336135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
336235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
336335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, VGPU10_OPCODE_MOV, FALSE);
336435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, dst);
336535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &bgra_src);
336635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
336735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
336835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
336935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
337035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/** Convert from 10_10_10_2 normalized to 10_10_10_2_snorm */
337135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
337235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_puint_to_snorm(struct svga_shader_emitter_v10 *emit,
337335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                    const struct tgsi_full_dst_register *dst,
337435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                    const struct tgsi_full_src_register *src)
337535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
337635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register half = make_immediate_reg_float(emit, 0.5f);
337735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register two =
337835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_immediate_reg_float4(emit, 2.0f, 2.0f, 2.0f, 3.0f);
337935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register neg_two =
338035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_immediate_reg_float4(emit, -2.0f, -2.0f, -2.0f, -1.66666f);
338135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
338235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned val_tmp = get_temp_index(emit);
338335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register val_dst = make_dst_temp_reg(val_tmp);
338435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register val_src = make_src_temp_reg(val_tmp);
338535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
338635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned bias_tmp = get_temp_index(emit);
338735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register bias_dst = make_dst_temp_reg(bias_tmp);
338835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register bias_src = make_src_temp_reg(bias_tmp);
338935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
339035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* val = src * 2.0 */
339135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &val_dst,
339235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        src, &two, FALSE);
339335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
339435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* bias = src > 0.5 */
339535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_GE, &bias_dst,
339635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        src, &half, FALSE);
339735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
339835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* bias = bias & -2.0 */
339935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_AND, &bias_dst,
340035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &bias_src, &neg_two, FALSE);
340135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
340235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = val + bias */
340335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_ADD, dst,
340435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &val_src, &bias_src, FALSE);
340535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
340635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
340735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
340835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
340935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
341035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/** Convert from 10_10_10_2_unorm to 10_10_10_2_uscaled */
341135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
341235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_puint_to_uscaled(struct svga_shader_emitter_v10 *emit,
341335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      const struct tgsi_full_dst_register *dst,
341435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      const struct tgsi_full_src_register *src)
341535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
341635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register scale =
341735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_immediate_reg_float4(emit, 1023.0f, 1023.0f, 1023.0f, 3.0f);
341835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
341935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = src * scale */
342035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_MUL, dst, src, &scale, FALSE);
342135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
342235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
342335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
342435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/** Convert from R32_UINT to 10_10_10_2_sscaled */
342535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
342635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_puint_to_sscaled(struct svga_shader_emitter_v10 *emit,
342735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      const struct tgsi_full_dst_register *dst,
342835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      const struct tgsi_full_src_register *src)
342935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
343035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register lshift =
343135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_immediate_reg_int4(emit, 22, 12, 2, 0);
343235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register rshift =
343335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_immediate_reg_int4(emit, 22, 22, 22, 30);
343435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
343535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src_xxxx = scalar_src(src, TGSI_SWIZZLE_X);
343635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
343735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
343835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
343935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
344035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
344135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
344235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * r = (pixel << 22) >> 22;   # signed int in [511, -512]
344335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * g = (pixel << 12) >> 22;   # signed int in [511, -512]
344435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * b = (pixel <<  2) >> 22;   # signed int in [511, -512]
344535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * a = (pixel <<  0) >> 30;   # signed int in [1, -2]
344635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst = i_to_f(r,g,b,a);     # convert to float
344735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
344835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_ISHL, &tmp_dst,
344935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &src_xxxx, &lshift, FALSE);
345035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_ISHR, &tmp_dst,
345135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &tmp_src, &rshift, FALSE);
345235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_ITOF, dst, &tmp_src, FALSE);
345335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
345435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
345535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
345635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
345735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
345835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
345935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_ARL or TGSI_OPCODE_UARL instruction.
346035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
346135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
346235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_arl_uarl(struct svga_shader_emitter_v10 *emit,
346335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul              const struct tgsi_full_instruction *inst)
346435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
346535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned index = inst->Dst[0].Register.Index;
346635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register dst;
346735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned opcode;
346835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
346935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(index < MAX_VGPU10_ADDR_REGS);
347035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   dst = make_dst_temp_reg(emit->address_reg_index[index]);
347135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
347235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* ARL dst, s0
347335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
347435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * FTOI address_tmp, s0
347535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
347635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * UARL dst, s0
347735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
347835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * MOV address_tmp, s0
347935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
348035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Instruction.Opcode == TGSI_OPCODE_ARL)
348135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode = VGPU10_OPCODE_FTOI;
348235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else
348335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode = VGPU10_OPCODE_MOV;
348435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
348535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, opcode, &dst, &inst->Src[0], FALSE);
348635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
348735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
348835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
348935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
349035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
349135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
349235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_CAL instruction.
349335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
349435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
349535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_cal(struct svga_shader_emitter_v10 *emit,
349635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
349735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
349835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned label = inst->Label.Label;
349935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OperandToken0 operand;
350035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand.value = 0;
350135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   operand.operandType = VGPU10_OPERAND_TYPE_LABEL;
350235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
350335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
350435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, operand.value);
350535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, label);
350635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
350735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
350835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
350935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
351035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
351135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
351235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
351335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_IABS instruction.
351435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
351535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
351635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_iabs(struct svga_shader_emitter_v10 *emit,
351735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          const struct tgsi_full_instruction *inst)
351835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
351935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst.x = (src0.x < 0) ? -src0.x : src0.x
352035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = (src0.y < 0) ? -src0.y : src0.y
352135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = (src0.z < 0) ? -src0.z : src0.z
352235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = (src0.w < 0) ? -src0.w : src0.w
352335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
352435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into
352535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   IMAX dst, src, neg(src)
352635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
352735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register neg_src = negate_src(&inst->Src[0]);
352835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_IMAX, &inst->Dst[0],
352935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[0], &neg_src, FALSE);
353035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
353135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
353235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
353335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
353435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
353535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
353635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_CMP instruction.
353735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
353835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
353935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_cmp(struct svga_shader_emitter_v10 *emit,
354035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
354135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
354235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst.x = (src0.x < 0) ? src1.x : src2.x
354335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = (src0.y < 0) ? src1.y : src2.y
354435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = (src0.z < 0) ? src1.z : src2.z
354535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = (src0.w < 0) ? src1.w : src2.w
354635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
354735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into
354835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   LT tmp, src0, 0.0
354935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC dst, tmp, src1, src2
355035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
355135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
355235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
355335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
355435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
355535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
355635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp_dst,
355735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[0], &zero, FALSE);
355835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0],
355935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &tmp_src, &inst->Src[1], &inst->Src[2],
356035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        inst->Instruction.Saturate);
356135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
356235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
356335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
356435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
356535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
356635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
356735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
356835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
356935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_DP2A instruction.
357035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
357135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
357235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_dp2a(struct svga_shader_emitter_v10 *emit,
357335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          const struct tgsi_full_instruction *inst)
357435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
357535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst.x = src0.x * src1.x + src0.y * src1.y + src2.x
357635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = src0.x * src1.x + src0.y * src1.y + src2.x
357735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = src0.x * src1.x + src0.y * src1.y + src2.x
357835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = src0.x * src1.x + src0.y * src1.y + src2.x
357935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translate into
358035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MAD tmp.x, s0.y, s1.y, s2.x
358135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MAD tmp.x, s0.x, s1.x, tmp.x
358235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOV dst.xyzw, tmp.xxxx
358335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
358435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
358535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
358635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
358735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
358835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src_xxxx =
358935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&tmp_src, TGSI_SWIZZLE_X);
359035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst_x =
359135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
359235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
359335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src0_xxxx =
359435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
359535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src0_yyyy =
359635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_Y);
359735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src1_xxxx =
359835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[1], TGSI_SWIZZLE_X);
359935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src1_yyyy =
360035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[1], TGSI_SWIZZLE_Y);
360135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src2_xxxx =
360235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[2], TGSI_SWIZZLE_X);
360335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
360435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MAD, &tmp_dst_x, &src0_yyyy,
360535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &src1_yyyy, &src2_xxxx, FALSE);
360635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MAD, &tmp_dst_x, &src0_xxxx,
360735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &src1_xxxx, &tmp_src_xxxx, FALSE);
360835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0],
360935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &tmp_src_xxxx, inst->Instruction.Saturate);
361035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
361135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
361235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
361335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
361435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
361535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
361635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
361735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
361835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_DPH instruction.
361935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
362035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
362135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_dph(struct svga_shader_emitter_v10 *emit,
362235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
362335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
362435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
362535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * DP3 tmp, s0, s1
362635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * ADD dst, tmp, s1.wwww
362735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
362835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
362935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s1_wwww =
363035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swizzle_src(&inst->Src[1], TGSI_SWIZZLE_W, TGSI_SWIZZLE_W,
363135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  TGSI_SWIZZLE_W, TGSI_SWIZZLE_W);
363235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
363335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
363435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
363535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
363635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
363735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* DP3 tmp, s0, s1 */
363835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_DP3, &tmp_dst, &inst->Src[0],
363935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[1], FALSE);
364035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
364135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* ADD dst, tmp, s1.wwww */
364235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &inst->Dst[0], &tmp_src,
364335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &s1_wwww, inst->Instruction.Saturate);
364435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
364535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
364635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
364735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
364835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
364935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
365035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
365135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
365235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_DST instruction.
365335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
365435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
365535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_dst(struct svga_shader_emitter_v10 *emit,
365635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
365735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
365835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
365935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.x = 1
366035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = src0.y * src1.y
366135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = src0.z
366235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = src1.w
366335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
366435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
366535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s0_yyyy =
366635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_Y);
366735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s0_zzzz =
366835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_Z);
366935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s1_yyyy =
367035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[1], TGSI_SWIZZLE_Y);
367135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s1_wwww =
367235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[1], TGSI_SWIZZLE_W);
367335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
367435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
367535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * If dst and either src0 and src1 are the same we need
367635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * to create a temporary for it and insert a extra move.
367735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
367835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp_move = get_temp_index(emit);
367935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register move_src = make_src_temp_reg(tmp_move);
368035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register move_dst = make_dst_temp_reg(tmp_move);
368135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
368235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst.x, 1.0 */
368335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
368435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_x =
368535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_X);
368635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
368735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
368835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_x, &one, FALSE);
368935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
369035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
369135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MUL dst.y, s0.y, s1.y */
369235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
369335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_y =
369435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_Y);
369535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
369635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &dst_y, &s0_yyyy,
369735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &s1_yyyy, inst->Instruction.Saturate);
369835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
369935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
370035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst.z, s0.z */
370135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
370235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_z =
370335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_Z);
370435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
370535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_z, &s0_zzzz,
370635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           inst->Instruction.Saturate);
370735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul  }
370835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
370935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst.w, s1.w */
371035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
371135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_w =
371235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_W);
371335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
371435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_w, &s1_wwww,
371535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           inst->Instruction.Saturate);
371635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
371735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
371835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &move_src,
371935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        FALSE);
372035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
372135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
372235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
372335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
372435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
372535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
372635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
372735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
372835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_ENDPRIM (GS only)
372935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
373035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
373135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_endprim(struct svga_shader_emitter_v10 *emit,
373235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             const struct tgsi_full_instruction *inst)
373335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
373435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_GEOMETRY);
373535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
373635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* We can't use emit_simple() because the TGSI instruction has one
373735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * operand (vertex stream number) which we must ignore for VGPU10.
373835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
373935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
374035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, VGPU10_OPCODE_CUT, FALSE);
374135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
374235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
374335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
374435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
374535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
374635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
374735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_EX2 (2^x) instruction.
374835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
374935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
375035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_ex2(struct svga_shader_emitter_v10 *emit,
375135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
375235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
375335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Note that TGSI_OPCODE_EX2 computes only one value from src.x
375435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * while VGPU10 computes four values.
375535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
375635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst = EX2(src):
375735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst.xyzw = 2.0 ^ src.x
375835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
375935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
376035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src_xxxx =
376135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swizzle_src(&inst->Src[0], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
376235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
376335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
376435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* EXP tmp, s0.xxxx */
376535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &inst->Dst[0], &src_xxxx,
376635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        inst->Instruction.Saturate);
376735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
376835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
376935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
377035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
377135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
377235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
377335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_EXP instruction.
377435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
377535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
377635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_exp(struct svga_shader_emitter_v10 *emit,
377735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
377835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
377935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
378035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.x = 2 ^ floor(s0.x)
378135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = s0.x - floor(s0.x)
378235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = 2 ^ s0.x
378335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = 1.0
378435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
378535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
378635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src_xxxx =
378735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
378835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
378935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
379035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
379135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
379235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
379335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * If dst and src are the same we need to create
379435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * a temporary for it and insert a extra move.
379535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
379635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp_move = get_temp_index(emit);
379735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register move_src = make_src_temp_reg(tmp_move);
379835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register move_dst = make_dst_temp_reg(tmp_move);
379935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
380035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* only use X component of temp reg */
380135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tmp_dst = writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
380235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tmp_src = scalar_src(&tmp_src, TGSI_SWIZZLE_X);
380335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
380435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* ROUND_NI tmp.x, s0.x */
380535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_ROUND_NI, &tmp_dst,
380635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &src_xxxx, FALSE); /* round to -infinity */
380735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
380835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* EXP dst.x, tmp.x */
380935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
381035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_x =
381135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_X);
381235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
381335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &dst_x, &tmp_src,
381435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           inst->Instruction.Saturate);
381535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
381635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
381735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* ADD dst.y, s0.x, -tmp */
381835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
381935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_y =
382035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_Y);
382135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register neg_tmp_src = negate_src(&tmp_src);
382235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
382335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &dst_y, &src_xxxx,
382435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &neg_tmp_src, inst->Instruction.Saturate);
382535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
382635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
382735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* EXP dst.z, s0.x */
382835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
382935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_z =
383035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_Z);
383135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
383235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &dst_z, &src_xxxx,
383335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           inst->Instruction.Saturate);
383435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
383535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
383635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst.w, 1.0 */
383735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
383835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_w =
383935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_W);
384035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
384135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
384235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_w, &one,
384335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           FALSE);
384435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
384535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
384635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &move_src,
384735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        FALSE);
384835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
384935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
385035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
385135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
385235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
385335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
385435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
385535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
385635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_IF instruction.
385735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
385835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
385935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_if(struct svga_shader_emitter_v10 *emit,
386035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul        const struct tgsi_full_instruction *inst)
386135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
386235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 opcode0;
386335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
386435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* The src register should be a scalar */
386535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(inst->Src[0].Register.SwizzleX == inst->Src[0].Register.SwizzleY &&
386635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          inst->Src[0].Register.SwizzleX == inst->Src[0].Register.SwizzleZ &&
386735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          inst->Src[0].Register.SwizzleX == inst->Src[0].Register.SwizzleW);
386835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
386935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* The only special thing here is that we need to set the
387035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * VGPU10_INSTRUCTION_TEST_NONZERO flag since we want to test if
387135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * src.x is non-zero.
387235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
387335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = 0;
387435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.opcodeType = VGPU10_OPCODE_IF;
387535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.testBoolean = VGPU10_INSTRUCTION_TEST_NONZERO;
387635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
387735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
387835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, opcode0.value);
387935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &inst->Src[0]);
388035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
388135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
388235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
388335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
388435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
388535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
388635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
388735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_KILL_IF instruction (kill fragment if any of
388835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * the register components are negative).
388935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
389035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
389135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_kill_if(struct svga_shader_emitter_v10 *emit,
389235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             const struct tgsi_full_instruction *inst)
389335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
389435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
389535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
389635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
389735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
389835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
389935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
390035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst_x =
390135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
390235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src_xxxx =
390335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&tmp_src, TGSI_SWIZZLE_X);
390435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
390535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* tmp = src[0] < 0.0 */
390635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp_dst, &inst->Src[0],
390735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &zero, FALSE);
390835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
390935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!same_swizzle_terms(&inst->Src[0])) {
391035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* If the swizzle is not XXXX, YYYY, ZZZZ or WWWW we need to
391135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * logically OR the swizzle terms.  Most uses of KILL_IF only
391235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * test one channel so it's good to avoid these extra steps.
391335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
391435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register tmp_src_yyyy =
391535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&tmp_src, TGSI_SWIZZLE_Y);
391635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register tmp_src_zzzz =
391735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&tmp_src, TGSI_SWIZZLE_Z);
391835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register tmp_src_wwww =
391935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&tmp_src, TGSI_SWIZZLE_W);
392035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
392135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_OR, &tmp_dst_x, &tmp_src_xxxx,
392235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_src_yyyy, FALSE);
392335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_OR, &tmp_dst_x, &tmp_src_xxxx,
392435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_src_zzzz, FALSE);
392535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_OR, &tmp_dst_x, &tmp_src_xxxx,
392635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_src_wwww, FALSE);
392735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
392835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
392935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
393035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_discard_opcode(emit, TRUE); /* discard if src0.x is non-zero */
393135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &tmp_src_xxxx);
393235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
393335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
393435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
393535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
393635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
393735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
393835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
393935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
394035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
394135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_KILL instruction (unconditional discard).
394235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
394335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
394435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_kill(struct svga_shader_emitter_v10 *emit,
394535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          const struct tgsi_full_instruction *inst)
394635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
394735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
394835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
394935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* DISCARD if 0.0 is zero */
395035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
395135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_discard_opcode(emit, FALSE);
395235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &zero);
395335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
395435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
395535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
395635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
395735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
395835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
395935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
396035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_LG2 instruction.
396135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
396235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
396335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_lg2(struct svga_shader_emitter_v10 *emit,
396435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
396535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
396635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Note that TGSI_OPCODE_LG2 computes only one value from src.x
396735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * while VGPU10 computes four values.
396835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
396935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst = LG2(src):
397035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst.xyzw = log2(src.x)
397135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
397235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
397335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src_xxxx =
397435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swizzle_src(&inst->Src[0], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
397535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
397635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
397735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* LOG tmp, s0.xxxx */
397835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_LOG, &inst->Dst[0], &src_xxxx,
397935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        inst->Instruction.Saturate);
398035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
398135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
398235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
398335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
398435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
398535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
398635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_LIT instruction.
398735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
398835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
398935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_lit(struct svga_shader_emitter_v10 *emit,
399035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
399135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
399235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
399335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
399435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
399535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * If dst and src are the same we need to create
399635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * a temporary for it and insert a extra move.
399735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
399835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp_move = get_temp_index(emit);
399935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register move_src = make_src_temp_reg(tmp_move);
400035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register move_dst = make_dst_temp_reg(tmp_move);
400135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
400235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
400335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.x = 1
400435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = max(src.x, 0)
400535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = (src.x > 0) ? max(src.y, 0)^{clamp(src.w, -128, 128))} : 0
400635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = 1
400735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
400835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
400935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst.x, 1.0 */
401035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
401135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_x =
401235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_X);
401335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_x, &one, FALSE);
401435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
401535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
401635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst.w, 1.0 */
401735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
401835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_w =
401935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_W);
402035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_w, &one, FALSE);
402135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
402235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
402335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MAX dst.y, src.x, 0.0 */
402435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
402535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_y =
402635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_Y);
402735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register zero =
402835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, 0.0f);
402935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register src_xxxx =
403035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         swizzle_src(&inst->Src[0], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
403135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
403235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
403335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MAX, &dst_y, &src_xxxx,
403435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &zero, inst->Instruction.Saturate);
403535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
403635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
403735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
403835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * tmp1 = clamp(src.w, -128, 128);
403935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MAX tmp1, src.w, -128
404035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MIN tmp1, tmp1, 128
404135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
404235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * tmp2 = max(tmp2, 0);
404335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MAX tmp2, src.y, 0
404435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
404535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * tmp1 = pow(tmp2, tmp1);
404635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   LOG tmp2, tmp2
404735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MUL tmp1, tmp2, tmp1
404835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   EXP tmp1, tmp1
404935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
405035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * tmp1 = (src.w == 0) ? 1 : tmp1;
405135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   EQ tmp2, 0, src.w
405235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC tmp1, tmp2, 1.0, tmp1
405335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
405435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = (0 < src.x) ? tmp1 : 0;
405535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   LT tmp2, 0, src.x
405635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC dst.z, tmp2, tmp1, 0.0
405735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
405835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
405935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_z =
406035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&move_dst, TGSI_WRITEMASK_Z);
406135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
406235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned tmp1 = get_temp_index(emit);
406335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register tmp1_src = make_src_temp_reg(tmp1);
406435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp1_dst = make_dst_temp_reg(tmp1);
406535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned tmp2 = get_temp_index(emit);
406635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register tmp2_src = make_src_temp_reg(tmp2);
406735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp2_dst = make_dst_temp_reg(tmp2);
406835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
406935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register src_xxxx =
407035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
407135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register src_yyyy =
407235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&inst->Src[0], TGSI_SWIZZLE_Y);
407335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register src_wwww =
407435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&inst->Src[0], TGSI_SWIZZLE_W);
407535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
407635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register zero =
407735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, 0.0f);
407835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register lowerbound =
407935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, -128.0f);
408035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register upperbound =
408135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, 128.0f);
408235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
408335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MAX, &tmp1_dst, &src_wwww,
408435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &lowerbound, FALSE);
408535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MIN, &tmp1_dst, &tmp1_src,
408635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &upperbound, FALSE);
408735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MAX, &tmp2_dst, &src_yyyy,
408835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &zero, FALSE);
408935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
409035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* POW tmp1, tmp2, tmp1 */
409135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* LOG tmp2, tmp2 */
409235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_LOG, &tmp2_dst, &tmp2_src,
409335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           FALSE);
409435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
409535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MUL tmp1, tmp2, tmp1 */
409635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp1_dst, &tmp2_src,
409735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp1_src, FALSE);
409835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
409935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* EXP tmp1, tmp1 */
410035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &tmp1_dst, &tmp1_src,
410135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           FALSE);
410235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
410335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* EQ tmp2, 0, src.w */
410435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_EQ, &tmp2_dst, &zero,
410535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &src_wwww, FALSE);
410635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOVC tmp1.z, tmp2, tmp1, 1.0 */
410735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &tmp1_dst,
410835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp2_src, &one, &tmp1_src, FALSE);
410935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
411035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* LT tmp2, 0, src.x */
411135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp2_dst, &zero,
411235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &src_xxxx, FALSE);
411335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOVC dst.z, tmp2, tmp1, 0.0 */
411435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &dst_z,
411535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp2_src, &tmp1_src, &zero, FALSE);
411635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
411735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
411835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &move_src,
411935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        FALSE);
412035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
412135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
412235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
412335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
412435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
412535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
412635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
412735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_LOG instruction.
412835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
412935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
413035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_log(struct svga_shader_emitter_v10 *emit,
413135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
413235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
413335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
413435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.x = floor(lg2(abs(s0.x)))
413535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = abs(s0.x) / (2 ^ floor(lg2(abs(s0.x))))
413635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = lg2(abs(s0.x))
413735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = 1.0
413835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
413935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
414035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src_xxxx =
414135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
414235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
414335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
414435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
414535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register abs_src_xxxx = absolute_src(&src_xxxx);
414635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
414735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* only use X component of temp reg */
414835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tmp_dst = writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
414935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tmp_src = scalar_src(&tmp_src, TGSI_SWIZZLE_X);
415035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
415135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* LOG tmp.x, abs(s0.x) */
415235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XYZ) {
415335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_LOG, &tmp_dst,
415435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                          &abs_src_xxxx, FALSE);
415535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
415635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
415735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst.z, tmp.x */
415835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
415935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_z =
416035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_Z);
416135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
416235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_z,
416335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_src, inst->Instruction.Saturate);
416435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
416535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
416635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* FLR tmp.x, tmp.x */
416735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) {
416835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_ROUND_NI, &tmp_dst,
416935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_src, FALSE);
417035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
417135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
417235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst.x, tmp.x */
417335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
417435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_x =
417535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_X);
417635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
417735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_x, &tmp_src,
417835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           inst->Instruction.Saturate);
417935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
418035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
418135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* EXP tmp.x, tmp.x */
418235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* DIV dst.y, abs(s0.x), tmp.x */
418335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
418435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_y =
418535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_Y);
418635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
418735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &tmp_dst, &tmp_src,
418835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           FALSE);
418935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_DIV, &dst_y, &abs_src_xxxx,
419035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_src, inst->Instruction.Saturate);
419135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
419235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
419335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst.w, 1.0 */
419435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
419535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register dst_w =
419635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_W);
419735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one =
419835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, 1.0f);
419935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
420035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_w, &one, FALSE);
420135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
420235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
420335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
420435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
420535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
420635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
420735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
420835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
420935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
421035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_LRP instruction.
421135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
421235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
421335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_lrp(struct svga_shader_emitter_v10 *emit,
421435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
421535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
421635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = LRP(s0, s1, s2):
421735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst = s0 * (s1 - s2) + s2
421835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
421935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   SUB tmp, s1, s2;        tmp = s1 - s2
422035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MAD dst, s0, tmp, s2;   dst = s0 * t1 + s2
422135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
422235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
422335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src_tmp = make_src_temp_reg(tmp);
422435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register dst_tmp = make_dst_temp_reg(tmp);
422535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register neg_src2 = negate_src(&inst->Src[2]);
422635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
422735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* ADD tmp, s1, -s2 */
422835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &dst_tmp,
422935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[1], &neg_src2, FALSE);
423035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
423135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MAD dst, s1, tmp, s3 */
423235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MAD, &inst->Dst[0],
423335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[0], &src_tmp, &inst->Src[2],
423435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        inst->Instruction.Saturate);
423535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
423635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
423735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
423835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
423935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
424035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
424135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
424235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
424335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_POW instruction.
424435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
424535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
424635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_pow(struct svga_shader_emitter_v10 *emit,
424735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
424835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
424935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Note that TGSI_OPCODE_POW computes only one value from src0.x and
425035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * src1.x while VGPU10 computes four values.
425135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
425235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst = POW(src0, src1):
425335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst.xyzw = src0.x ^ src1.x
425435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
425535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
425635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
425735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
425835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src0_xxxx =
425935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swizzle_src(&inst->Src[0], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
426035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
426135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src1_xxxx =
426235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swizzle_src(&inst->Src[1], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
426335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
426435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
426535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* LOG tmp, s0.xxxx */
426635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_LOG, &tmp_dst, &src0_xxxx,
426735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        FALSE);
426835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
426935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MUL tmp, tmp, s1.xxxx */
427035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_dst, &tmp_src,
427135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &src1_xxxx, FALSE);
427235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
427335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* EXP tmp, s0.xxxx */
427435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &inst->Dst[0],
427535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &tmp_src, inst->Instruction.Saturate);
427635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
427735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* free tmp */
427835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
427935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
428035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
428135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
428235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
428335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
428435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
428535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_RCP (reciprocal) instruction.
428635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
428735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
428835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_rcp(struct svga_shader_emitter_v10 *emit,
428935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
429035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
429135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
429235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
429335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
429435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
429535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
429635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
429735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst_x =
429835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
429935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src_xxxx =
430035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&tmp_src, TGSI_SWIZZLE_X);
430135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
430235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* DIV tmp.x, 1.0, s0 */
430335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_DIV, &tmp_dst_x, &one,
430435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[0], FALSE);
430535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
430635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst, tmp.xxxx */
430735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0],
430835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &tmp_src_xxxx, inst->Instruction.Saturate);
430935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
431035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
431135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
431235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
431335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
431435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
431535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
431635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
431735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_RSQ instruction.
431835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
431935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
432035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_rsq(struct svga_shader_emitter_v10 *emit,
432135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
432235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
432335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = RSQ(src):
432435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst.xyzw = 1 / sqrt(src.x)
432535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
432635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   RSQ tmp, src.x
432735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOV dst, tmp.xxxx
432835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
432935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
433035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
433135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
433235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
433335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
433435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst_x =
433535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
433635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src_xxxx =
433735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&tmp_src, TGSI_SWIZZLE_X);
433835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
433935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* RSQ tmp, src.x */
434035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_RSQ, &tmp_dst_x,
434135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[0], FALSE);
434235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
434335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst, tmp.xxxx */
434435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0],
434535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &tmp_src_xxxx, inst->Instruction.Saturate);
434635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
434735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* free tmp */
434835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
434935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
435035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
435135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
435235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
435335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
435435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
435535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SCS instruction.
435635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
435735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
435835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_scs(struct svga_shader_emitter_v10 *emit,
435935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
436035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
436135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst.x = cos(src.x)
436235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = sin(src.x)
436335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = 0.0
436435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = 1.0
436535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
436635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register dst_x =
436735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_X);
436835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register dst_y =
436935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_Y);
437035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register dst_zw =
437135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_ZW);
437235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
437335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero_one =
437435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_immediate_reg_float4(emit, 0.0f, 0.0f, 0.0f, 1.0f);
437535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
437635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
437735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, VGPU10_OPCODE_SINCOS, inst->Instruction.Saturate);
437835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, &dst_y);
437935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, &dst_x);
438035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &inst->Src[0]);
438135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
438235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
438335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
438435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &dst_zw, &zero_one, inst->Instruction.Saturate);
438535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
438635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
438735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
438835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
438935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
439035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
439135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SEQ (Set Equal) instruction.
439235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
439335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
439435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_seq(struct svga_shader_emitter_v10 *emit,
439535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
439635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
439735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = SEQ(s0, s1):
439835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst = s0 == s1 ? 1.0 : 0.0  (per component)
439935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
440035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   EQ tmp, s0, s1;           tmp = s0 == s1 : 0xffffffff : 0 (per comp)
440135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC dst, tmp, 1.0, 0.0;  dst = tmp ? 1.0 : 0.0 (per component)
440235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
440335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
440435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
440535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
440635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
440735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
440835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
440935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* EQ tmp, s0, s1 */
441035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_EQ, &tmp_dst, &inst->Src[0],
441135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[1], FALSE);
441235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
441335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOVC dst, tmp, one, zero */
441435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
441535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &one, &zero, FALSE);
441635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
441735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
441835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
441935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
442035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
442135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
442235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
442335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
442435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SGE (Set Greater than or Equal) instruction.
442535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
442635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
442735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_sge(struct svga_shader_emitter_v10 *emit,
442835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
442935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
443035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = SGE(s0, s1):
443135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst = s0 >= s1 ? 1.0 : 0.0  (per component)
443235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
443335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   GE tmp, s0, s1;           tmp = s0 >= s1 : 0xffffffff : 0 (per comp)
443435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC dst, tmp, 1.0, 0.0;  dst = tmp ? 1.0 : 0.0 (per component)
443535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
443635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
443735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
443835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
443935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
444035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
444135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
444235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* GE tmp, s0, s1 */
444335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_GE, &tmp_dst, &inst->Src[0],
444435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[1], FALSE);
444535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
444635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOVC dst, tmp, one, zero */
444735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
444835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &one, &zero, FALSE);
444935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
445035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
445135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
445235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
445335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
445435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
445535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
445635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
445735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SGT (Set Greater than) instruction.
445835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
445935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
446035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_sgt(struct svga_shader_emitter_v10 *emit,
446135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
446235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
446335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = SGT(s0, s1):
446435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst = s0 > s1 ? 1.0 : 0.0  (per component)
446535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
446635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   LT tmp, s1, s0;           tmp = s1 < s0 ? 0xffffffff : 0 (per comp)
446735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC dst, tmp, 1.0, 0.0;  dst = tmp ? 1.0 : 0.0 (per component)
446835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
446935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
447035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
447135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
447235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
447335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
447435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
447535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* LT tmp, s1, s0 */
447635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp_dst, &inst->Src[1],
447735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[0], FALSE);
447835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
447935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOVC dst, tmp, one, zero */
448035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
448135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &one, &zero, FALSE);
448235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
448335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
448435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
448535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
448635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
448735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
448835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
448935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
449035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SIN and TGSI_OPCODE_COS instructions.
449135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
449235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
449335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_sincos(struct svga_shader_emitter_v10 *emit,
449435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
449535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
449635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
449735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
449835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
449935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
450035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src_xxxx =
450135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&tmp_src, TGSI_SWIZZLE_X);
450235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst_x =
450335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
450435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
450535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
450635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, VGPU10_OPCODE_SINCOS, FALSE);
450735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
450835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if(inst->Instruction.Opcode == TGSI_OPCODE_SIN)
450935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   {
451035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, &tmp_dst_x);  /* first destination register */
451135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_null_dst_register(emit);  /* second destination register */
451235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
451335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
451435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_null_dst_register(emit);
451535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, &tmp_dst_x);
451635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
451735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
451835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &inst->Src[0]);
451935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
452035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
452135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0],
452235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &tmp_src_xxxx, inst->Instruction.Saturate);
452335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
452435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
452535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
452635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
452735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
452835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
452935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
453035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
453135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SLE (Set Less than or Equal) instruction.
453235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
453335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
453435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_sle(struct svga_shader_emitter_v10 *emit,
453535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
453635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
453735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = SLE(s0, s1):
453835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst = s0 <= s1 ? 1.0 : 0.0  (per component)
453935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
454035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   GE tmp, s1, s0;           tmp = s1 >= s0 : 0xffffffff : 0 (per comp)
454135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC dst, tmp, 1.0, 0.0;  dst = tmp ? 1.0 : 0.0 (per component)
454235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
454335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
454435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
454535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
454635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
454735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
454835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
454935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* GE tmp, s1, s0 */
455035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_GE, &tmp_dst, &inst->Src[1],
455135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[0], FALSE);
455235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
455335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOVC dst, tmp, one, zero */
455435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
455535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &one, &zero, FALSE);
455635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
455735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
455835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
455935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
456035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
456135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
456235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
456335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
456435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SLT (Set Less than) instruction.
456535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
456635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
456735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_slt(struct svga_shader_emitter_v10 *emit,
456835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
456935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
457035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = SLT(s0, s1):
457135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst = s0 < s1 ? 1.0 : 0.0  (per component)
457235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
457335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   LT tmp, s0, s1;           tmp = s0 < s1 ? 0xffffffff : 0 (per comp)
457435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC dst, tmp, 1.0, 0.0;  dst = tmp ? 1.0 : 0.0 (per component)
457535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
457635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
457735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
457835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
457935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
458035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
458135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
458235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* LT tmp, s0, s1 */
458335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp_dst, &inst->Src[0],
458435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[1], FALSE);
458535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
458635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOVC dst, tmp, one, zero */
458735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
458835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &one, &zero, FALSE);
458935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
459035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
459135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
459235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
459335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
459435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
459535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
459635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
459735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SNE (Set Not Equal) instruction.
459835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
459935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
460035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_sne(struct svga_shader_emitter_v10 *emit,
460135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
460235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
460335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = SNE(s0, s1):
460435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   dst = s0 != s1 ? 1.0 : 0.0  (per component)
460535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
460635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   EQ tmp, s0, s1;           tmp = s0 == s1 : 0xffffffff : 0 (per comp)
460735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC dst, tmp, 1.0, 0.0;  dst = tmp ? 1.0 : 0.0 (per component)
460835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
460935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
461035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
461135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
461235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
461335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
461435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
461535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* NE tmp, s0, s1 */
461635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_NE, &tmp_dst, &inst->Src[0],
461735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[1], FALSE);
461835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
461935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOVC dst, tmp, one, zero */
462035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
462135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &one, &zero, FALSE);
462235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
462335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
462435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
462535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
462635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
462735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
462835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
462935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
463035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SSG (Set Sign) instruction.
463135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
463235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
463335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_ssg(struct svga_shader_emitter_v10 *emit,
463435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
463535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
463635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst.x = (src.x > 0.0) ? 1.0 : (src.x < 0.0) ? -1.0 : 0.0
463735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = (src.y > 0.0) ? 1.0 : (src.y < 0.0) ? -1.0 : 0.0
463835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = (src.z > 0.0) ? 1.0 : (src.z < 0.0) ? -1.0 : 0.0
463935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = (src.w > 0.0) ? 1.0 : (src.w < 0.0) ? -1.0 : 0.0
464035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
464135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   LT tmp1, src, zero;           tmp1 = src < zero ? 0xffffffff : 0 (per comp)
464235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC tmp2, tmp1, -1.0, 0.0;   tmp2 = tmp1 ? -1.0 : 0.0 (per component)
464335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   LT tmp1, zero, src;           tmp1 = zero < src ? 0xffffffff : 0 (per comp)
464435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   MOVC dst, tmp1, 1.0, tmp2;    dst = tmp1 ? 1.0 : tmp2 (per component)
464535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
464635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero =
464735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_immediate_reg_float(emit, 0.0f);
464835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register one =
464935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_immediate_reg_float(emit, 1.0f);
465035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register neg_one =
465135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_immediate_reg_float(emit, -1.0f);
465235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
465335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp1 = get_temp_index(emit);
465435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp1_src = make_src_temp_reg(tmp1);
465535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp1_dst = make_dst_temp_reg(tmp1);
465635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
465735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp2 = get_temp_index(emit);
465835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp2_src = make_src_temp_reg(tmp2);
465935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp2_dst = make_dst_temp_reg(tmp2);
466035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
466135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp1_dst, &inst->Src[0],
466235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &zero, FALSE);
466335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &tmp2_dst, &tmp1_src,
466435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &neg_one, &zero, FALSE);
466535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp1_dst, &zero,
466635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[0], FALSE);
466735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp1_src,
466835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &one, &tmp2_src, FALSE);
466935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
467035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
467135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
467235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
467335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
467435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
467535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
467635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
467735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_ISSG (Integer Set Sign) instruction.
467835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
467935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
468035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_issg(struct svga_shader_emitter_v10 *emit,
468135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          const struct tgsi_full_instruction *inst)
468235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
468335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst.x = (src.x > 0) ? 1 : (src.x < 0) ? -1 : 0
468435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = (src.y > 0) ? 1 : (src.y < 0) ? -1 : 0
468535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = (src.z > 0) ? 1 : (src.z < 0) ? -1 : 0
468635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = (src.w > 0) ? 1 : (src.w < 0) ? -1 : 0
468735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Translates into:
468835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   ILT tmp1, src, 0              tmp1 = src < 0 ? -1 : 0 (per component)
468935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   ILT tmp2, 0, src              tmp2 = 0 < src ? -1 : 0 (per component)
469035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *   IADD dst, tmp1, neg(tmp2)     dst  = tmp1 - tmp2      (per component)
469135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
469235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
469335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
469435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp1 = get_temp_index(emit);
469535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp1_src = make_src_temp_reg(tmp1);
469635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp1_dst = make_dst_temp_reg(tmp1);
469735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
469835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp2 = get_temp_index(emit);
469935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp2_src = make_src_temp_reg(tmp2);
470035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp2_dst = make_dst_temp_reg(tmp2);
470135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
470235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register neg_tmp2 = negate_src(&tmp2_src);
470335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
470435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_ILT, &tmp1_dst,
470535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &inst->Src[0], &zero, FALSE);
470635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_ILT, &tmp2_dst,
470735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &zero, &inst->Src[0], FALSE);
470835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_IADD, &inst->Dst[0],
470935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &tmp1_src, &neg_tmp2, FALSE);
471035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
471135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
471235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
471335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
471435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
471535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
471635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
471735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
471835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit a comparison instruction.  The dest register will get
471935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * 0 or ~0 values depending on the outcome of comparing src0 to src1.
472035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
472135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
472235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_comparison(struct svga_shader_emitter_v10 *emit,
472335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                SVGA3dCmpFunc func,
472435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                const struct tgsi_full_dst_register *dst,
472535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                const struct tgsi_full_src_register *src0,
472635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                const struct tgsi_full_src_register *src1)
472735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
472835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register immediate;
472935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10OpcodeToken0 opcode0;
473035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   boolean swapSrc = FALSE;
473135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
473235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Sanity checks for svga vs. gallium enums */
473335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   STATIC_ASSERT(SVGA3D_CMP_LESS == (PIPE_FUNC_LESS + 1));
473435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   STATIC_ASSERT(SVGA3D_CMP_GREATEREQUAL == (PIPE_FUNC_GEQUAL + 1));
473535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
473635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   opcode0.value = 0;
473735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
473835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (func) {
473935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case SVGA3D_CMP_NEVER:
474035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      immediate = make_immediate_reg_int(emit, 0);
474135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV dst, {0} */
474235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
474335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, VGPU10_OPCODE_MOV);
474435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, dst);
474535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &immediate);
474635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
474735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return;
474835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case SVGA3D_CMP_ALWAYS:
474935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      immediate = make_immediate_reg_int(emit, -1);
475035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV dst, {-1} */
475135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
475235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dword(emit, VGPU10_OPCODE_MOV);
475335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, dst);
475435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &immediate);
475535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
475635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return;
475735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case SVGA3D_CMP_LESS:
475835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_LT;
475935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
476035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case SVGA3D_CMP_EQUAL:
476135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_EQ;
476235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
476335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case SVGA3D_CMP_LESSEQUAL:
476435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_GE;
476535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swapSrc = TRUE;
476635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
476735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case SVGA3D_CMP_GREATER:
476835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_LT;
476935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swapSrc = TRUE;
477035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
477135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case SVGA3D_CMP_NOTEQUAL:
477235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_NE;
477335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
477435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case SVGA3D_CMP_GREATEREQUAL:
477535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_GE;
477635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      break;
477735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
477835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(!"Unexpected comparison mode");
477935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode0.opcodeType = VGPU10_OPCODE_EQ;
478035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
478135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
478235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
478335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dword(emit, opcode0.value);
478435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, dst);
478535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (swapSrc) {
478635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, src1);
478735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, src0);
478835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
478935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
479035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, src0);
479135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, src1);
479235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
479335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
479435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
479535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
479635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
479735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
479835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Get texel/address offsets for a texture instruction.
479935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
480035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
480135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulget_texel_offsets(const struct svga_shader_emitter_v10 *emit,
480235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  const struct tgsi_full_instruction *inst, int offsets[3])
480335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
480435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Texture.NumOffsets == 1) {
480535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* According to OpenGL Shader Language spec the offsets are only
480635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * fetched from a previously-declared immediate/literal.
480735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
480835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      const struct tgsi_texture_offset *off = inst->TexOffsets;
480935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      const unsigned index = off[0].Index;
481035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      const unsigned swizzleX = off[0].SwizzleX;
481135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      const unsigned swizzleY = off[0].SwizzleY;
481235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      const unsigned swizzleZ = off[0].SwizzleZ;
481335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      const union tgsi_immediate_data *imm = emit->immediates[index];
481435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
481535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(inst->TexOffsets[0].File == TGSI_FILE_IMMEDIATE);
481635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
481735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      offsets[0] = imm[swizzleX].Int;
481835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      offsets[1] = imm[swizzleY].Int;
481935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      offsets[2] = imm[swizzleZ].Int;
482035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
482135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
482235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      offsets[0] = offsets[1] = offsets[2] = 0;
482335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
482435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
482535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
482635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
482735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
482835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Set up the coordinate register for texture sampling.
482935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * When we're sampling from a RECT texture we have to scale the
483035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * unnormalized coordinate to a normalized coordinate.
483135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * We do that by multiplying the coordinate by an "extra" constant.
483235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * An alternative would be to use the RESINFO instruction to query the
483335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * texture's size.
483435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
483535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic struct tgsi_full_src_register
483635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulsetup_texcoord(struct svga_shader_emitter_v10 *emit,
483735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               unsigned unit,
483835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               const struct tgsi_full_src_register *coord)
483935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
484035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->key.tex[unit].unnormalized) {
484135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned scale_index = emit->texcoord_scale_index[unit];
484235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned tmp = get_temp_index(emit);
484335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
484435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
484535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register scale_src = make_src_const_reg(scale_index);
484635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
484735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MUL tmp, coord, const[] */
484835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_dst,
484935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           coord, &scale_src, FALSE);
485035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return tmp_src;
485135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
485235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
485335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* use texcoord as-is */
485435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return *coord;
485535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
485635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
485735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
485835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
485935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
486035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * For SAMPLE_C instructions, emit the extra src register which indicates
486135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * the reference/comparision value.
486235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
486335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
486435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_tex_compare_refcoord(struct svga_shader_emitter_v10 *emit,
486535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                          unsigned target,
486635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                          const struct tgsi_full_src_register *coord)
486735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
486835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register coord_src_ref;
486935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned component;
487035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
487135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(tgsi_is_shadow_target(target));
487235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
487335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(target != TGSI_TEXTURE_SHADOWCUBE_ARRAY); /* XXX not implemented */
487435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (target == TGSI_TEXTURE_SHADOW2D_ARRAY ||
487535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       target == TGSI_TEXTURE_SHADOWCUBE)
487635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      component = TGSI_SWIZZLE_W;
487735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else
487835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      component = TGSI_SWIZZLE_Z;
487935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
488035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   coord_src_ref = scalar_src(coord, component);
488135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
488235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &coord_src_ref);
488335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
488435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
488535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
488635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
488735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Info for implementing texture swizzles.
488835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * The begin_tex_swizzle(), get_tex_swizzle_dst() and end_tex_swizzle()
488935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * functions use this to encapsulate the extra steps needed to perform
489035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * a texture swizzle, or shadow/depth comparisons.
489135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * The shadow/depth comparison is only done here if for the cases where
489235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * there's no VGPU10 opcode (like texture bias lookup w/ shadow compare).
489335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
489435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstruct tex_swizzle_info
489535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
489635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   boolean swizzled;
489735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   boolean shadow_compare;
489835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned unit;
489935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned texture_target;  /**< TGSI_TEXTURE_x */
490035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src;
490135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst;
490235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const struct tgsi_full_dst_register *inst_dst;
490335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const struct tgsi_full_src_register *coord_src;
490435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul};
490535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
490635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
490735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
490835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Do setup for handling texture swizzles or shadow compares.
490935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param unit  the texture unit
491035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param inst  the TGSI texture instruction
491135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param shadow_compare  do shadow/depth comparison?
491235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param swz  returns the swizzle info
491335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
491435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
491535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulbegin_tex_swizzle(struct svga_shader_emitter_v10 *emit,
491635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  unsigned unit,
491735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  const struct tgsi_full_instruction *inst,
491835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  boolean shadow_compare,
491935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                  struct tex_swizzle_info *swz)
492035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
492135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swz->swizzled = (emit->key.tex[unit].swizzle_r != TGSI_SWIZZLE_X ||
492235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                    emit->key.tex[unit].swizzle_g != TGSI_SWIZZLE_Y ||
492335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                    emit->key.tex[unit].swizzle_b != TGSI_SWIZZLE_Z ||
492435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                    emit->key.tex[unit].swizzle_a != TGSI_SWIZZLE_W);
492535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
492635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swz->shadow_compare = shadow_compare;
492735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swz->texture_target = inst->Texture.Texture;
492835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
492935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (swz->swizzled || shadow_compare) {
493035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Allocate temp register for the result of the SAMPLE instruction
493135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * and the source of the MOV/compare/swizzle instructions.
493235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
493335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned tmp = get_temp_index(emit);
493435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swz->tmp_src = make_src_temp_reg(tmp);
493535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swz->tmp_dst = make_dst_temp_reg(tmp);
493635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
493735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      swz->unit = unit;
493835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
493935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swz->inst_dst = &inst->Dst[0];
494035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   swz->coord_src = &inst->Src[0];
494135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
494235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
494335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
494435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
494535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Returns the register to put the SAMPLE instruction results into.
494635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * This will either be the original instruction dst reg (if no swizzle
494735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * and no shadow comparison) or a temporary reg if there is a swizzle.
494835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
494935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic const struct tgsi_full_dst_register *
495035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulget_tex_swizzle_dst(const struct tex_swizzle_info *swz)
495135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
495235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return (swz->swizzled || swz->shadow_compare)
495335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      ? &swz->tmp_dst : swz->inst_dst;
495435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
495535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
495635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
495735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
495835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * This emits the MOV instruction that actually implements a texture swizzle
495935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * and/or shadow comparison.
496035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
496135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
496235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulend_tex_swizzle(struct svga_shader_emitter_v10 *emit,
496335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                const struct tex_swizzle_info *swz)
496435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
496535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (swz->shadow_compare) {
496635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Emit extra instructions to compare the fetched texel value against
496735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * a texture coordinate component.  The result of the comparison
496835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * is 0.0 or 1.0.
496935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
497035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register coord_src;
497135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register texel_src =
497235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&swz->tmp_src, TGSI_SWIZZLE_X);
497335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one =
497435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, 1.0f);
497535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* convert gallium comparison func to SVGA comparison func */
497635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      SVGA3dCmpFunc compare_func = emit->key.tex[swz->unit].compare_func + 1;
497735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
497835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(emit->unit == PIPE_SHADER_FRAGMENT);
497935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
498035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      switch (swz->texture_target) {
498135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TEXTURE_SHADOW2D:
498235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TEXTURE_SHADOWRECT:
498335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TEXTURE_SHADOW1D_ARRAY:
498435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         coord_src = scalar_src(swz->coord_src, TGSI_SWIZZLE_Z);
498535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         break;
498635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TEXTURE_SHADOW1D:
498735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         coord_src = scalar_src(swz->coord_src, TGSI_SWIZZLE_Y);
498835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         break;
498935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TEXTURE_SHADOWCUBE:
499035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TEXTURE_SHADOW2D_ARRAY:
499135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         coord_src = scalar_src(swz->coord_src, TGSI_SWIZZLE_W);
499235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         break;
499335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      default:
499435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         assert(!"Unexpected texture target in end_tex_swizzle()");
499535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         coord_src = scalar_src(swz->coord_src, TGSI_SWIZZLE_Z);
499635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
499735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
499835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* COMPARE tmp, coord, texel */
499935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* XXX it would seem that the texel and coord arguments should
500035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * be transposed here, but piglit tests indicate otherwise.
500135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
500235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_comparison(emit, compare_func,
500335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      &swz->tmp_dst, &texel_src, &coord_src);
500435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
500535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* AND dest, tmp, {1.0} */
500635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
500735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_opcode(emit, VGPU10_OPCODE_AND, FALSE);
500835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (swz->swizzled) {
500935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dst_register(emit, &swz->tmp_dst);
501035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
501135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      else {
501235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dst_register(emit, swz->inst_dst);
501335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
501435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &swz->tmp_src);
501535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &one);
501635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
501735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
501835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
501935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (swz->swizzled) {
502035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned swz_r = emit->key.tex[swz->unit].swizzle_r;
502135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned swz_g = emit->key.tex[swz->unit].swizzle_g;
502235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned swz_b = emit->key.tex[swz->unit].swizzle_b;
502335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned swz_a = emit->key.tex[swz->unit].swizzle_a;
502435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned writemask_0 = 0, writemask_1 = 0;
5025dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul      boolean int_tex = is_integer_type(emit->sampler_return_type[swz->unit]);
502635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
502735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Swizzle w/out zero/one terms */
502835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register src_swizzled =
502935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         swizzle_src(&swz->tmp_src,
5030fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     swz_r < PIPE_SWIZZLE_0 ? swz_r : PIPE_SWIZZLE_X,
5031fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     swz_g < PIPE_SWIZZLE_0 ? swz_g : PIPE_SWIZZLE_Y,
5032fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     swz_b < PIPE_SWIZZLE_0 ? swz_b : PIPE_SWIZZLE_Z,
5033fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     swz_a < PIPE_SWIZZLE_0 ? swz_a : PIPE_SWIZZLE_W);
503435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
503535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV dst, color(tmp).<swizzle> */
503635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
503735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           swz->inst_dst, &src_swizzled, FALSE);
503835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
503935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* handle swizzle zero terms */
5040fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák      writemask_0 = (((swz_r == PIPE_SWIZZLE_0) << 0) |
5041fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     ((swz_g == PIPE_SWIZZLE_0) << 1) |
5042fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     ((swz_b == PIPE_SWIZZLE_0) << 2) |
5043fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     ((swz_a == PIPE_SWIZZLE_0) << 3));
504435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
504535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (writemask_0) {
504635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         struct tgsi_full_src_register zero = int_tex ?
504735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            make_immediate_reg_int(emit, 0) :
504835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            make_immediate_reg_float(emit, 0.0f);
504935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         struct tgsi_full_dst_register dst =
505035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            writemask_dst(swz->inst_dst, writemask_0);
505135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
505235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* MOV dst.writemask_0, {0,0,0,0} */
505335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
505435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                              &dst, &zero, FALSE);
505535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
505635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
505735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* handle swizzle one terms */
5058fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák      writemask_1 = (((swz_r == PIPE_SWIZZLE_1) << 0) |
5059fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     ((swz_g == PIPE_SWIZZLE_1) << 1) |
5060fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     ((swz_b == PIPE_SWIZZLE_1) << 2) |
5061fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák                     ((swz_a == PIPE_SWIZZLE_1) << 3));
506235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
506335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (writemask_1) {
506435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         struct tgsi_full_src_register one = int_tex ?
506535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            make_immediate_reg_int(emit, 1) :
506635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            make_immediate_reg_float(emit, 1.0f);
506735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         struct tgsi_full_dst_register dst =
506835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            writemask_dst(swz->inst_dst, writemask_1);
506935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
507035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* MOV dst.writemask_1, {1,1,1,1} */
507135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst, &one, FALSE);
507235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
507335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
507435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
507535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
507635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
507735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
507835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_SAMPLE instruction.
507935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
508035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
508135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_sample(struct svga_shader_emitter_v10 *emit,
508235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            const struct tgsi_full_instruction *inst)
508335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
508435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned resource_unit = inst->Src[1].Register.Index;
508535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned sampler_unit = inst->Src[2].Register.Index;
508635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register coord;
508735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   int offsets[3];
508835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tex_swizzle_info swz_info;
508935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
509035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_tex_swizzle(emit, sampler_unit, inst, FALSE, &swz_info);
509135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
509235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   get_texel_offsets(emit, inst, offsets);
509335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
509435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   coord = setup_texcoord(emit, resource_unit, &inst->Src[0]);
509535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
509635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* SAMPLE dst, coord(s0), resource, sampler */
509735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
509835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
509935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sample_opcode(emit, VGPU10_OPCODE_SAMPLE,
510035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      inst->Instruction.Saturate, offsets);
510135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
510235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &coord);
510335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_resource_register(emit, resource_unit);
510435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sampler_register(emit, sampler_unit);
510535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
510635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
510735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_tex_swizzle(emit, &swz_info);
510835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
510935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
511035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
511135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
511235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
511335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
511435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
511535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
511635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Check if a texture instruction is valid.
511735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * An example of an invalid texture instruction is doing shadow comparison
511835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * with an integer-valued texture.
511935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * If we detect an invalid texture instruction, we replace it with:
512035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *   MOV dst, {1,1,1,1};
512135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \return TRUE if valid, FALSE if invalid.
512235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
512335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
512435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulis_valid_tex_instruction(struct svga_shader_emitter_v10 *emit,
512535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                         const struct tgsi_full_instruction *inst)
512635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
512735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned unit = inst->Src[1].Register.Index;
512835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned target = inst->Texture.Texture;
512935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   boolean valid = TRUE;
513035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
513135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (tgsi_is_shadow_target(target) &&
5132dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul       is_integer_type(emit->sampler_return_type[unit])) {
513335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("Invalid SAMPLE_C with an integer texture!\n");
513435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      valid = FALSE;
513535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
513635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* XXX might check for other conditions in the future here */
513735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
513835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!valid) {
513935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* emit a MOV dst, {1,1,1,1} instruction. */
514035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
514135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
514235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_opcode(emit, VGPU10_OPCODE_MOV, FALSE);
514335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, &inst->Dst[0]);
514435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &one);
514535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
514635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
514735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
514835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return valid;
514935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
515035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
515135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
515235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
515335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_TEX (simple texture lookup)
515435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
515535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
515635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_tex(struct svga_shader_emitter_v10 *emit,
515735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
515835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
515935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const uint unit = inst->Src[1].Register.Index;
516035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned target = inst->Texture.Texture;
516135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned opcode;
516235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register coord;
516335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   int offsets[3];
516435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tex_swizzle_info swz_info;
516535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
516635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* check that the sampler returns a float */
516735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!is_valid_tex_instruction(emit, inst))
516835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
516935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
517035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_tex_swizzle(emit, unit, inst, FALSE, &swz_info);
517135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
517235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   get_texel_offsets(emit, inst, offsets);
517335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
517435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   coord = setup_texcoord(emit, unit, &inst->Src[0]);
517535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
517635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* SAMPLE dst, coord(s0), resource, sampler */
517735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
517835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
517935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (tgsi_is_shadow_target(target))
518035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode = VGPU10_OPCODE_SAMPLE_C;
518135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else
518235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode = VGPU10_OPCODE_SAMPLE;
518335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
518435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sample_opcode(emit, opcode, inst->Instruction.Saturate, offsets);
518535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
518635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &coord);
518735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_resource_register(emit, unit);
518835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sampler_register(emit, unit);
518935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (opcode == VGPU10_OPCODE_SAMPLE_C) {
519035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_tex_compare_refcoord(emit, target, &coord);
519135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
519235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
519335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
519435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_tex_swizzle(emit, &swz_info);
519535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
519635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
519735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
519835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
519935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
520035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
520135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
520235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
520335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_TXP (projective texture)
520435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
520535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
520635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_txp(struct svga_shader_emitter_v10 *emit,
520735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
520835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
520935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const uint unit = inst->Src[1].Register.Index;
521035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned target = inst->Texture.Texture;
521135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned opcode;
521235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   int offsets[3];
521335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
521435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
521535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
521635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register src0_wwww =
521735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_W);
521835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register coord;
521935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tex_swizzle_info swz_info;
522035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
522135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* check that the sampler returns a float */
522235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!is_valid_tex_instruction(emit, inst))
522335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
522435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
522535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_tex_swizzle(emit, unit, inst, FALSE, &swz_info);
522635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
522735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   get_texel_offsets(emit, inst, offsets);
522835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
522935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   coord = setup_texcoord(emit, unit, &inst->Src[0]);
523035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
523135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* DIV tmp, coord, coord.wwww */
523235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op2(emit, VGPU10_OPCODE_DIV, &tmp_dst,
523335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        &coord, &src0_wwww, FALSE);
523435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
523535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* SAMPLE dst, coord(tmp), resource, sampler */
523635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
523735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
523835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (tgsi_is_shadow_target(target))
523935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode = VGPU10_OPCODE_SAMPLE_C;
524035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else
524135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode = VGPU10_OPCODE_SAMPLE;
524235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
524335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sample_opcode(emit, opcode, inst->Instruction.Saturate, offsets);
524435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
524535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &tmp_src);  /* projected coord */
524635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_resource_register(emit, unit);
524735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sampler_register(emit, unit);
524835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (opcode == VGPU10_OPCODE_SAMPLE_C) {
524935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_tex_compare_refcoord(emit, target, &tmp_src);
525035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
525135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
525235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
525335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_tex_swizzle(emit, &swz_info);
525435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
525535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
525635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
525735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
525835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
525935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
526035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
526135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/*
526235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_XPD instruction.
526335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
526435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
526535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_xpd(struct svga_shader_emitter_v10 *emit,
526635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
526735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
526835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst.x = src0.y * src1.z - src1.y * src0.z
526935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.y = src0.z * src1.x - src1.z * src0.x
527035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.z = src0.x * src1.y - src1.x * src0.y
527135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * dst.w = 1
527235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
527335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s0_xxxx =
527435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
527535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s0_yyyy =
527635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_Y);
527735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s0_zzzz =
527835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[0], TGSI_SWIZZLE_Z);
527935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
528035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s1_xxxx =
528135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[1], TGSI_SWIZZLE_X);
528235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s1_yyyy =
528335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[1], TGSI_SWIZZLE_Y);
528435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register s1_zzzz =
528535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&inst->Src[1], TGSI_SWIZZLE_Z);
528635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
528735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp1 = get_temp_index(emit);
528835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp1_src = make_src_temp_reg(tmp1);
528935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp1_dst = make_dst_temp_reg(tmp1);
529035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
529135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp2 = get_temp_index(emit);
529235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp2_src = make_src_temp_reg(tmp2);
529335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp2_dst = make_dst_temp_reg(tmp2);
529435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register neg_tmp2_src = negate_src(&tmp2_src);
529535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
529635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp3 = get_temp_index(emit);
529735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp3_src = make_src_temp_reg(tmp3);
529835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp3_dst = make_dst_temp_reg(tmp3);
529935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp3_dst_x =
530035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&tmp3_dst, TGSI_WRITEMASK_X);
530135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp3_dst_y =
530235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&tmp3_dst, TGSI_WRITEMASK_Y);
530335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp3_dst_z =
530435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&tmp3_dst, TGSI_WRITEMASK_Z);
530535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp3_dst_w =
530635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      writemask_dst(&tmp3_dst, TGSI_WRITEMASK_W);
530735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
530835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Note: we put all the intermediate computations into tmp3 in case
530935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * the XPD dest register is that same as one of the src regs (in which
531035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * case we could clobber a src reg before we're done with it) .
531135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *
531235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Note: we could get by with just one temp register instead of three
531335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * since we're doing scalar operations and there's enough room in one
531435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * temp for everything.
531535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
531635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
531735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MUL tmp1, src0.y, src1.z */
531835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MUL tmp2, src1.y, src0.z */
531935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* ADD tmp3.x, tmp1, -tmp2 */
532035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
532135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp1_dst,
532235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &s0_yyyy, &s1_zzzz, FALSE);
532335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp2_dst,
532435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &s1_yyyy, &s0_zzzz, FALSE);
532535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &tmp3_dst_x,
532635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp1_src, &neg_tmp2_src, FALSE);
532735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
532835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
532935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MUL tmp1, src0.z, src1.x */
533035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MUL tmp2, src1.z, src0.x */
533135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* ADD tmp3.y, tmp1, -tmp2 */
533235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
533335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp1_dst, &s0_zzzz,
533435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &s1_xxxx, FALSE);
533535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp2_dst, &s1_zzzz,
533635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &s0_xxxx, FALSE);
533735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &tmp3_dst_y,
533835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp1_src, &neg_tmp2_src, FALSE);
533935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
534035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
534135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MUL tmp1, src0.x, src1.y */
534235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MUL tmp2, src1.x, src0.y */
534335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* ADD tmp3.z, tmp1, -tmp2 */
534435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
534535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp1_dst, &s0_xxxx,
534635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &s1_yyyy, FALSE);
534735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp2_dst, &s1_xxxx,
534835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &s0_yyyy, FALSE);
534935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &tmp3_dst_z,
535035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp1_src, &neg_tmp2_src, FALSE);
535135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
535235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
535335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV tmp3.w, 1.0 */
535435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
535535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one =
535635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, 1.0f);
535735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
535835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &tmp3_dst_w, &one, FALSE);
535935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
536035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
536135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* MOV dst, tmp3 */
536235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &tmp3_src,
536335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        inst->Instruction.Saturate);
536435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
536535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
536635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
536735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
536835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
536935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
537035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
537135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
537235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
537335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_TXD (explicit derivatives)
537435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
537535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
537635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_txd(struct svga_shader_emitter_v10 *emit,
537735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
537835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
537935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const uint unit = inst->Src[3].Register.Index;
538035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned target = inst->Texture.Texture;
538135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   int offsets[3];
538235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register coord;
538335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tex_swizzle_info swz_info;
538435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
538535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_tex_swizzle(emit, unit, inst, tgsi_is_shadow_target(target),
538635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     &swz_info);
538735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
538835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   get_texel_offsets(emit, inst, offsets);
538935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
539035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   coord = setup_texcoord(emit, unit, &inst->Src[0]);
539135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
539235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* SAMPLE_D dst, coord(s0), resource, sampler, Xderiv(s1), Yderiv(s2) */
539335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
539435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sample_opcode(emit, VGPU10_OPCODE_SAMPLE_D,
539535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      inst->Instruction.Saturate, offsets);
539635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
539735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &coord);
539835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_resource_register(emit, unit);
539935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sampler_register(emit, unit);
540035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &inst->Src[1]);  /* Xderiv */
540135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &inst->Src[2]);  /* Yderiv */
540235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
540335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
540435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_tex_swizzle(emit, &swz_info);
540535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
540635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
540735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
540835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
540935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
541035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
541135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
541235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
541335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_TXF (texel fetch)
541435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
541535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
541635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_txf(struct svga_shader_emitter_v10 *emit,
541735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
541835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
541935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const uint unit = inst->Src[1].Register.Index;
5420b283c763425983480f85ed5b92ac8a984b6aa942Brian Paul   const boolean msaa = tgsi_is_msaa_target(inst->Texture.Texture);
542135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   int offsets[3];
542235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tex_swizzle_info swz_info;
542335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
542435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_tex_swizzle(emit, unit, inst, FALSE, &swz_info);
542535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
542635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   get_texel_offsets(emit, inst, offsets);
542735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
542835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (msaa) {
542935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Fetch one sample from an MSAA texture */
543035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register sampleIndex =
543135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&inst->Src[0], TGSI_SWIZZLE_W);
543235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* LD_MS dst, coord(s0), resource, sampleIndex */
543335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
543435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_sample_opcode(emit, VGPU10_OPCODE_LD_MS,
543535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                         inst->Instruction.Saturate, offsets);
543635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
543735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &inst->Src[0]);
543835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_resource_register(emit, unit);
543935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &sampleIndex);
544035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
544135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
544235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
544335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Fetch one texel specified by integer coordinate */
544435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* LD dst, coord(s0), resource */
544535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
544635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_sample_opcode(emit, VGPU10_OPCODE_LD,
544735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                         inst->Instruction.Saturate, offsets);
544835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
544935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &inst->Src[0]);
545035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_resource_register(emit, unit);
545135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
545235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
545335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
545435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_tex_swizzle(emit, &swz_info);
545535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
545635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
545735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
545835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
545935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
546035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
546135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
546235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
546335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_TXL (explicit LOD) or TGSI_OPCODE_TXB (LOD bias)
546435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * or TGSI_OPCODE_TXB2 (for cube shadow maps).
546535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
546635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
546735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_txl_txb(struct svga_shader_emitter_v10 *emit,
546835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul             const struct tgsi_full_instruction *inst)
546935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
547035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned target = inst->Texture.Texture;
547135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned opcode, unit;
547235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   int offsets[3];
547335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register coord, lod_bias;
547435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tex_swizzle_info swz_info;
547535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
547635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(inst->Instruction.Opcode == TGSI_OPCODE_TXL ||
547735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          inst->Instruction.Opcode == TGSI_OPCODE_TXB ||
547835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          inst->Instruction.Opcode == TGSI_OPCODE_TXB2);
547935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
548035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Instruction.Opcode == TGSI_OPCODE_TXB2) {
548135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      lod_bias = scalar_src(&inst->Src[1], TGSI_SWIZZLE_X);
548235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unit = inst->Src[2].Register.Index;
548335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
548435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
548535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      lod_bias = scalar_src(&inst->Src[0], TGSI_SWIZZLE_W);
548635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unit = inst->Src[1].Register.Index;
548735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
548835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
548935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_tex_swizzle(emit, unit, inst, tgsi_is_shadow_target(target),
549035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     &swz_info);
549135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
549235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   get_texel_offsets(emit, inst, offsets);
549335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
549435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   coord = setup_texcoord(emit, unit, &inst->Src[0]);
549535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
549635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* SAMPLE_L/B dst, coord(s0), resource, sampler, lod(s3) */
549735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
549835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (inst->Instruction.Opcode == TGSI_OPCODE_TXL) {
549935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode = VGPU10_OPCODE_SAMPLE_L;
550035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
550135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else {
550235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      opcode = VGPU10_OPCODE_SAMPLE_B;
550335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
550435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sample_opcode(emit, opcode, inst->Instruction.Saturate, offsets);
550535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
550635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &coord);
550735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_resource_register(emit, unit);
550835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sampler_register(emit, unit);
550935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &lod_bias);
551035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
551135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
551235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_tex_swizzle(emit, &swz_info);
551335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
551435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
551535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
551635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
551735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
551835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
551935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
552035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
552135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit code for TGSI_OPCODE_TXQ (texture query) instruction.
552235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
552335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
552435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_txq(struct svga_shader_emitter_v10 *emit,
552535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_full_instruction *inst)
552635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
552735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const uint unit = inst->Src[1].Register.Index;
552835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
5529dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   if (emit->sampler_target[unit] == TGSI_TEXTURE_BUFFER) {
553035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* RESINFO does not support querying texture buffers, so we instead
553135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * store texture buffer sizes in shader constants, then copy them to
553235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * implement TXQ instead of emitting RESINFO.
553335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * MOV dst, const[texture_buffer_size_index[unit]]
553435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
553535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register size_src =
553635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_src_const_reg(emit->texture_buffer_size_index[unit]);
553735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &size_src,
553835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           FALSE);
553935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } else {
554035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* RESINFO dst, srcMipLevel, resource */
554135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
554235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_opcode_resinfo(emit, VGPU10_RESINFO_RETURN_UINT);
554335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, &inst->Dst[0]);
554435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &inst->Src[0]);
554535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_resource_register(emit, unit);
554635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
554735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
554835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
554935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
555035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
555135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
555235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
555335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
555435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
555535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
555635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit a simple instruction (like ADD, MUL, MIN, etc).
555735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
555835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
555935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_simple(struct svga_shader_emitter_v10 *emit,
556035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            const struct tgsi_full_instruction *inst)
556135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
556235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned opcode = inst->Instruction.Opcode;
556335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const struct tgsi_opcode_info *op = tgsi_get_opcode_info(opcode);
556435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
556535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
556635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
556735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, translate_opcode(inst->Instruction.Opcode),
556835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               inst->Instruction.Saturate);
556935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < op->num_dst; i++) {
557035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, &inst->Dst[i]);
557135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
557235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < op->num_src; i++) {
557335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &inst->Src[i]);
557435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
557535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
557635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
557735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
557835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
557935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
558035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
558135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
55821082735bb69e9f64cb3991a52f0e270902917855Brian Paul * We only special case the MOV instruction to try to detect constant
55831082735bb69e9f64cb3991a52f0e270902917855Brian Paul * color writes in the fragment shader.
55841082735bb69e9f64cb3991a52f0e270902917855Brian Paul */
55851082735bb69e9f64cb3991a52f0e270902917855Brian Paulstatic boolean
55861082735bb69e9f64cb3991a52f0e270902917855Brian Paulemit_mov(struct svga_shader_emitter_v10 *emit,
55871082735bb69e9f64cb3991a52f0e270902917855Brian Paul         const struct tgsi_full_instruction *inst)
55881082735bb69e9f64cb3991a52f0e270902917855Brian Paul{
55891082735bb69e9f64cb3991a52f0e270902917855Brian Paul   const struct tgsi_full_src_register *src = &inst->Src[0];
55901082735bb69e9f64cb3991a52f0e270902917855Brian Paul   const struct tgsi_full_dst_register *dst = &inst->Dst[0];
55911082735bb69e9f64cb3991a52f0e270902917855Brian Paul
55921082735bb69e9f64cb3991a52f0e270902917855Brian Paul   if (emit->unit == PIPE_SHADER_FRAGMENT &&
55931082735bb69e9f64cb3991a52f0e270902917855Brian Paul       dst->Register.File == TGSI_FILE_OUTPUT &&
55941082735bb69e9f64cb3991a52f0e270902917855Brian Paul       dst->Register.Index == 0 &&
55951082735bb69e9f64cb3991a52f0e270902917855Brian Paul       src->Register.File == TGSI_FILE_CONSTANT &&
55961082735bb69e9f64cb3991a52f0e270902917855Brian Paul       !src->Register.Indirect) {
55971082735bb69e9f64cb3991a52f0e270902917855Brian Paul      emit->constant_color_output = TRUE;
55981082735bb69e9f64cb3991a52f0e270902917855Brian Paul   }
55991082735bb69e9f64cb3991a52f0e270902917855Brian Paul
56001082735bb69e9f64cb3991a52f0e270902917855Brian Paul   return emit_simple(emit, inst);
56011082735bb69e9f64cb3991a52f0e270902917855Brian Paul}
56021082735bb69e9f64cb3991a52f0e270902917855Brian Paul
56031082735bb69e9f64cb3991a52f0e270902917855Brian Paul
56041082735bb69e9f64cb3991a52f0e270902917855Brian Paul/**
560535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit a simple VGPU10 instruction which writes to multiple dest registers,
560635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * where TGSI only uses one dest register.
560735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
560835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
560935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_simple_1dst(struct svga_shader_emitter_v10 *emit,
561035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                 const struct tgsi_full_instruction *inst,
561135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                 unsigned dst_count,
561235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                 unsigned dst_index)
561335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
561435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned opcode = inst->Instruction.Opcode;
561535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const struct tgsi_opcode_info *op = tgsi_get_opcode_info(opcode);
561635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
561735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
561835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
561935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, translate_opcode(inst->Instruction.Opcode),
562035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               inst->Instruction.Saturate);
562135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
562235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < dst_count; i++) {
562335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (i == dst_index) {
562435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_dst_register(emit, &inst->Dst[0]);
562535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      } else {
562635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_null_dst_register(emit);
562735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
562835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
562935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
563035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < op->num_src; i++) {
563135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &inst->Src[i]);
563235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
563335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
563435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
563535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
563635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
563735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
563835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
563935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
564035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate a single TGSI instruction to VGPU10.
564135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
564235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
564335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vgpu10_instruction(struct svga_shader_emitter_v10 *emit,
564435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        unsigned inst_number,
564535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                        const struct tgsi_full_instruction *inst)
564635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
564735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned opcode = inst->Instruction.Opcode;
564835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
564935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   switch (opcode) {
565035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ADD:
565135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_AND:
565235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_BGNLOOP:
565335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_BRK:
565435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_CEIL:
565535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_CONT:
565635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DDX:
565735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DDY:
565835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DIV:
565935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DP2:
566035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DP3:
566135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DP4:
566235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ELSE:
566335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ENDIF:
566435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ENDLOOP:
566535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ENDSUB:
566635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_F2I:
566735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_F2U:
566835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FLR:
566935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FRC:
567035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FSEQ:
567135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FSGE:
567235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FSLT:
567335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_FSNE:
567435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_I2F:
567535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IMAX:
567635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IMIN:
567735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_INEG:
567835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ISGE:
567935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ISHR:
568035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ISLT:
568135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MAD:
568235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MAX:
568335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MIN:
568435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MUL:
568535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_NOP:
568635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_NOT:
568735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_OR:
568835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_RET:
568935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UADD:
569035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USEQ:
569135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USGE:
569235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USLT:
569335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMIN:
569435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMAD:
569535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMAX:
569635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ROUND:
569735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SQRT:
569835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SHL:
569935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TRUNC:
570035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_U2F:
570135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UCMP:
570235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USHR:
570335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_USNE:
570435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_XOR:
570535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* simple instructions */
570635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_simple(emit, inst);
570735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
57081082735bb69e9f64cb3991a52f0e270902917855Brian Paul   case TGSI_OPCODE_MOV:
57091082735bb69e9f64cb3991a52f0e270902917855Brian Paul      return emit_mov(emit, inst);
571035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_EMIT:
571135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_vertex(emit, inst);
571235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ENDPRIM:
571335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_endprim(emit, inst);
571435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IABS:
571535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_iabs(emit, inst);
571635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ARL:
571735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* fall-through */
571835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UARL:
571935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_arl_uarl(emit, inst);
572035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_BGNSUB:
572135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* no-op */
572235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return TRUE;
572335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_CAL:
572435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_cal(emit, inst);
572535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_CMP:
572635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_cmp(emit, inst);
572735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_COS:
572835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_sincos(emit, inst);
572935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DP2A:
573035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_dp2a(emit, inst);
573135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DPH:
573235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_dph(emit, inst);
573335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_DST:
573435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_dst(emit, inst);
573535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_EX2:
573635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_ex2(emit, inst);
573735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_EXP:
573835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_exp(emit, inst);
573935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IF:
574035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_if(emit, inst);
574135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_KILL:
574235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_kill(emit, inst);
574335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_KILL_IF:
574435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_kill_if(emit, inst);
574535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_LG2:
574635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_lg2(emit, inst);
574735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_LIT:
574835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_lit(emit, inst);
574935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_LOG:
575035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_log(emit, inst);
575135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_LRP:
575235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_lrp(emit, inst);
575335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_POW:
575435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_pow(emit, inst);
575535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_RCP:
575635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_rcp(emit, inst);
575735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_RSQ:
575835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_rsq(emit, inst);
575935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SAMPLE:
576035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_sample(emit, inst);
576135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SCS:
576235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_scs(emit, inst);
576335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SEQ:
576435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_seq(emit, inst);
576535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SGE:
576635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_sge(emit, inst);
576735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SGT:
576835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_sgt(emit, inst);
576935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SIN:
577035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_sincos(emit, inst);
577135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SLE:
577235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_sle(emit, inst);
577335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SLT:
577435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_slt(emit, inst);
577535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SNE:
577635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_sne(emit, inst);
577735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_SSG:
577835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_ssg(emit, inst);
577935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_ISSG:
578035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_issg(emit, inst);
578135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TEX:
578235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_tex(emit, inst);
578335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TXP:
578435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_txp(emit, inst);
578535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TXB:
578635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TXB2:
578735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TXL:
578835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_txl_txb(emit, inst);
578935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TXD:
579035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_txd(emit, inst);
579135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TXF:
579235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_txf(emit, inst);
579335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_TXQ:
579435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_txq(emit, inst);
579535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UIF:
579635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_if(emit, inst);
579735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_XPD:
579835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_xpd(emit, inst);
579935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMUL_HI:
580035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IMUL_HI:
580135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UDIV:
580235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_IDIV:
580335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* These cases use only the FIRST of two destination registers */
580435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_simple_1dst(emit, inst, 2, 0);
580535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMUL:
580635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_UMOD:
580735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_MOD:
580835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* These cases use only the SECOND of two destination registers */
580935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_simple_1dst(emit, inst, 2, 1);
581035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   case TGSI_OPCODE_END:
581135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (!emit_post_helpers(emit))
581235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         return FALSE;
581335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return emit_simple(emit, inst);
581435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
581535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   default:
581635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("Unimplemented tgsi instruction %s\n",
581735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   tgsi_get_opcode_name(opcode));
581835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
581935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
582035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
582135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
582235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
582335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
582435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
582535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
582635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the extra instructions to adjust the vertex position.
582735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * There are two possible adjustments:
582835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * 1. Converting from Gallium to VGPU10 coordinate space by applying the
582935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *    "prescale" and "pretranslate" values.
583035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * 2. Undoing the viewport transformation when we use the swtnl/draw path.
583135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param vs_pos_tmp_index  which temporary register contains the vertex pos.
583235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
583335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
583435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vpos_instructions(struct svga_shader_emitter_v10 *emit,
583535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                       unsigned vs_pos_tmp_index)
583635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
583735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_pos_src;
583835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register pos_dst;
583935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
584035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Don't bother to emit any extra vertex instructions if vertex position is
584135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * not written out
584235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
584335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->vposition.out_index == INVALID_INDEX)
584435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return;
584535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
584635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tmp_pos_src = make_src_temp_reg(vs_pos_tmp_index);
584735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   pos_dst = make_dst_output_reg(emit->vposition.out_index);
584835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
584935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* If non-adjusted vertex position register index
585035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * is valid, copy the vertex position from the temporary
585135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * vertex position register before it is modified by the
585235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * prescale computation.
585335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
585435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->vposition.so_index != INVALID_INDEX) {
585535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register pos_so_dst =
585635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_dst_output_reg(emit->vposition.so_index);
585735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
585835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV pos_so, tmp_pos */
585935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &pos_so_dst,
586035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_pos_src, FALSE);
586135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
586235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
586335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->vposition.need_prescale) {
586435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* This code adjusts the vertex position to match the VGPU10 convention.
586535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * If p is the position computed by the shader (usually by applying the
586635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * modelview and projection matrices), the new position q is computed by:
586735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       *
586835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * q.x = p.w * trans.x + p.x * scale.x
586935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * q.y = p.w * trans.y + p.y * scale.y
587035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * q.z = p.w * trans.z + p.z * scale.z;
587135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * q.w = p.w * trans.w + p.w;
587235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
587335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register tmp_pos_src_w =
587435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&tmp_pos_src, TGSI_SWIZZLE_W);
587535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp_pos_dst =
587635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_dst_temp_reg(vs_pos_tmp_index);
587735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp_pos_dst_xyz =
587835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&tmp_pos_dst, TGSI_WRITEMASK_XYZ);
587935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
588035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register prescale_scale =
588135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_src_const_reg(emit->vposition.prescale_scale_index);
588235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register prescale_trans =
588335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_src_const_reg(emit->vposition.prescale_trans_index);
588435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
588535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MUL tmp_pos.xyz, tmp_pos, prescale.scale */
588635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_pos_dst_xyz,
588735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_pos_src, &prescale_scale, FALSE);
588835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
588935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MAD pos, tmp_pos.wwww, prescale.trans, tmp_pos */
589035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op3(emit, VGPU10_OPCODE_MAD, &pos_dst, &tmp_pos_src_w,
589135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &prescale_trans, &tmp_pos_src, FALSE);
589235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
589335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (emit->key.vs.undo_viewport) {
589435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* This code computes the final vertex position from the temporary
589535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * vertex position by undoing the viewport transformation and the
589635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * divide-by-W operation (we convert window coords back to clip coords).
589735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * This is needed when we use the 'draw' module for fallbacks.
589835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * If p is the temp pos in window coords, then the NDC coord q is:
589935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       *   q.x = (p.x - vp.x_trans) / vp.x_scale * p.w
590035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       *   q.y = (p.y - vp.y_trans) / vp.y_scale * p.w
590135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       *   q.z = p.z * p.w
590235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       *   q.w = p.w
590335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * CONST[vs_viewport_index] contains:
590435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       *   { 1/vp.x_scale, 1/vp.y_scale, -vp.x_trans, -vp.y_trans }
590535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
590635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp_pos_dst =
590735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_dst_temp_reg(vs_pos_tmp_index);
590835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp_pos_dst_xy =
590935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&tmp_pos_dst, TGSI_WRITEMASK_XY);
591035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register tmp_pos_src_wwww =
591135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         scalar_src(&tmp_pos_src, TGSI_SWIZZLE_W);
591235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
591335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register pos_dst_xyz =
591435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&pos_dst, TGSI_WRITEMASK_XYZ);
591535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register pos_dst_w =
591635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&pos_dst, TGSI_WRITEMASK_W);
591735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
591835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register vp_xyzw =
591935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_src_const_reg(emit->vs.viewport_index);
592035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register vp_zwww =
592135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         swizzle_src(&vp_xyzw, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W,
592235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     TGSI_SWIZZLE_W, TGSI_SWIZZLE_W);
592335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
592435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* ADD tmp_pos.xy, tmp_pos.xy, viewport.zwww */
592535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &tmp_pos_dst_xy,
592635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_pos_src, &vp_zwww, FALSE);
592735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
592835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MUL tmp_pos.xy, tmp_pos.xyzw, viewport.xyzy */
592935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_pos_dst_xy,
593035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_pos_src, &vp_xyzw, FALSE);
593135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
593235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MUL pos.xyz, tmp_pos.xyz, tmp_pos.www */
593335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &pos_dst_xyz,
593435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_pos_src, &tmp_pos_src_wwww, FALSE);
593535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
593635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV pos.w, tmp_pos.w */
593735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &pos_dst_w,
593835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &tmp_pos_src, FALSE);
593935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
594035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (vs_pos_tmp_index != INVALID_INDEX) {
594135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* This code is to handle the case where the temporary vertex
594235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * position register is created when the vertex shader has stream
594335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * output and prescale is disabled because rasterization is to be
594435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * discarded.
594535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
594635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register pos_dst =
594735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_dst_output_reg(emit->vposition.out_index);
594835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
594935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV pos, tmp_pos */
595035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
595135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_opcode(emit, VGPU10_OPCODE_MOV, FALSE);
595235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, &pos_dst);
595335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &tmp_pos_src);
595435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
595535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
595635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
595735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
595835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
595935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_clipping_instructions(struct svga_shader_emitter_v10 *emit)
596035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
596135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->clip_mode == CLIP_DISTANCE) {
596235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Copy from copy distance temporary to CLIPDIST & the shadow copy */
596335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_clip_distance_instructions(emit);
596435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
596535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } else if (emit->clip_mode == CLIP_VERTEX) {
596635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Convert TGSI CLIPVERTEX to CLIPDIST */
596735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_clip_vertex_instructions(emit);
596835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
596935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
597035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /**
597135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Emit vertex position and take care of legacy user planes only if
597235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * there is a valid vertex position register index.
597335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * This is to take care of the case
597435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * where the shader doesn't output vertex position. Then in
597535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * this case, don't bother to emit more vertex instructions.
597635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
597735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->vposition.out_index == INVALID_INDEX)
597835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return;
597935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
598035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /**
598135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Emit per-vertex clipping instructions for legacy user defined clip planes.
598235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * NOTE: we must emit the clip distance instructions before the
598335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * emit_vpos_instructions() call since the later function will change
598435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * the TEMP[vs_pos_tmp_index] value.
598535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
598635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->clip_mode == CLIP_LEGACY) {
598735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Emit CLIPDIST for legacy user defined clip planes */
598835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_clip_distance_from_vpos(emit, emit->vposition.tmp_index);
598935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
599035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
599135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
599235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
599335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
599435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit extra per-vertex instructions.  This includes clip-coordinate
599535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * space conversion and computing clip distances.  This is called for
599635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * each GS emit-vertex instruction and at the end of VS translation.
599735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
599835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
599935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vertex_instructions(struct svga_shader_emitter_v10 *emit)
600035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
600135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned vs_pos_tmp_index = emit->vposition.tmp_index;
600235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
600335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Emit clipping instructions based on clipping mode */
600435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_clipping_instructions(emit);
600535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
600635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /**
600735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Reset the temporary vertex position register index
600835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * so that emit_dst_register() will use the real vertex position output
600935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
601035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->vposition.tmp_index = INVALID_INDEX;
601135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
601235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Emit vertex position instructions */
601335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_vpos_instructions(emit, vs_pos_tmp_index);
601435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
601535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Restore original vposition.tmp_index value for the next GS vertex.
601635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * It doesn't matter for VS.
601735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
601835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->vposition.tmp_index = vs_pos_tmp_index;
601935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
602035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
602135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
602235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate the TGSI_OPCODE_EMIT GS instruction.
602335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
602435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
602535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vertex(struct svga_shader_emitter_v10 *emit,
602635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            const struct tgsi_full_instruction *inst)
602735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
602835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned ret = TRUE;
602935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
603035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_GEOMETRY);
603135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
603235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_vertex_instructions(emit);
603335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
603435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* We can't use emit_simple() because the TGSI instruction has one
603535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * operand (vertex stream number) which we must ignore for VGPU10.
603635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
603735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
603835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_opcode(emit, VGPU10_OPCODE_EMIT, FALSE);
603935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
604035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
604135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return ret;
604235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
604335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
604435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
604535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
604635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the extra code to convert from VGPU10's boolean front-face
604735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * register to TGSI's signed front-face register.
604835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *
604935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * TODO: Make temporary front-face register a scalar.
605035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
605135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
605235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_frontface_instructions(struct svga_shader_emitter_v10 *emit)
605335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
605435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_FRAGMENT);
605535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
605635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->fs.face_input_index != INVALID_INDEX) {
605735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* convert vgpu10 boolean face register to gallium +/-1 value */
605835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp_dst =
605935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_dst_temp_reg(emit->fs.face_tmp_index);
606035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one =
606135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, 1.0f);
606235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register neg_one =
606335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, -1.0f);
606435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
606535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOVC face_tmp, IS_FRONT_FACE.x, 1.0, -1.0 */
606635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
606735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_opcode(emit, VGPU10_OPCODE_MOVC, FALSE);
606835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, &tmp_dst);
606935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_face_register(emit);
607035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &one);
607135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &neg_one);
607235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
607335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
607435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
607535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
607635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
607735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
607835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the extra code to convert from VGPU10's fragcoord.w value to 1/w.
607935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
608035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
608135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_fragcoord_instructions(struct svga_shader_emitter_v10 *emit)
608235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
608335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_FRAGMENT);
608435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
608535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->fs.fragcoord_input_index != INVALID_INDEX) {
608635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp_dst =
608735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_dst_temp_reg(emit->fs.fragcoord_tmp_index);
608835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp_dst_xyz =
608935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&tmp_dst, TGSI_WRITEMASK_XYZ);
609035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register tmp_dst_w =
609135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         writemask_dst(&tmp_dst, TGSI_WRITEMASK_W);
609235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one =
609335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, 1.0f);
609435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register fragcoord =
609535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_src_reg(TGSI_FILE_INPUT, emit->fs.fragcoord_input_index);
609635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
609735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* save the input index */
609835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned fragcoord_input_index = emit->fs.fragcoord_input_index;
609935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* set to invalid to prevent substitution in emit_src_register() */
610035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->fs.fragcoord_input_index = INVALID_INDEX;
610135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
610235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV fragcoord_tmp.xyz, fragcoord.xyz */
610335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
610435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_opcode(emit, VGPU10_OPCODE_MOV, FALSE);
610535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, &tmp_dst_xyz);
610635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &fragcoord);
610735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
610835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
610935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* DIV fragcoord_tmp.w, 1.0, fragcoord.w */
611035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      begin_emit_instruction(emit);
611135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_opcode(emit, VGPU10_OPCODE_DIV, FALSE);
611235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_dst_register(emit, &tmp_dst_w);
611335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &one);
611435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_src_register(emit, &fragcoord);
611535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      end_emit_instruction(emit);
611635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
611735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* restore saved value */
611835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->fs.fragcoord_input_index = fragcoord_input_index;
611935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
612035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
612135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
612235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
612335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
612435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit extra instructions to adjust VS inputs/attributes.  This can
612535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * mean casting a vertex attribute from int to float or setting the
612635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * W component to 1, or both.
612735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
612835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
612935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vertex_attrib_instructions(struct svga_shader_emitter_v10 *emit)
613035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
613135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned save_w_1_mask = emit->key.vs.adjust_attrib_w_1;
613235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned save_itof_mask = emit->key.vs.adjust_attrib_itof;
613335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned save_utof_mask = emit->key.vs.adjust_attrib_utof;
613435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned save_is_bgra_mask = emit->key.vs.attrib_is_bgra;
613535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned save_puint_to_snorm_mask = emit->key.vs.attrib_puint_to_snorm;
613635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned save_puint_to_uscaled_mask = emit->key.vs.attrib_puint_to_uscaled;
613735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned save_puint_to_sscaled_mask = emit->key.vs.attrib_puint_to_sscaled;
613835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
613935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned adjust_mask = (save_w_1_mask |
614035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           save_itof_mask |
614135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           save_utof_mask |
614235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           save_is_bgra_mask |
614335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           save_puint_to_snorm_mask |
614435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           save_puint_to_uscaled_mask |
614535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           save_puint_to_sscaled_mask);
614635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
614735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_VERTEX);
614835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
614935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (adjust_mask) {
615035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one =
615135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_float(emit, 1.0f);
615235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
615335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_src_register one_int =
615435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_immediate_reg_int(emit, 1);
615535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
615635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* We need to turn off these bitmasks while emitting the
615735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * instructions below, then restore them afterward.
615835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
615935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.adjust_attrib_w_1 = 0;
616035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.adjust_attrib_itof = 0;
616135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.adjust_attrib_utof = 0;
616235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.attrib_is_bgra = 0;
616335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.attrib_puint_to_snorm = 0;
616435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.attrib_puint_to_uscaled = 0;
616535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.attrib_puint_to_sscaled = 0;
616635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
616735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      while (adjust_mask) {
616835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned index = u_bit_scan(&adjust_mask);
6169b074a5b02de3dc0e2d0cbb6b9154673153b29525Charmaine Lee
6170b074a5b02de3dc0e2d0cbb6b9154673153b29525Charmaine Lee         /* skip the instruction if this vertex attribute is not being used */
6171b074a5b02de3dc0e2d0cbb6b9154673153b29525Charmaine Lee         if (emit->info.input_usage_mask[index] == 0)
6172b074a5b02de3dc0e2d0cbb6b9154673153b29525Charmaine Lee            continue;
6173b074a5b02de3dc0e2d0cbb6b9154673153b29525Charmaine Lee
617435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         unsigned tmp = emit->vs.adjusted_input[index];
617535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         struct tgsi_full_src_register input_src =
617635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            make_src_reg(TGSI_FILE_INPUT, index);
617735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
617835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
617935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
618035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         struct tgsi_full_dst_register tmp_dst_w =
618135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            writemask_dst(&tmp_dst, TGSI_WRITEMASK_W);
618235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
618335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* ITOF/UTOF/MOV tmp, input[index] */
618435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (save_itof_mask & (1 << index)) {
618535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_instruction_op1(emit, VGPU10_OPCODE_ITOF,
618635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 &tmp_dst, &input_src, FALSE);
618735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
618835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (save_utof_mask & (1 << index)) {
618935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_instruction_op1(emit, VGPU10_OPCODE_UTOF,
619035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 &tmp_dst, &input_src, FALSE);
619135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
619235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (save_puint_to_snorm_mask & (1 << index)) {
619335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_puint_to_snorm(emit, &tmp_dst, &input_src);
619435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
619535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (save_puint_to_uscaled_mask & (1 << index)) {
619635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_puint_to_uscaled(emit, &tmp_dst, &input_src);
619735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
619835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else if (save_puint_to_sscaled_mask & (1 << index)) {
619935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_puint_to_sscaled(emit, &tmp_dst, &input_src);
620035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
620135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         else {
620235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            assert((save_w_1_mask | save_is_bgra_mask) & (1 << index));
620335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
620435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 &tmp_dst, &input_src, FALSE);
620535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
620635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
620735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (save_is_bgra_mask & (1 << index)) {
620835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit_swap_r_b(emit, &tmp_dst, &tmp_src);
620935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
621035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
621135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (save_w_1_mask & (1 << index)) {
621235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* MOV tmp.w, 1.0 */
621335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            if (emit->key.vs.attrib_is_pure_int & (1 << index)) {
621435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
621535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                    &tmp_dst_w, &one_int, FALSE);
621635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            }
621735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            else {
621835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
621935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                    &tmp_dst_w, &one, FALSE);
622035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            }
622135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
622235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
622335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
622435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.adjust_attrib_w_1 = save_w_1_mask;
622535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.adjust_attrib_itof = save_itof_mask;
622635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.adjust_attrib_utof = save_utof_mask;
622735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.attrib_is_bgra = save_is_bgra_mask;
622835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.attrib_puint_to_snorm = save_puint_to_snorm_mask;
622935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.attrib_puint_to_uscaled = save_puint_to_uscaled_mask;
623035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.vs.attrib_puint_to_sscaled = save_puint_to_sscaled_mask;
623135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
623235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
623335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
623435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
623535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
623635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Some common values like 0.0, 1.0, 0.5, etc. are frequently needed
623735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * to implement some instructions.  We pre-allocate those values here
623835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * in the immediate constant buffer.
623935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
624035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
624135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulalloc_common_immediates(struct svga_shader_emitter_v10 *emit)
624235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
624335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned n = 0;
624435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
624535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->common_immediate_pos[n++] =
624635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      alloc_immediate_float4(emit, 0.0f, 1.0f, 0.5f, -1.0f);
624735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
624835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->common_immediate_pos[n++] =
624935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      alloc_immediate_float4(emit, 128.0f, -128.0f, 2.0f, 3.0f);
625035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
625135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->common_immediate_pos[n++] =
625235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      alloc_immediate_int4(emit, 0, 1, 0, -1);
625335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
625435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->key.vs.attrib_puint_to_snorm) {
625535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->common_immediate_pos[n++] =
625635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         alloc_immediate_float4(emit, -2.0f, -2.0f, -2.0f, -1.66666f);
625735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
625835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
625935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->key.vs.attrib_puint_to_uscaled) {
626035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->common_immediate_pos[n++] =
626135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         alloc_immediate_float4(emit, 1023.0f, 3.0f, 0.0f, 0.0f);
626235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
626335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
626435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->key.vs.attrib_puint_to_sscaled) {
626535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->common_immediate_pos[n++] =
626635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         alloc_immediate_int4(emit, 22, 12, 2, 0);
626735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
626835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->common_immediate_pos[n++] =
626935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         alloc_immediate_int4(emit, 22, 30, 0, 0);
627035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
627135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
6272e0184b3995fa308c125ae8e090d2bbdffd495b5fBrian Paul   assert(n <= ARRAY_SIZE(emit->common_immediate_pos));
627335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->num_common_immediates = n;
627435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
627535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
627635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
627735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
627835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit any extra/helper declarations/code that we might need between
627935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * the declaration section and code section.
628035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
628135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
628235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_pre_helpers(struct svga_shader_emitter_v10 *emit)
628335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
628435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Properties */
628535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->unit == PIPE_SHADER_GEOMETRY)
628635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_property_instructions(emit);
628735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
628835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Declare inputs */
628935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!emit_input_declarations(emit))
629035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
629135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
629235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Declare outputs */
629335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!emit_output_declarations(emit))
629435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
629535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
629635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Declare temporary registers */
629735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_temporaries_declaration(emit);
629835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
629935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Declare constant registers */
630035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_constant_declaration(emit);
630135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
630235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Declare samplers and resources */
630335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_sampler_declarations(emit);
630435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_resource_declarations(emit);
630535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
630635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Declare clip distance output registers */
630735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->unit == PIPE_SHADER_VERTEX ||
630835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       emit->unit == PIPE_SHADER_GEOMETRY) {
630935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_clip_distance_declarations(emit);
631035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
631135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
631235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   alloc_common_immediates(emit);
631335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
631435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->unit == PIPE_SHADER_FRAGMENT &&
631535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       emit->key.fs.alpha_func != SVGA3D_CMP_ALWAYS) {
631635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      float alpha = emit->key.fs.alpha_ref;
631735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->fs.alpha_ref_index =
631835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         alloc_immediate_float4(emit, alpha, alpha, alpha, alpha);
631935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
632035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
632135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Now, emit the constant block containing all the immediates
632235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * declared by shader, as well as the extra ones seen above.
632335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
632435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_vgpu10_immediates_block(emit);
632535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
632635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->unit == PIPE_SHADER_FRAGMENT) {
632735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_frontface_instructions(emit);
632835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_fragcoord_instructions(emit);
632935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
633035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (emit->unit == PIPE_SHADER_VERTEX) {
633135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_vertex_attrib_instructions(emit);
633235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
633335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
633435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
633535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
633635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
633735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
633835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
633935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit alpha test code.  This compares TEMP[fs_color_tmp_index].w
634035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * against the alpha reference value and discards the fragment if the
634135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * comparison fails.
634235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
634335bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
634435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_alpha_test_instructions(struct svga_shader_emitter_v10 *emit,
634535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                             unsigned fs_color_tmp_index)
634635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
634735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* compare output color's alpha to alpha ref and kill */
634835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned tmp = get_temp_index(emit);
634935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
635035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register tmp_src_x =
635135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&tmp_src, TGSI_SWIZZLE_X);
635235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
635335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register color_src =
635435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_src_temp_reg(fs_color_tmp_index);
635535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register color_src_w =
635635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      scalar_src(&color_src, TGSI_SWIZZLE_W);
635735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register ref_src =
635835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_src_immediate_reg(emit->fs.alpha_ref_index);
635935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_dst_register color_dst =
636035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_dst_output_reg(emit->fs.color_out_index[0]);
636135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
636235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_FRAGMENT);
636335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
636435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* dst = src0 'alpha_func' src1 */
636535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_comparison(emit, emit->key.fs.alpha_func, &tmp_dst,
636635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                   &color_src_w, &ref_src);
636735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
636835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* DISCARD if dst.x == 0 */
636935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   begin_emit_instruction(emit);
637035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_discard_opcode(emit, FALSE);  /* discard if src0.x is zero */
637135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit_src_register(emit, &tmp_src_x);
637235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   end_emit_instruction(emit);
637335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
6374d31481e70ab0da293d4c3010815f643f161b7168Brian Paul   /* If we don't need to broadcast the color below or set fragments to
6375d31481e70ab0da293d4c3010815f643f161b7168Brian Paul    * white, emit final color here.
6376d31481e70ab0da293d4c3010815f643f161b7168Brian Paul    */
6377d31481e70ab0da293d4c3010815f643f161b7168Brian Paul   if (emit->key.fs.write_color0_to_n_cbufs <= 1 &&
6378d31481e70ab0da293d4c3010815f643f161b7168Brian Paul       !emit->key.fs.white_fragments) {
637935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV output.color, tempcolor */
638035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &color_dst,
638135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &color_src, FALSE);     /* XXX saturate? */
638235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
638335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
638435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_temp_indexes(emit);
638535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
638635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
638735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
638835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
6389d31481e70ab0da293d4c3010815f643f161b7168Brian Paul * When we need to emit white for all fragments (for emulating XOR logicop
6390d31481e70ab0da293d4c3010815f643f161b7168Brian Paul * mode), this function copies white into the temporary color output register.
6391d31481e70ab0da293d4c3010815f643f161b7168Brian Paul */
6392d31481e70ab0da293d4c3010815f643f161b7168Brian Paulstatic void
6393d31481e70ab0da293d4c3010815f643f161b7168Brian Paulemit_set_color_white(struct svga_shader_emitter_v10 *emit,
6394d31481e70ab0da293d4c3010815f643f161b7168Brian Paul                     unsigned fs_color_tmp_index)
6395d31481e70ab0da293d4c3010815f643f161b7168Brian Paul{
6396d31481e70ab0da293d4c3010815f643f161b7168Brian Paul   struct tgsi_full_dst_register color_dst =
6397d31481e70ab0da293d4c3010815f643f161b7168Brian Paul      make_dst_temp_reg(fs_color_tmp_index);
6398d31481e70ab0da293d4c3010815f643f161b7168Brian Paul   struct tgsi_full_src_register white =
6399d31481e70ab0da293d4c3010815f643f161b7168Brian Paul      make_immediate_reg_float(emit, 1.0f);
6400d31481e70ab0da293d4c3010815f643f161b7168Brian Paul
6401d31481e70ab0da293d4c3010815f643f161b7168Brian Paul   emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &color_dst, &white, FALSE);
6402d31481e70ab0da293d4c3010815f643f161b7168Brian Paul}
6403d31481e70ab0da293d4c3010815f643f161b7168Brian Paul
6404d31481e70ab0da293d4c3010815f643f161b7168Brian Paul
6405d31481e70ab0da293d4c3010815f643f161b7168Brian Paul/**
640635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit instructions for writing a single color output to multiple
640735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * color buffers.
6408d31481e70ab0da293d4c3010815f643f161b7168Brian Paul * This is used when the TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS (or
6409d31481e70ab0da293d4c3010815f643f161b7168Brian Paul * when key.fs.white_fragments is true).
641035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * property is set and the number of render targets is greater than one.
641135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * \param fs_color_tmp_index  index of the temp register that holds the
641235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul *                            color to broadcast.
641335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
641435bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic void
641535bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_broadcast_color_instructions(struct svga_shader_emitter_v10 *emit,
641635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                 unsigned fs_color_tmp_index)
641735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
641835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const unsigned n = emit->key.fs.write_color0_to_n_cbufs;
641935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned i;
642035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_full_src_register color_src =
642135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      make_src_temp_reg(fs_color_tmp_index);
642235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
642335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(emit->unit == PIPE_SHADER_FRAGMENT);
642435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
642535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   for (i = 0; i < n; i++) {
642635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      unsigned output_reg = emit->fs.color_out_index[i];
642735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      struct tgsi_full_dst_register color_dst =
642835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         make_dst_output_reg(output_reg);
642935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
643035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Fill in this semantic here since we'll use it later in
643135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * emit_dst_register().
643235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
643335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->info.output_semantic_name[output_reg] = TGSI_SEMANTIC_COLOR;
643435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
643535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* MOV output.color[i], tempcolor */
643635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &color_dst,
643735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           &color_src, FALSE);     /* XXX saturate? */
643835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
643935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
644035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
644135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
644235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
644335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit extra helper code after the original shader code, but before the
644435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * last END/RET instruction.
644535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * For vertex shaders this means emitting the extra code to apply the
644635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * prescale scale/translation.
644735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
644835bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
644935bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_post_helpers(struct svga_shader_emitter_v10 *emit)
645035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
645135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->unit == PIPE_SHADER_VERTEX) {
645235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit_vertex_instructions(emit);
645335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
645435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   else if (emit->unit == PIPE_SHADER_FRAGMENT) {
645535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      const unsigned fs_color_tmp_index = emit->fs.color_tmp_index;
645635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
645735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* We no longer want emit_dst_register() to substitute the
645835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * temporary fragment color register for the real color output.
645935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
646035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->fs.color_tmp_index = INVALID_INDEX;
646135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
646235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (emit->key.fs.alpha_func != SVGA3D_CMP_ALWAYS) {
646335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_alpha_test_instructions(emit, fs_color_tmp_index);
646435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
6465d31481e70ab0da293d4c3010815f643f161b7168Brian Paul      if (emit->key.fs.white_fragments) {
6466d31481e70ab0da293d4c3010815f643f161b7168Brian Paul         emit_set_color_white(emit, fs_color_tmp_index);
6467d31481e70ab0da293d4c3010815f643f161b7168Brian Paul      }
6468d31481e70ab0da293d4c3010815f643f161b7168Brian Paul      if (emit->key.fs.write_color0_to_n_cbufs > 1 ||
6469d31481e70ab0da293d4c3010815f643f161b7168Brian Paul          emit->key.fs.white_fragments) {
647035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit_broadcast_color_instructions(emit, fs_color_tmp_index);
647135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
647235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
647335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
647435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
647535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
647635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
647735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
647835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
647935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Translate the TGSI tokens into VGPU10 tokens.
648035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
648135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
648235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vgpu10_instructions(struct svga_shader_emitter_v10 *emit,
648335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                         const struct tgsi_token *tokens)
648435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
648535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct tgsi_parse_context parse;
648635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   boolean ret = TRUE;
648735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   boolean pre_helpers_emitted = FALSE;
648835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned inst_number = 0;
648935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
649035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tgsi_parse_init(&parse, tokens);
649135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
649235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   while (!tgsi_parse_end_of_tokens(&parse)) {
649335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_parse_token(&parse);
649435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
649535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      switch (parse.FullToken.Token.Type) {
649635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TOKEN_TYPE_IMMEDIATE:
649735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         ret = emit_vgpu10_immediate(emit, &parse.FullToken.FullImmediate);
649835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (!ret)
649935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            goto done;
650035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         break;
650135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
650235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TOKEN_TYPE_DECLARATION:
650335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         ret = emit_vgpu10_declaration(emit, &parse.FullToken.FullDeclaration);
650435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (!ret)
650535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            goto done;
650635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         break;
650735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
650835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TOKEN_TYPE_INSTRUCTION:
650935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (!pre_helpers_emitted) {
651035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            ret = emit_pre_helpers(emit);
651135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            if (!ret)
651235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               goto done;
651335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            pre_helpers_emitted = TRUE;
651435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
651535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         ret = emit_vgpu10_instruction(emit, inst_number++,
651635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                       &parse.FullToken.FullInstruction);
651735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (!ret)
651835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            goto done;
651935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         break;
652035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
652135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      case TGSI_TOKEN_TYPE_PROPERTY:
652235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         ret = emit_vgpu10_property(emit, &parse.FullToken.FullProperty);
652335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (!ret)
652435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            goto done;
652535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         break;
652635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
652735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      default:
652835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         break;
652935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
653035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
653135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
653235bb29d4994efadd1719a147731afa34e78a0be1Brian Pauldone:
653335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tgsi_parse_free(&parse);
653435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return ret;
653535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
653635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
653735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
653835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
653935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Emit the first VGPU10 shader tokens.
654035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
654135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
654235bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vgpu10_header(struct svga_shader_emitter_v10 *emit)
654335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
654435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10ProgramToken ptoken;
654535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
654635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* First token: VGPU10ProgramToken  (version info, program type (VS,GS,PS)) */
654735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   ptoken.majorVersion = 4;
654835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   ptoken.minorVersion = 0;
654935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   ptoken.programType = translate_shader_type(emit->unit);
655035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!emit_dword(emit, ptoken.value))
655135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      return FALSE;
655235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
655335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Second token: total length of shader, in tokens.  We can't fill this
655435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * in until we're all done.  Emit zero for now.
655535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
655635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return emit_dword(emit, 0);
655735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
655835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
655935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
656035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic boolean
656135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulemit_vgpu10_tail(struct svga_shader_emitter_v10 *emit)
656235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
656335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   VGPU10ProgramToken *tokens;
656435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
656535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Replace the second token with total shader length */
656635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tokens = (VGPU10ProgramToken *) emit->buf;
656735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tokens[1].value = emit_get_num_tokens(emit);
656835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
656935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return TRUE;
657035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
657135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
657235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
657335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
657435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Modify the FS to read the BCOLORs and use the FACE register
657535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * to choose between the front/back colors.
657635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
657735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic const struct tgsi_token *
657835bb29d4994efadd1719a147731afa34e78a0be1Brian Paultransform_fs_twoside(const struct tgsi_token *tokens)
657935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
658035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (0) {
658135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("Before tgsi_add_two_side ------------------\n");
658235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_dump(tokens,0);
658335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
658435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tokens = tgsi_add_two_side(tokens);
658535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (0) {
658635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("After tgsi_add_two_side ------------------\n");
658735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_dump(tokens, 0);
658835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
658935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return tokens;
659035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
659135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
659235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
659335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
659435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Modify the FS to do polygon stipple.
659535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
659635bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic const struct tgsi_token *
659735bb29d4994efadd1719a147731afa34e78a0be1Brian Paultransform_fs_pstipple(struct svga_shader_emitter_v10 *emit,
659835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                      const struct tgsi_token *tokens)
659935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
660035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const struct tgsi_token *new_tokens;
660135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   unsigned unit;
660235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
660335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (0) {
660435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("Before pstipple ------------------\n");
660535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_dump(tokens,0);
660635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
660735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
660869f43c2cc903d5973bab2515be51465c9e8f9f9eMarek Olšák   new_tokens = util_pstipple_create_fragment_shader(tokens, &unit, 0,
660969f43c2cc903d5973bab2515be51465c9e8f9f9eMarek Olšák                                                     TGSI_FILE_INPUT);
661035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
661135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->fs.pstipple_sampler_unit = unit;
661235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
661335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* Setup texture state for stipple */
6614dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80Brian Paul   emit->sampler_target[unit] = TGSI_TEXTURE_2D;
661535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->key.tex[unit].swizzle_r = TGSI_SWIZZLE_X;
661635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->key.tex[unit].swizzle_g = TGSI_SWIZZLE_Y;
661735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->key.tex[unit].swizzle_b = TGSI_SWIZZLE_Z;
661835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->key.tex[unit].swizzle_a = TGSI_SWIZZLE_W;
661935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
662035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (0) {
662135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("After pstipple ------------------\n");
662235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_dump(new_tokens, 0);
662335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
662435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
662535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return new_tokens;
662635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
662735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
662835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
662935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * Modify the FS to support anti-aliasing point.
663035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
663135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstatic const struct tgsi_token *
663235bb29d4994efadd1719a147731afa34e78a0be1Brian Paultransform_fs_aapoint(const struct tgsi_token *tokens,
663335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                     int aa_coord_index)
663435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
663535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (0) {
663635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("Before tgsi_add_aa_point ------------------\n");
663735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_dump(tokens,0);
663835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
663935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   tokens = tgsi_add_aa_point(tokens, aa_coord_index);
664035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (0) {
664135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("After tgsi_add_aa_point ------------------\n");
664235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_dump(tokens, 0);
664335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
664435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return tokens;
664535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
664635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
664735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul/**
664835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul * This is the main entrypoint for the TGSI -> VPGU10 translator.
664935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul */
665035bb29d4994efadd1719a147731afa34e78a0be1Brian Paulstruct svga_shader_variant *
665135bb29d4994efadd1719a147731afa34e78a0be1Brian Paulsvga_tgsi_vgpu10_translate(struct svga_context *svga,
665235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           const struct svga_shader *shader,
665335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           const struct svga_compile_key *key,
665435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                           unsigned unit)
665535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul{
665635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct svga_shader_variant *variant = NULL;
665735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct svga_shader_emitter_v10 *emit;
665835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   const struct tgsi_token *tokens = shader->tokens;
665935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct svga_vertex_shader *vs = svga->curr.vs;
666035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   struct svga_geometry_shader *gs = svga->curr.gs;
666135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
666235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(unit == PIPE_SHADER_VERTEX ||
666335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          unit == PIPE_SHADER_GEOMETRY ||
666435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          unit == PIPE_SHADER_FRAGMENT);
666535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
666635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* These two flags cannot be used together */
666735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   assert(key->vs.need_prescale + key->vs.undo_viewport <= 1);
666835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
66692e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_TGSIVGPU10TRANSLATE);
667035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
667135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Setup the code emitter
667235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
667335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit = alloc_emitter();
667435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!emit)
66752e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee      goto done;
667635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
667735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->unit = unit;
667835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->key = *key;
667935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
668035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->vposition.need_prescale = (emit->key.vs.need_prescale ||
668135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul                                   emit->key.gs.need_prescale);
668235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->vposition.tmp_index = INVALID_INDEX;
668335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->vposition.so_index = INVALID_INDEX;
668435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->vposition.out_index = INVALID_INDEX;
668535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
668635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->fs.color_tmp_index = INVALID_INDEX;
668735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->fs.face_input_index = INVALID_INDEX;
668835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->fs.fragcoord_input_index = INVALID_INDEX;
668935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
669035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->gs.prim_id_index = INVALID_INDEX;
669135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
669235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->clip_dist_out_index = INVALID_INDEX;
669335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->clip_dist_tmp_index = INVALID_INDEX;
669435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->clip_dist_so_index = INVALID_INDEX;
669535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->clip_vertex_out_index = INVALID_INDEX;
669635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
669735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->key.fs.alpha_func == SVGA3D_CMP_INVALID) {
669835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->key.fs.alpha_func = SVGA3D_CMP_ALWAYS;
669935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
670035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
670135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (unit == PIPE_SHADER_FRAGMENT) {
670235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (key->fs.light_twoside) {
670335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         tokens = transform_fs_twoside(tokens);
670435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
670535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (key->fs.pstipple) {
670635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         const struct tgsi_token *new_tokens =
670735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            transform_fs_pstipple(emit, tokens);
670835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (tokens != shader->tokens) {
670935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            /* free the two-sided shader tokens */
671035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            tgsi_free_tokens(tokens);
671135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
671235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         tokens = new_tokens;
671335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
671435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (key->fs.aa_point) {
671535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         tokens = transform_fs_aapoint(tokens, key->fs.aa_point_coord_index);
671635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
671735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
671835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
671935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (SVGA_DEBUG & DEBUG_TGSI) {
672035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("#####################################\n");
672135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("### TGSI Shader %u\n", shader->id);
672235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_dump(tokens, 0);
672335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
672435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
672535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /**
672635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Rescan the header if the token string is different from the one
672735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * included in the shader; otherwise, the header info is already up-to-date
672835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
672935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (tokens != shader->tokens) {
673035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_scan_shader(tokens, &emit->info);
673135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } else {
673235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      emit->info = shader->info;
673335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
673435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
673535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->num_outputs = emit->info.num_outputs;
673635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
673735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (unit == PIPE_SHADER_FRAGMENT) {
673835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /* Compute FS input remapping to match the output from VS/GS */
673935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (gs) {
674035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         svga_link_shaders(&gs->base.info, &emit->info, &emit->linkage);
674135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      } else {
674235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         assert(vs);
674335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         svga_link_shaders(&vs->base.info, &emit->info, &emit->linkage);
674435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
674535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   } else if (unit == PIPE_SHADER_GEOMETRY) {
674635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(vs);
674735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      svga_link_shaders(&vs->base.info, &emit->info, &emit->linkage);
674835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
674935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
675035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   determine_clipping_mode(emit);
675135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
675235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (unit == PIPE_SHADER_GEOMETRY || unit == PIPE_SHADER_VERTEX) {
675335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      if (shader->stream_output != NULL || emit->clip_mode == CLIP_DISTANCE) {
675435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         /* if there is stream output declarations associated
675535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * with this shader or the shader writes to ClipDistance
675635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * then reserve extra registers for the non-adjusted vertex position
675735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          * and the ClipDistance shadow copy
675835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul          */
675935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         emit->vposition.so_index = emit->num_outputs++;
676035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
676135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         if (emit->clip_mode == CLIP_DISTANCE) {
676235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            emit->clip_dist_so_index = emit->num_outputs++;
676335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul            if (emit->info.num_written_clipdistance > 4)
676435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul               emit->num_outputs++;
676535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul         }
676635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      }
676735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
676835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
676935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
677035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Do actual shader translation.
677135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
677235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!emit_vgpu10_header(emit)) {
677335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("svga: emit VGPU10 header failed\n");
677435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      goto cleanup;
677535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
677635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
677735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!emit_vgpu10_instructions(emit, tokens)) {
677835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("svga: emit VGPU10 instructions failed\n");
677935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      goto cleanup;
678035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
678135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
678235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!emit_vgpu10_tail(emit)) {
678335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      debug_printf("svga: emit VGPU10 tail failed\n");
678435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      goto cleanup;
678535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
678635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
678735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (emit->register_overflow) {
678835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      goto cleanup;
678935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
679035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
679135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /*
679235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * Create, initialize the 'variant' object.
679335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
6794f413f1a17c506d5d4474a1baa0556a9e9f554c63Brian Paul   variant = svga_new_shader_variant(svga);
679535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (!variant)
679635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      goto cleanup;
679735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
679835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   variant->shader = shader;
679935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   variant->nr_tokens = emit_get_num_tokens(emit);
680035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   variant->tokens = (const unsigned *)emit->buf;
680135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   emit->buf = NULL;  /* buffer is no longer owed by emitter context */
680235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   memcpy(&variant->key, key, sizeof(*key));
680335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   variant->id = UTIL_BITMASK_INVALID_INDEX;
680435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
680535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /* The extra constant starting offset starts with the number of
680635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    * shader constants declared in the shader.
680735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
680835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   variant->extra_const_start = emit->num_shader_consts[0];
680935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (key->gs.wide_point) {
681035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      /**
681135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * The extra constant added in the transformed shader
681235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * for inverse viewport scale is to be supplied by the driver.
681335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       * So the extra constant starting offset needs to be reduced by 1.
681435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul       */
681535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      assert(variant->extra_const_start > 0);
681635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      variant->extra_const_start--;
681735bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
681835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
681935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   variant->pstipple_sampler_unit = emit->fs.pstipple_sampler_unit;
682035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
68211082735bb69e9f64cb3991a52f0e270902917855Brian Paul   /* If there was exactly one write to a fragment shader output register
68221082735bb69e9f64cb3991a52f0e270902917855Brian Paul    * and it came from a constant buffer, we know all fragments will have
68231082735bb69e9f64cb3991a52f0e270902917855Brian Paul    * the same color (except for blending).
68241082735bb69e9f64cb3991a52f0e270902917855Brian Paul    */
68251082735bb69e9f64cb3991a52f0e270902917855Brian Paul   variant->constant_color_output =
68261082735bb69e9f64cb3991a52f0e270902917855Brian Paul      emit->constant_color_output && emit->num_output_writes == 1;
68271082735bb69e9f64cb3991a52f0e270902917855Brian Paul
682835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   /** keep track in the variant if flat interpolation is used
682935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    *  for any of the varyings.
683035bb29d4994efadd1719a147731afa34e78a0be1Brian Paul    */
683135bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   variant->uses_flat_interp = emit->uses_flat_interp;
683235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
683335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   if (tokens != shader->tokens) {
683435bb29d4994efadd1719a147731afa34e78a0be1Brian Paul      tgsi_free_tokens(tokens);
683535bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   }
683635bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
683735bb29d4994efadd1719a147731afa34e78a0be1Brian Paulcleanup:
683835bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   free_emitter(emit);
683935bb29d4994efadd1719a147731afa34e78a0be1Brian Paul
68402e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Leedone:
68412e1cfcc431471c68ba79c9323716bed7da79c909Charmaine Lee   SVGA_STATS_TIME_POP(svga_sws(svga));
684235bb29d4994efadd1719a147731afa34e78a0be1Brian Paul   return variant;
684335bb29d4994efadd1719a147731afa34e78a0be1Brian Paul}
6844