1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2012-2021 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17bf215546Sopenharmony_ci * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
21bf215546Sopenharmony_ci *
22bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
23bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
24bf215546Sopenharmony_ci * of the Software.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci/*
29bf215546Sopenharmony_ci * ShaderTGSI.c --
30bf215546Sopenharmony_ci *    Functions for translating shaders.
31bf215546Sopenharmony_ci */
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "Debug.h"
34bf215546Sopenharmony_ci#include "ShaderParse.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci#include "pipe/p_state.h"
37bf215546Sopenharmony_ci#include "tgsi/tgsi_ureg.h"
38bf215546Sopenharmony_ci#include "tgsi/tgsi_dump.h"
39bf215546Sopenharmony_ci#include "util/u_memory.h"
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci#include "ShaderDump.h"
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_cienum dx10_opcode_format {
45bf215546Sopenharmony_ci   OF_FLOAT,
46bf215546Sopenharmony_ci   OF_INT,
47bf215546Sopenharmony_ci   OF_UINT
48bf215546Sopenharmony_ci};
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_cistruct dx10_opcode_xlate {
51bf215546Sopenharmony_ci   D3D10_SB_OPCODE_TYPE type;
52bf215546Sopenharmony_ci   enum dx10_opcode_format format;
53bf215546Sopenharmony_ci   uint tgsi_opcode;
54bf215546Sopenharmony_ci};
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci/* Opcodes that we have not even attempted to implement:
57bf215546Sopenharmony_ci */
58bf215546Sopenharmony_ci#define TGSI_LOG_UNSUPPORTED TGSI_OPCODE_LAST
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ci/* Opcodes which do not translate directly to a TGSI opcode, but which
61bf215546Sopenharmony_ci * have at least a partial implemention coded below:
62bf215546Sopenharmony_ci */
63bf215546Sopenharmony_ci#define TGSI_EXPAND          (TGSI_OPCODE_LAST+1)
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_cistatic struct dx10_opcode_xlate opcode_xlate[D3D10_SB_NUM_OPCODES] = {
66bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ADD,                              OF_FLOAT, TGSI_OPCODE_ADD},
67bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_AND,                              OF_UINT,  TGSI_OPCODE_AND},
68bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_BREAK,                            OF_FLOAT, TGSI_OPCODE_BRK},
69bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_BREAKC,                           OF_UINT,  TGSI_EXPAND},
70bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_CALL,                             OF_UINT,  TGSI_EXPAND},
71bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_CALLC,                            OF_UINT,  TGSI_EXPAND},
72bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_CASE,                             OF_UINT,  TGSI_OPCODE_CASE},
73bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_CONTINUE,                         OF_FLOAT, TGSI_OPCODE_CONT},
74bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_CONTINUEC,                        OF_UINT,  TGSI_EXPAND},
75bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_CUT,                              OF_FLOAT, TGSI_EXPAND},
76bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DEFAULT,                          OF_FLOAT, TGSI_OPCODE_DEFAULT},
77bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DERIV_RTX,                        OF_FLOAT, TGSI_OPCODE_DDX},
78bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DERIV_RTY,                        OF_FLOAT, TGSI_OPCODE_DDY},
79bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DISCARD,                          OF_UINT,  TGSI_EXPAND},
80bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DIV,                              OF_FLOAT, TGSI_OPCODE_DIV},
81bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DP2,                              OF_FLOAT, TGSI_OPCODE_DP2},
82bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DP3,                              OF_FLOAT, TGSI_OPCODE_DP3},
83bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DP4,                              OF_FLOAT, TGSI_OPCODE_DP4},
84bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ELSE,                             OF_FLOAT, TGSI_OPCODE_ELSE},
85bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_EMIT,                             OF_FLOAT, TGSI_EXPAND},
86bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_EMITTHENCUT,                      OF_FLOAT, TGSI_EXPAND},
87bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ENDIF,                            OF_FLOAT, TGSI_OPCODE_ENDIF},
88bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ENDLOOP,                          OF_FLOAT, TGSI_OPCODE_ENDLOOP},
89bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ENDSWITCH,                        OF_FLOAT, TGSI_OPCODE_ENDSWITCH},
90bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_EQ,                               OF_FLOAT, TGSI_OPCODE_FSEQ},
91bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_EXP,                              OF_FLOAT, TGSI_EXPAND},
92bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_FRC,                              OF_FLOAT, TGSI_OPCODE_FRC},
93bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_FTOI,                             OF_FLOAT, TGSI_EXPAND},
94bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_FTOU,                             OF_FLOAT, TGSI_EXPAND},
95bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_GE,                               OF_FLOAT, TGSI_OPCODE_FSGE},
96bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_IADD,                             OF_INT,   TGSI_OPCODE_UADD},
97bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_IF,                               OF_UINT,  TGSI_EXPAND},
98bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_IEQ,                              OF_INT,   TGSI_OPCODE_USEQ},
99bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_IGE,                              OF_INT,   TGSI_OPCODE_ISGE},
100bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ILT,                              OF_INT,   TGSI_OPCODE_ISLT},
101bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_IMAD,                             OF_INT,   TGSI_OPCODE_UMAD},
102bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_IMAX,                             OF_INT,   TGSI_OPCODE_IMAX},
103bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_IMIN,                             OF_INT,   TGSI_OPCODE_IMIN},
104bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_IMUL,                             OF_INT,   TGSI_EXPAND},
105bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_INE,                              OF_INT,   TGSI_OPCODE_USNE},
106bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_INEG,                             OF_INT,   TGSI_OPCODE_INEG},
107bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ISHL,                             OF_INT,   TGSI_OPCODE_SHL},
108bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ISHR,                             OF_INT,   TGSI_OPCODE_ISHR},
109bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ITOF,                             OF_INT,   TGSI_OPCODE_I2F},
110bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_LABEL,                            OF_INT,   TGSI_EXPAND},
111bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_LD,                               OF_UINT,  TGSI_EXPAND},
112bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_LD_MS,                            OF_UINT,  TGSI_EXPAND},
113bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_LOG,                              OF_FLOAT, TGSI_EXPAND},
114bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_LOOP,                             OF_FLOAT, TGSI_OPCODE_BGNLOOP},
115bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_LT,                               OF_FLOAT, TGSI_OPCODE_FSLT},
116bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_MAD,                              OF_FLOAT, TGSI_OPCODE_MAD},
117bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_MIN,                              OF_FLOAT, TGSI_OPCODE_MIN},
118bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_MAX,                              OF_FLOAT, TGSI_OPCODE_MAX},
119bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_CUSTOMDATA,                       OF_FLOAT, TGSI_EXPAND},
120bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_MOV,                              OF_UINT,  TGSI_OPCODE_MOV},
121bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_MOVC,                             OF_UINT,  TGSI_OPCODE_UCMP},
122bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_MUL,                              OF_FLOAT, TGSI_OPCODE_MUL},
123bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_NE,                               OF_FLOAT, TGSI_OPCODE_FSNE},
124bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_NOP,                              OF_FLOAT, TGSI_OPCODE_NOP},
125bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_NOT,                              OF_UINT,  TGSI_OPCODE_NOT},
126bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_OR,                               OF_UINT,  TGSI_OPCODE_OR},
127bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_RESINFO,                          OF_UINT,  TGSI_EXPAND},
128bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_RET,                              OF_FLOAT, TGSI_OPCODE_RET},
129bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_RETC,                             OF_UINT,  TGSI_EXPAND},
130bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ROUND_NE,                         OF_FLOAT, TGSI_OPCODE_ROUND},
131bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ROUND_NI,                         OF_FLOAT, TGSI_OPCODE_FLR},
132bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ROUND_PI,                         OF_FLOAT, TGSI_OPCODE_CEIL},
133bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ROUND_Z,                          OF_FLOAT, TGSI_OPCODE_TRUNC},
134bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_RSQ,                              OF_FLOAT, TGSI_EXPAND},
135bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_SAMPLE,                           OF_FLOAT, TGSI_EXPAND},
136bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_SAMPLE_C,                         OF_FLOAT, TGSI_EXPAND},
137bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_SAMPLE_C_LZ,                      OF_FLOAT, TGSI_EXPAND},
138bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_SAMPLE_L,                         OF_FLOAT, TGSI_EXPAND},
139bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_SAMPLE_D,                         OF_FLOAT, TGSI_EXPAND},
140bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_SAMPLE_B,                         OF_FLOAT, TGSI_EXPAND},
141bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_SQRT,                             OF_FLOAT, TGSI_EXPAND},
142bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_SWITCH,                           OF_UINT,  TGSI_OPCODE_SWITCH},
143bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_SINCOS,                           OF_FLOAT, TGSI_EXPAND},
144bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_UDIV,                             OF_UINT,  TGSI_EXPAND},
145bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_ULT,                              OF_UINT,  TGSI_OPCODE_USLT},
146bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_UGE,                              OF_UINT,  TGSI_OPCODE_USGE},
147bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_UMUL,                             OF_UINT,  TGSI_EXPAND},
148bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_UMAD,                             OF_UINT,  TGSI_OPCODE_UMAD},
149bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_UMAX,                             OF_UINT,  TGSI_OPCODE_UMAX},
150bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_UMIN,                             OF_UINT,  TGSI_OPCODE_UMIN},
151bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_USHR,                             OF_UINT,  TGSI_OPCODE_USHR},
152bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_UTOF,                             OF_UINT,  TGSI_OPCODE_U2F},
153bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_XOR,                              OF_UINT,  TGSI_OPCODE_XOR},
154bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_RESOURCE,                     OF_FLOAT, TGSI_EXPAND},
155bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_CONSTANT_BUFFER,              OF_FLOAT, TGSI_EXPAND},
156bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_SAMPLER,                      OF_FLOAT, TGSI_EXPAND},
157bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_INDEX_RANGE,                  OF_FLOAT, TGSI_LOG_UNSUPPORTED},
158bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY, OF_FLOAT, TGSI_EXPAND},
159bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_GS_INPUT_PRIMITIVE,           OF_FLOAT, TGSI_EXPAND},
160bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT,      OF_FLOAT, TGSI_EXPAND},
161bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_INPUT,                        OF_FLOAT, TGSI_EXPAND},
162bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_INPUT_SGV,                    OF_FLOAT, TGSI_EXPAND},
163bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_INPUT_SIV,                    OF_FLOAT, TGSI_EXPAND},
164bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_INPUT_PS,                     OF_FLOAT, TGSI_EXPAND},
165bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_INPUT_PS_SGV,                 OF_FLOAT, TGSI_EXPAND},
166bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_INPUT_PS_SIV,                 OF_FLOAT, TGSI_EXPAND},
167bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_OUTPUT,                       OF_FLOAT, TGSI_EXPAND},
168bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_OUTPUT_SGV,                   OF_FLOAT, TGSI_EXPAND},
169bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_OUTPUT_SIV,                   OF_FLOAT, TGSI_EXPAND},
170bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_TEMPS,                        OF_FLOAT, TGSI_EXPAND},
171bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP,               OF_FLOAT, TGSI_EXPAND},
172bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS,                 OF_FLOAT, TGSI_LOG_UNSUPPORTED},
173bf215546Sopenharmony_ci   {D3D10_SB_OPCODE_RESERVED0,                        OF_FLOAT, TGSI_LOG_UNSUPPORTED},
174bf215546Sopenharmony_ci   {D3D10_1_SB_OPCODE_LOD,                            OF_FLOAT, TGSI_LOG_UNSUPPORTED},
175bf215546Sopenharmony_ci   {D3D10_1_SB_OPCODE_GATHER4,                        OF_FLOAT, TGSI_LOG_UNSUPPORTED},
176bf215546Sopenharmony_ci   {D3D10_1_SB_OPCODE_SAMPLE_POS,                     OF_FLOAT, TGSI_LOG_UNSUPPORTED},
177bf215546Sopenharmony_ci   {D3D10_1_SB_OPCODE_SAMPLE_INFO,                    OF_FLOAT, TGSI_LOG_UNSUPPORTED}
178bf215546Sopenharmony_ci};
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci#define SHADER_MAX_TEMPS 4096
181bf215546Sopenharmony_ci#define SHADER_MAX_INPUTS 32
182bf215546Sopenharmony_ci#define SHADER_MAX_OUTPUTS 32
183bf215546Sopenharmony_ci#define SHADER_MAX_CONSTS 4096
184bf215546Sopenharmony_ci#define SHADER_MAX_RESOURCES PIPE_MAX_SHADER_SAMPLER_VIEWS
185bf215546Sopenharmony_ci#define SHADER_MAX_SAMPLERS PIPE_MAX_SAMPLERS
186bf215546Sopenharmony_ci#define SHADER_MAX_INDEXABLE_TEMPS 4096
187bf215546Sopenharmony_ci
188bf215546Sopenharmony_cistruct Shader_call {
189bf215546Sopenharmony_ci   unsigned d3d_label;
190bf215546Sopenharmony_ci   unsigned tgsi_label_token;
191bf215546Sopenharmony_ci};
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_cistruct Shader_label {
194bf215546Sopenharmony_ci   unsigned d3d_label;
195bf215546Sopenharmony_ci   unsigned tgsi_insn_no;
196bf215546Sopenharmony_ci};
197bf215546Sopenharmony_ci
198bf215546Sopenharmony_cistruct Shader_resource {
199bf215546Sopenharmony_ci   uint target;   /* TGSI_TEXTURE_x */
200bf215546Sopenharmony_ci};
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_cistruct Shader_xlate {
203bf215546Sopenharmony_ci   struct ureg_program *ureg;
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci   uint vertices_in;
206bf215546Sopenharmony_ci   uint declared_temps;
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci   struct ureg_dst temps[SHADER_MAX_TEMPS];
209bf215546Sopenharmony_ci   struct ureg_dst output_depth;
210bf215546Sopenharmony_ci   struct Shader_resource resources[SHADER_MAX_RESOURCES];
211bf215546Sopenharmony_ci   struct ureg_src sv[SHADER_MAX_RESOURCES];
212bf215546Sopenharmony_ci   struct ureg_src samplers[SHADER_MAX_SAMPLERS];
213bf215546Sopenharmony_ci   struct ureg_src imms;
214bf215546Sopenharmony_ci   struct ureg_src prim_id;
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ci   uint temp_offset;
217bf215546Sopenharmony_ci   uint indexable_temp_offsets[SHADER_MAX_INDEXABLE_TEMPS];
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci   struct {
220bf215546Sopenharmony_ci      boolean declared;
221bf215546Sopenharmony_ci      uint    writemask;
222bf215546Sopenharmony_ci      uint    siv_name;
223bf215546Sopenharmony_ci      boolean overloaded;
224bf215546Sopenharmony_ci      struct ureg_src reg;
225bf215546Sopenharmony_ci   } inputs[SHADER_MAX_INPUTS];
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_ci   struct {
228bf215546Sopenharmony_ci      struct ureg_dst reg[4];
229bf215546Sopenharmony_ci   } outputs[SHADER_MAX_OUTPUTS];
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci   struct {
232bf215546Sopenharmony_ci      uint d3d;
233bf215546Sopenharmony_ci      uint tgsi;
234bf215546Sopenharmony_ci   } clip_distance_mapping[2], cull_distance_mapping[2];
235bf215546Sopenharmony_ci   uint num_clip_distances_declared;
236bf215546Sopenharmony_ci   uint num_cull_distances_declared;
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci   struct Shader_call *calls;
239bf215546Sopenharmony_ci   uint num_calls;
240bf215546Sopenharmony_ci   uint max_calls;
241bf215546Sopenharmony_ci   struct Shader_label *labels;
242bf215546Sopenharmony_ci   uint num_labels;
243bf215546Sopenharmony_ci   uint max_labels;
244bf215546Sopenharmony_ci};
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_cistatic uint
247bf215546Sopenharmony_citranslate_interpolation(D3D10_SB_INTERPOLATION_MODE interpolation)
248bf215546Sopenharmony_ci{
249bf215546Sopenharmony_ci   switch (interpolation) {
250bf215546Sopenharmony_ci   case D3D10_SB_INTERPOLATION_UNDEFINED:
251bf215546Sopenharmony_ci      assert(0);
252bf215546Sopenharmony_ci      return TGSI_INTERPOLATE_LINEAR;
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   case D3D10_SB_INTERPOLATION_CONSTANT:
255bf215546Sopenharmony_ci      return TGSI_INTERPOLATE_CONSTANT;
256bf215546Sopenharmony_ci   case D3D10_SB_INTERPOLATION_LINEAR:
257bf215546Sopenharmony_ci      return TGSI_INTERPOLATE_PERSPECTIVE;
258bf215546Sopenharmony_ci   case D3D10_SB_INTERPOLATION_LINEAR_NOPERSPECTIVE:
259bf215546Sopenharmony_ci      return TGSI_INTERPOLATE_LINEAR;
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci   case D3D10_SB_INTERPOLATION_LINEAR_CENTROID:
262bf215546Sopenharmony_ci   case D3D10_SB_INTERPOLATION_LINEAR_SAMPLE: // DX10.1
263bf215546Sopenharmony_ci      LOG_UNSUPPORTED(TRUE);
264bf215546Sopenharmony_ci      return TGSI_INTERPOLATE_PERSPECTIVE;
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_ci   case D3D10_SB_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID:
267bf215546Sopenharmony_ci   case D3D10_SB_INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE: // DX10.1
268bf215546Sopenharmony_ci      LOG_UNSUPPORTED(TRUE);
269bf215546Sopenharmony_ci      return TGSI_INTERPOLATE_LINEAR;
270bf215546Sopenharmony_ci   }
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_ci   assert(0);
273bf215546Sopenharmony_ci   return TGSI_INTERPOLATE_LINEAR;
274bf215546Sopenharmony_ci}
275bf215546Sopenharmony_ci
276bf215546Sopenharmony_cistatic uint
277bf215546Sopenharmony_citranslate_system_name(D3D10_SB_NAME name)
278bf215546Sopenharmony_ci{
279bf215546Sopenharmony_ci   switch (name) {
280bf215546Sopenharmony_ci   case D3D10_SB_NAME_UNDEFINED:
281bf215546Sopenharmony_ci      assert(0);                /* should not happen */
282bf215546Sopenharmony_ci      return TGSI_SEMANTIC_GENERIC;
283bf215546Sopenharmony_ci   case D3D10_SB_NAME_POSITION:
284bf215546Sopenharmony_ci      return TGSI_SEMANTIC_POSITION;
285bf215546Sopenharmony_ci   case D3D10_SB_NAME_CLIP_DISTANCE:
286bf215546Sopenharmony_ci   case D3D10_SB_NAME_CULL_DISTANCE:
287bf215546Sopenharmony_ci      return TGSI_SEMANTIC_CLIPDIST;
288bf215546Sopenharmony_ci   case D3D10_SB_NAME_PRIMITIVE_ID:
289bf215546Sopenharmony_ci      return TGSI_SEMANTIC_PRIMID;
290bf215546Sopenharmony_ci   case D3D10_SB_NAME_INSTANCE_ID:
291bf215546Sopenharmony_ci      return TGSI_SEMANTIC_INSTANCEID;
292bf215546Sopenharmony_ci   case D3D10_SB_NAME_VERTEX_ID:
293bf215546Sopenharmony_ci      return TGSI_SEMANTIC_VERTEXID_NOBASE;
294bf215546Sopenharmony_ci   case D3D10_SB_NAME_VIEWPORT_ARRAY_INDEX:
295bf215546Sopenharmony_ci      return TGSI_SEMANTIC_VIEWPORT_INDEX;
296bf215546Sopenharmony_ci   case D3D10_SB_NAME_RENDER_TARGET_ARRAY_INDEX:
297bf215546Sopenharmony_ci      return TGSI_SEMANTIC_LAYER;
298bf215546Sopenharmony_ci   case D3D10_SB_NAME_IS_FRONT_FACE:
299bf215546Sopenharmony_ci      return TGSI_SEMANTIC_FACE;
300bf215546Sopenharmony_ci   case D3D10_SB_NAME_SAMPLE_INDEX:
301bf215546Sopenharmony_ci      LOG_UNSUPPORTED(TRUE);
302bf215546Sopenharmony_ci      return TGSI_SEMANTIC_GENERIC;
303bf215546Sopenharmony_ci   }
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci   assert(0);
306bf215546Sopenharmony_ci   return TGSI_SEMANTIC_GENERIC;
307bf215546Sopenharmony_ci}
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_cistatic uint
310bf215546Sopenharmony_citranslate_semantic_index(struct Shader_xlate *sx,
311bf215546Sopenharmony_ci                         D3D10_SB_NAME name,
312bf215546Sopenharmony_ci                         const struct Shader_dst_operand *operand)
313bf215546Sopenharmony_ci{
314bf215546Sopenharmony_ci   unsigned idx;
315bf215546Sopenharmony_ci   switch (name) {
316bf215546Sopenharmony_ci   case D3D10_SB_NAME_CLIP_DISTANCE:
317bf215546Sopenharmony_ci   case D3D10_SB_NAME_CULL_DISTANCE:
318bf215546Sopenharmony_ci      if (sx->clip_distance_mapping[0].d3d == operand->base.index[0].imm) {
319bf215546Sopenharmony_ci         idx = sx->clip_distance_mapping[0].tgsi;
320bf215546Sopenharmony_ci      } else {
321bf215546Sopenharmony_ci         assert(sx->clip_distance_mapping[1].d3d == operand->base.index[0].imm);
322bf215546Sopenharmony_ci         idx = sx->clip_distance_mapping[1].tgsi;
323bf215546Sopenharmony_ci      }
324bf215546Sopenharmony_ci      break;
325bf215546Sopenharmony_ci/*   case D3D10_SB_NAME_CULL_DISTANCE:
326bf215546Sopenharmony_ci      if (sx->cull_distance_mapping[0].d3d == operand->base.index[0].imm) {
327bf215546Sopenharmony_ci         idx = sx->cull_distance_mapping[0].tgsi;
328bf215546Sopenharmony_ci      } else {
329bf215546Sopenharmony_ci         assert(sx->cull_distance_mapping[1].d3d == operand->base.index[0].imm);
330bf215546Sopenharmony_ci         idx = sx->cull_distance_mapping[1].tgsi;
331bf215546Sopenharmony_ci      }
332bf215546Sopenharmony_ci      break;*/
333bf215546Sopenharmony_ci   default:
334bf215546Sopenharmony_ci      idx = 0;
335bf215546Sopenharmony_ci   }
336bf215546Sopenharmony_ci   return idx;
337bf215546Sopenharmony_ci}
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_cistatic enum tgsi_return_type
340bf215546Sopenharmony_citrans_dcl_ret_type(D3D10_SB_RESOURCE_RETURN_TYPE d3drettype) {
341bf215546Sopenharmony_ci   switch (d3drettype) {
342bf215546Sopenharmony_ci   case D3D10_SB_RETURN_TYPE_UNORM:
343bf215546Sopenharmony_ci      return TGSI_RETURN_TYPE_UNORM;
344bf215546Sopenharmony_ci   case D3D10_SB_RETURN_TYPE_SNORM:
345bf215546Sopenharmony_ci      return TGSI_RETURN_TYPE_SNORM;
346bf215546Sopenharmony_ci   case D3D10_SB_RETURN_TYPE_SINT:
347bf215546Sopenharmony_ci      return TGSI_RETURN_TYPE_SINT;
348bf215546Sopenharmony_ci   case D3D10_SB_RETURN_TYPE_UINT:
349bf215546Sopenharmony_ci      return TGSI_RETURN_TYPE_UINT;
350bf215546Sopenharmony_ci   case D3D10_SB_RETURN_TYPE_FLOAT:
351bf215546Sopenharmony_ci      return TGSI_RETURN_TYPE_FLOAT;
352bf215546Sopenharmony_ci   case D3D10_SB_RETURN_TYPE_MIXED:
353bf215546Sopenharmony_ci   default:
354bf215546Sopenharmony_ci      LOG_UNSUPPORTED(TRUE);
355bf215546Sopenharmony_ci      return TGSI_RETURN_TYPE_FLOAT;
356bf215546Sopenharmony_ci   }
357bf215546Sopenharmony_ci}
358bf215546Sopenharmony_ci
359bf215546Sopenharmony_cistatic void
360bf215546Sopenharmony_cideclare_vertices_in(struct Shader_xlate *sx,
361bf215546Sopenharmony_ci                    unsigned in)
362bf215546Sopenharmony_ci{
363bf215546Sopenharmony_ci   /* Make sure vertices_in is consistent with input primitive
364bf215546Sopenharmony_ci    * and other input declarations.
365bf215546Sopenharmony_ci    */
366bf215546Sopenharmony_ci   if (sx->vertices_in) {
367bf215546Sopenharmony_ci      assert(sx->vertices_in == in);
368bf215546Sopenharmony_ci   } else {
369bf215546Sopenharmony_ci      sx->vertices_in = in;
370bf215546Sopenharmony_ci   }
371bf215546Sopenharmony_ci}
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_cistruct swizzle_mapping {
374bf215546Sopenharmony_ci   unsigned x;
375bf215546Sopenharmony_ci   unsigned y;
376bf215546Sopenharmony_ci   unsigned z;
377bf215546Sopenharmony_ci   unsigned w;
378bf215546Sopenharmony_ci};
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ci/* mapping of writmask to swizzles */
381bf215546Sopenharmony_cistatic const struct swizzle_mapping writemask_to_swizzle[] = {
382bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_X, TGSI_SWIZZLE_X, TGSI_SWIZZLE_X }, //TGSI_WRITEMASK_NONE
383bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_X, TGSI_SWIZZLE_X, TGSI_SWIZZLE_X }, //TGSI_WRITEMASK_X
384bf215546Sopenharmony_ci   { TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y }, //TGSI_WRITEMASK_Y
385bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y }, //TGSI_WRITEMASK_XY
386bf215546Sopenharmony_ci   { TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z }, //TGSI_WRITEMASK_Z
387bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Z }, //TGSI_WRITEMASK_XZ
388bf215546Sopenharmony_ci   { TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z }, //TGSI_WRITEMASK_YZ
389bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_X }, //TGSI_WRITEMASK_XYZ
390bf215546Sopenharmony_ci   { TGSI_SWIZZLE_W, TGSI_SWIZZLE_W, TGSI_SWIZZLE_W, TGSI_SWIZZLE_W }, //TGSI_WRITEMASK_W
391bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_W, TGSI_SWIZZLE_X, TGSI_SWIZZLE_W }, //TGSI_WRITEMASK_XW
392bf215546Sopenharmony_ci   { TGSI_SWIZZLE_Y, TGSI_SWIZZLE_W, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_W }, //TGSI_WRITEMASK_YW
393bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_W, TGSI_SWIZZLE_W }, //TGSI_WRITEMASK_XYW
394bf215546Sopenharmony_ci   { TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W }, //TGSI_WRITEMASK_ZW
395bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W }, //TGSI_WRITEMASK_XZW
396bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W }, //TGSI_WRITEMASK_YZW
397bf215546Sopenharmony_ci   { TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W }, //TGSI_WRITEMASK_XYZW
398bf215546Sopenharmony_ci};
399bf215546Sopenharmony_ci
400bf215546Sopenharmony_cistatic struct ureg_src
401bf215546Sopenharmony_ciswizzle_reg(struct ureg_src src, uint writemask,
402bf215546Sopenharmony_ci            unsigned siv_name)
403bf215546Sopenharmony_ci{
404bf215546Sopenharmony_ci   switch (siv_name) {
405bf215546Sopenharmony_ci   case D3D10_SB_NAME_PRIMITIVE_ID:
406bf215546Sopenharmony_ci   case D3D10_SB_NAME_INSTANCE_ID:
407bf215546Sopenharmony_ci   case D3D10_SB_NAME_VERTEX_ID:
408bf215546Sopenharmony_ci   case D3D10_SB_NAME_VIEWPORT_ARRAY_INDEX:
409bf215546Sopenharmony_ci   case D3D10_SB_NAME_RENDER_TARGET_ARRAY_INDEX:
410bf215546Sopenharmony_ci   case D3D10_SB_NAME_IS_FRONT_FACE:
411bf215546Sopenharmony_ci      return ureg_scalar(src, TGSI_SWIZZLE_X);
412bf215546Sopenharmony_ci   default: {
413bf215546Sopenharmony_ci      const struct swizzle_mapping *swizzle =
414bf215546Sopenharmony_ci         &writemask_to_swizzle[writemask];
415bf215546Sopenharmony_ci      return ureg_swizzle(src, swizzle->x, swizzle->y,
416bf215546Sopenharmony_ci                          swizzle->z, swizzle->w);
417bf215546Sopenharmony_ci   }
418bf215546Sopenharmony_ci   }
419bf215546Sopenharmony_ci}
420bf215546Sopenharmony_ci
421bf215546Sopenharmony_cistatic void
422bf215546Sopenharmony_cidcl_base_output(struct Shader_xlate *sx,
423bf215546Sopenharmony_ci                struct ureg_program *ureg,
424bf215546Sopenharmony_ci                struct ureg_dst reg,
425bf215546Sopenharmony_ci                const struct Shader_dst_operand *operand)
426bf215546Sopenharmony_ci{
427bf215546Sopenharmony_ci   unsigned writemask =
428bf215546Sopenharmony_ci      operand->mask >> D3D10_SB_OPERAND_4_COMPONENT_MASK_SHIFT;
429bf215546Sopenharmony_ci   unsigned idx = operand->base.index[0].imm;
430bf215546Sopenharmony_ci   unsigned i;
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci   if (!writemask) {
433bf215546Sopenharmony_ci      sx->outputs[idx].reg[0] = reg;
434bf215546Sopenharmony_ci      sx->outputs[idx].reg[1] = reg;
435bf215546Sopenharmony_ci      sx->outputs[idx].reg[2] = reg;
436bf215546Sopenharmony_ci      sx->outputs[idx].reg[3] = reg;
437bf215546Sopenharmony_ci      return;
438bf215546Sopenharmony_ci   }
439bf215546Sopenharmony_ci
440bf215546Sopenharmony_ci   for (i = 0; i < 4; ++i) {
441bf215546Sopenharmony_ci      unsigned mask = 1 << i;
442bf215546Sopenharmony_ci      if ((writemask & mask)) {
443bf215546Sopenharmony_ci         sx->outputs[idx].reg[i] = reg;
444bf215546Sopenharmony_ci      }
445bf215546Sopenharmony_ci   }
446bf215546Sopenharmony_ci}
447bf215546Sopenharmony_ci
448bf215546Sopenharmony_cistatic void
449bf215546Sopenharmony_cidcl_base_input(struct Shader_xlate *sx,
450bf215546Sopenharmony_ci               struct ureg_program *ureg,
451bf215546Sopenharmony_ci               const struct Shader_dst_operand *operand,
452bf215546Sopenharmony_ci               struct ureg_src dcl_reg,
453bf215546Sopenharmony_ci               uint index,
454bf215546Sopenharmony_ci               uint siv_name)
455bf215546Sopenharmony_ci{
456bf215546Sopenharmony_ci   unsigned writemask =
457bf215546Sopenharmony_ci      operand->mask >> D3D10_SB_OPERAND_4_COMPONENT_MASK_SHIFT;
458bf215546Sopenharmony_ci
459bf215546Sopenharmony_ci   if (sx->inputs[index].declared && !sx->inputs[index].overloaded) {
460bf215546Sopenharmony_ci      struct ureg_dst temp = ureg_DECL_temporary(sx->ureg);
461bf215546Sopenharmony_ci
462bf215546Sopenharmony_ci      ureg_MOV(ureg,
463bf215546Sopenharmony_ci               ureg_writemask(temp, sx->inputs[index].writemask),
464bf215546Sopenharmony_ci               swizzle_reg(sx->inputs[index].reg, sx->inputs[index].writemask,
465bf215546Sopenharmony_ci                           sx->inputs[index].siv_name));
466bf215546Sopenharmony_ci      ureg_MOV(ureg, ureg_writemask(temp, writemask),
467bf215546Sopenharmony_ci               swizzle_reg(dcl_reg, writemask, siv_name));
468bf215546Sopenharmony_ci      sx->inputs[index].reg = ureg_src(temp);
469bf215546Sopenharmony_ci      sx->inputs[index].overloaded = TRUE;
470bf215546Sopenharmony_ci      sx->inputs[index].writemask |= writemask;
471bf215546Sopenharmony_ci   } else if (sx->inputs[index].overloaded) {
472bf215546Sopenharmony_ci      struct ureg_dst temp = ureg_dst(sx->inputs[index].reg);
473bf215546Sopenharmony_ci      ureg_MOV(ureg, ureg_writemask(temp, writemask),
474bf215546Sopenharmony_ci               swizzle_reg(dcl_reg, writemask, siv_name));
475bf215546Sopenharmony_ci      sx->inputs[index].writemask |= writemask;
476bf215546Sopenharmony_ci   } else {
477bf215546Sopenharmony_ci      assert(!sx->inputs[index].declared);
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_ci      sx->inputs[index].reg = dcl_reg;
480bf215546Sopenharmony_ci      sx->inputs[index].declared = TRUE;
481bf215546Sopenharmony_ci      sx->inputs[index].writemask = writemask;
482bf215546Sopenharmony_ci      sx->inputs[index].siv_name = siv_name;
483bf215546Sopenharmony_ci   }
484bf215546Sopenharmony_ci}
485bf215546Sopenharmony_ci
486bf215546Sopenharmony_cistatic void
487bf215546Sopenharmony_cidcl_vs_input(struct Shader_xlate *sx,
488bf215546Sopenharmony_ci             struct ureg_program *ureg,
489bf215546Sopenharmony_ci             const struct Shader_dst_operand *dst)
490bf215546Sopenharmony_ci{
491bf215546Sopenharmony_ci   struct ureg_src reg;
492bf215546Sopenharmony_ci   assert(dst->base.index_dim == 1);
493bf215546Sopenharmony_ci   assert(dst->base.index[0].imm < SHADER_MAX_INPUTS);
494bf215546Sopenharmony_ci
495bf215546Sopenharmony_ci   reg = ureg_DECL_vs_input(ureg, dst->base.index[0].imm);
496bf215546Sopenharmony_ci
497bf215546Sopenharmony_ci   dcl_base_input(sx, ureg, dst, reg, dst->base.index[0].imm,
498bf215546Sopenharmony_ci                  D3D10_SB_NAME_UNDEFINED);
499bf215546Sopenharmony_ci}
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_cistatic void
502bf215546Sopenharmony_cidcl_gs_input(struct Shader_xlate *sx,
503bf215546Sopenharmony_ci             struct ureg_program *ureg,
504bf215546Sopenharmony_ci             const struct Shader_dst_operand *dst)
505bf215546Sopenharmony_ci{
506bf215546Sopenharmony_ci   if (dst->base.index_dim == 2) {
507bf215546Sopenharmony_ci      assert(dst->base.index[1].imm < SHADER_MAX_INPUTS);
508bf215546Sopenharmony_ci
509bf215546Sopenharmony_ci      declare_vertices_in(sx, dst->base.index[0].imm);
510bf215546Sopenharmony_ci
511bf215546Sopenharmony_ci      /* XXX: Implement declaration masks in gallium.
512bf215546Sopenharmony_ci       */
513bf215546Sopenharmony_ci      if (!sx->inputs[dst->base.index[1].imm].reg.File) {
514bf215546Sopenharmony_ci         struct ureg_src reg =
515bf215546Sopenharmony_ci            ureg_DECL_input(ureg,
516bf215546Sopenharmony_ci                            TGSI_SEMANTIC_GENERIC,
517bf215546Sopenharmony_ci                            dst->base.index[1].imm,
518bf215546Sopenharmony_ci                            0, 1);
519bf215546Sopenharmony_ci         dcl_base_input(sx, ureg, dst, reg, dst->base.index[1].imm,
520bf215546Sopenharmony_ci                        D3D10_SB_NAME_UNDEFINED);
521bf215546Sopenharmony_ci      }
522bf215546Sopenharmony_ci   } else {
523bf215546Sopenharmony_ci      assert(dst->base.type == D3D10_SB_OPERAND_TYPE_INPUT_PRIMITIVEID);
524bf215546Sopenharmony_ci      assert(dst->base.index_dim == 0);
525bf215546Sopenharmony_ci
526bf215546Sopenharmony_ci      sx->prim_id = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_PRIMID, 0);
527bf215546Sopenharmony_ci   }
528bf215546Sopenharmony_ci}
529bf215546Sopenharmony_ci
530bf215546Sopenharmony_cistatic void
531bf215546Sopenharmony_cidcl_sgv_input(struct Shader_xlate *sx,
532bf215546Sopenharmony_ci              struct ureg_program *ureg,
533bf215546Sopenharmony_ci              const struct Shader_dst_operand *dst,
534bf215546Sopenharmony_ci              uint dcl_siv_name)
535bf215546Sopenharmony_ci{
536bf215546Sopenharmony_ci   struct ureg_src reg;
537bf215546Sopenharmony_ci   assert(dst->base.index_dim == 1);
538bf215546Sopenharmony_ci   assert(dst->base.index[0].imm < SHADER_MAX_INPUTS);
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_ci   reg = ureg_DECL_system_value(ureg, translate_system_name(dcl_siv_name), 0);
541bf215546Sopenharmony_ci
542bf215546Sopenharmony_ci   dcl_base_input(sx, ureg, dst, reg, dst->base.index[0].imm,
543bf215546Sopenharmony_ci                  dcl_siv_name);
544bf215546Sopenharmony_ci}
545bf215546Sopenharmony_ci
546bf215546Sopenharmony_cistatic void
547bf215546Sopenharmony_cidcl_siv_input(struct Shader_xlate *sx,
548bf215546Sopenharmony_ci              struct ureg_program *ureg,
549bf215546Sopenharmony_ci              const struct Shader_dst_operand *dst,
550bf215546Sopenharmony_ci              uint dcl_siv_name)
551bf215546Sopenharmony_ci{
552bf215546Sopenharmony_ci   struct ureg_src reg;
553bf215546Sopenharmony_ci   assert(dst->base.index_dim == 2);
554bf215546Sopenharmony_ci   assert(dst->base.index[1].imm < SHADER_MAX_INPUTS);
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci   declare_vertices_in(sx, dst->base.index[0].imm);
557bf215546Sopenharmony_ci
558bf215546Sopenharmony_ci   reg = ureg_DECL_input(ureg,
559bf215546Sopenharmony_ci                         translate_system_name(dcl_siv_name), 0,
560bf215546Sopenharmony_ci                         0, 1);
561bf215546Sopenharmony_ci
562bf215546Sopenharmony_ci   dcl_base_input(sx, ureg, dst, reg, dst->base.index[1].imm,
563bf215546Sopenharmony_ci                  dcl_siv_name);
564bf215546Sopenharmony_ci}
565bf215546Sopenharmony_ci
566bf215546Sopenharmony_cistatic void
567bf215546Sopenharmony_cidcl_ps_input(struct Shader_xlate *sx,
568bf215546Sopenharmony_ci             struct ureg_program *ureg,
569bf215546Sopenharmony_ci             const struct Shader_dst_operand *dst,
570bf215546Sopenharmony_ci             uint dcl_in_ps_interp)
571bf215546Sopenharmony_ci{
572bf215546Sopenharmony_ci   struct ureg_src reg;
573bf215546Sopenharmony_ci   assert(dst->base.index_dim == 1);
574bf215546Sopenharmony_ci   assert(dst->base.index[0].imm < SHADER_MAX_INPUTS);
575bf215546Sopenharmony_ci
576bf215546Sopenharmony_ci   reg = ureg_DECL_fs_input(ureg,
577bf215546Sopenharmony_ci                            TGSI_SEMANTIC_GENERIC,
578bf215546Sopenharmony_ci                            dst->base.index[0].imm,
579bf215546Sopenharmony_ci                            translate_interpolation(dcl_in_ps_interp));
580bf215546Sopenharmony_ci
581bf215546Sopenharmony_ci   dcl_base_input(sx, ureg, dst, reg, dst->base.index[0].imm,
582bf215546Sopenharmony_ci                  D3D10_SB_NAME_UNDEFINED);
583bf215546Sopenharmony_ci}
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_cistatic void
586bf215546Sopenharmony_cidcl_ps_sgv_input(struct Shader_xlate *sx,
587bf215546Sopenharmony_ci                 struct ureg_program *ureg,
588bf215546Sopenharmony_ci                 const struct Shader_dst_operand *dst,
589bf215546Sopenharmony_ci                 uint dcl_siv_name)
590bf215546Sopenharmony_ci{
591bf215546Sopenharmony_ci   struct ureg_src reg;
592bf215546Sopenharmony_ci   assert(dst->base.index_dim == 1);
593bf215546Sopenharmony_ci   assert(dst->base.index[0].imm < SHADER_MAX_INPUTS);
594bf215546Sopenharmony_ci
595bf215546Sopenharmony_ci   if (dcl_siv_name == D3D10_SB_NAME_POSITION) {
596bf215546Sopenharmony_ci      ureg_property(ureg,
597bf215546Sopenharmony_ci                    TGSI_PROPERTY_FS_COORD_ORIGIN,
598bf215546Sopenharmony_ci                    TGSI_FS_COORD_ORIGIN_UPPER_LEFT);
599bf215546Sopenharmony_ci      ureg_property(ureg,
600bf215546Sopenharmony_ci                    TGSI_PROPERTY_FS_COORD_PIXEL_CENTER,
601bf215546Sopenharmony_ci                    TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER);
602bf215546Sopenharmony_ci   }
603bf215546Sopenharmony_ci
604bf215546Sopenharmony_ci   reg = ureg_DECL_fs_input(ureg,
605bf215546Sopenharmony_ci                            translate_system_name(dcl_siv_name),
606bf215546Sopenharmony_ci                            0,
607bf215546Sopenharmony_ci                            TGSI_INTERPOLATE_CONSTANT);
608bf215546Sopenharmony_ci
609bf215546Sopenharmony_ci   if (dcl_siv_name == D3D10_SB_NAME_IS_FRONT_FACE) {
610bf215546Sopenharmony_ci      /* We need to map gallium's front_face to the one expected
611bf215546Sopenharmony_ci       * by D3D10 */
612bf215546Sopenharmony_ci      struct ureg_dst tmp = ureg_DECL_temporary(ureg);
613bf215546Sopenharmony_ci
614bf215546Sopenharmony_ci      tmp = ureg_writemask(tmp, TGSI_WRITEMASK_X);
615bf215546Sopenharmony_ci
616bf215546Sopenharmony_ci      ureg_CMP(ureg, tmp, reg,
617bf215546Sopenharmony_ci               ureg_imm1i(ureg, 0), ureg_imm1i(ureg, -1));
618bf215546Sopenharmony_ci
619bf215546Sopenharmony_ci      reg = ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X);
620bf215546Sopenharmony_ci   }
621bf215546Sopenharmony_ci
622bf215546Sopenharmony_ci   dcl_base_input(sx, ureg, dst, reg, dst->base.index[0].imm,
623bf215546Sopenharmony_ci                  dcl_siv_name);
624bf215546Sopenharmony_ci}
625bf215546Sopenharmony_ci
626bf215546Sopenharmony_cistatic void
627bf215546Sopenharmony_cidcl_ps_siv_input(struct Shader_xlate *sx,
628bf215546Sopenharmony_ci                 struct ureg_program *ureg,
629bf215546Sopenharmony_ci                 const struct Shader_dst_operand *dst,
630bf215546Sopenharmony_ci                 uint dcl_siv_name, uint dcl_in_ps_interp)
631bf215546Sopenharmony_ci{
632bf215546Sopenharmony_ci   struct ureg_src reg;
633bf215546Sopenharmony_ci   assert(dst->base.index_dim == 1);
634bf215546Sopenharmony_ci   assert(dst->base.index[0].imm < SHADER_MAX_INPUTS);
635bf215546Sopenharmony_ci
636bf215546Sopenharmony_ci   reg = ureg_DECL_fs_input(ureg,
637bf215546Sopenharmony_ci                            translate_system_name(dcl_siv_name),
638bf215546Sopenharmony_ci                            0,
639bf215546Sopenharmony_ci                            translate_interpolation(dcl_in_ps_interp));
640bf215546Sopenharmony_ci
641bf215546Sopenharmony_ci   if (dcl_siv_name == D3D10_SB_NAME_POSITION) {
642bf215546Sopenharmony_ci      /* D3D10 expects reciprocal of interpolated 1/w as 4th component,
643bf215546Sopenharmony_ci       * gallium/GL just interpolated 1/w */
644bf215546Sopenharmony_ci      struct ureg_dst tmp = ureg_DECL_temporary(ureg);
645bf215546Sopenharmony_ci
646bf215546Sopenharmony_ci      ureg_MOV(ureg, tmp, reg);
647bf215546Sopenharmony_ci      ureg_RCP(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W),
648bf215546Sopenharmony_ci               ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_W));
649bf215546Sopenharmony_ci      reg = ureg_src(tmp);
650bf215546Sopenharmony_ci   }
651bf215546Sopenharmony_ci
652bf215546Sopenharmony_ci   dcl_base_input(sx, ureg, dst, reg, dst->base.index[0].imm,
653bf215546Sopenharmony_ci                  dcl_siv_name);
654bf215546Sopenharmony_ci}
655bf215546Sopenharmony_ci
656bf215546Sopenharmony_cistatic struct ureg_src
657bf215546Sopenharmony_citranslate_relative_operand(struct Shader_xlate *sx,
658bf215546Sopenharmony_ci                           const struct Shader_relative_operand *operand)
659bf215546Sopenharmony_ci{
660bf215546Sopenharmony_ci   struct ureg_src reg;
661bf215546Sopenharmony_ci
662bf215546Sopenharmony_ci   switch (operand->type) {
663bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_TEMP:
664bf215546Sopenharmony_ci      assert(operand->index[0].imm < SHADER_MAX_TEMPS);
665bf215546Sopenharmony_ci
666bf215546Sopenharmony_ci      reg = ureg_src(sx->temps[sx->temp_offset + operand->index[0].imm]);
667bf215546Sopenharmony_ci      break;
668bf215546Sopenharmony_ci
669bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INPUT_PRIMITIVEID:
670bf215546Sopenharmony_ci      reg = sx->prim_id;
671bf215546Sopenharmony_ci      break;
672bf215546Sopenharmony_ci
673bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INDEXABLE_TEMP:
674bf215546Sopenharmony_ci      assert(operand->index[1].imm < SHADER_MAX_TEMPS);
675bf215546Sopenharmony_ci
676bf215546Sopenharmony_ci      reg = ureg_src(sx->temps[sx->indexable_temp_offsets[operand->index[0].imm] +
677bf215546Sopenharmony_ci            operand->index[1].imm]);
678bf215546Sopenharmony_ci      break;
679bf215546Sopenharmony_ci
680bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INPUT:
681bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_OUTPUT:
682bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_IMMEDIATE32:
683bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_IMMEDIATE64:
684bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_SAMPLER:
685bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_RESOURCE:
686bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER:
687bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER:
688bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_LABEL:
689bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_OUTPUT_DEPTH:
690bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_NULL:
691bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_RASTERIZER:
692bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_OUTPUT_COVERAGE_MASK:
693bf215546Sopenharmony_ci      LOG_UNSUPPORTED(TRUE);
694bf215546Sopenharmony_ci      reg = ureg_src(ureg_DECL_temporary(sx->ureg));
695bf215546Sopenharmony_ci      break;
696bf215546Sopenharmony_ci
697bf215546Sopenharmony_ci   default:
698bf215546Sopenharmony_ci      assert(0);                /* should never happen */
699bf215546Sopenharmony_ci      reg = ureg_src(ureg_DECL_temporary(sx->ureg));
700bf215546Sopenharmony_ci   }
701bf215546Sopenharmony_ci
702bf215546Sopenharmony_ci   reg = ureg_scalar(reg, operand->comp);
703bf215546Sopenharmony_ci   return reg;
704bf215546Sopenharmony_ci}
705bf215546Sopenharmony_ci
706bf215546Sopenharmony_cistatic struct ureg_dst
707bf215546Sopenharmony_citranslate_operand(struct Shader_xlate *sx,
708bf215546Sopenharmony_ci                  const struct Shader_operand *operand,
709bf215546Sopenharmony_ci                  unsigned writemask)
710bf215546Sopenharmony_ci{
711bf215546Sopenharmony_ci   struct ureg_dst reg;
712bf215546Sopenharmony_ci
713bf215546Sopenharmony_ci   switch (operand->type) {
714bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_TEMP:
715bf215546Sopenharmony_ci      assert(operand->index_dim == 1);
716bf215546Sopenharmony_ci      assert(operand->index[0].index_rep == D3D10_SB_OPERAND_INDEX_IMMEDIATE32);
717bf215546Sopenharmony_ci      assert(operand->index[0].imm < SHADER_MAX_TEMPS);
718bf215546Sopenharmony_ci
719bf215546Sopenharmony_ci      reg = sx->temps[sx->temp_offset + operand->index[0].imm];
720bf215546Sopenharmony_ci      break;
721bf215546Sopenharmony_ci
722bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_OUTPUT:
723bf215546Sopenharmony_ci      assert(operand->index_dim == 1);
724bf215546Sopenharmony_ci      assert(operand->index[0].imm < SHADER_MAX_OUTPUTS);
725bf215546Sopenharmony_ci
726bf215546Sopenharmony_ci      if (operand->index[0].index_rep == D3D10_SB_OPERAND_INDEX_IMMEDIATE32) {
727bf215546Sopenharmony_ci         if (!writemask) {
728bf215546Sopenharmony_ci            reg = sx->outputs[operand->index[0].imm].reg[0];
729bf215546Sopenharmony_ci         } else {
730bf215546Sopenharmony_ci            unsigned i;
731bf215546Sopenharmony_ci            for (i = 0; i < 4; ++i) {
732bf215546Sopenharmony_ci               unsigned mask = 1 << i;
733bf215546Sopenharmony_ci               if ((writemask & mask)) {
734bf215546Sopenharmony_ci                  reg = sx->outputs[operand->index[0].imm].reg[i];
735bf215546Sopenharmony_ci                  break;
736bf215546Sopenharmony_ci               }
737bf215546Sopenharmony_ci            }
738bf215546Sopenharmony_ci         }
739bf215546Sopenharmony_ci      } else {
740bf215546Sopenharmony_ci         struct ureg_src addr =
741bf215546Sopenharmony_ci            translate_relative_operand(sx, &operand->index[0].rel);
742bf215546Sopenharmony_ci         assert(operand->index[0].index_rep == D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE);
743bf215546Sopenharmony_ci         reg = ureg_dst_indirect(sx->outputs[operand->index[0].imm].reg[0], addr);
744bf215546Sopenharmony_ci      }
745bf215546Sopenharmony_ci      break;
746bf215546Sopenharmony_ci
747bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_OUTPUT_DEPTH:
748bf215546Sopenharmony_ci      assert(operand->index_dim == 0);
749bf215546Sopenharmony_ci
750bf215546Sopenharmony_ci      reg = sx->output_depth;
751bf215546Sopenharmony_ci      break;
752bf215546Sopenharmony_ci
753bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INPUT_PRIMITIVEID:
754bf215546Sopenharmony_ci      assert(operand->index_dim == 0);
755bf215546Sopenharmony_ci
756bf215546Sopenharmony_ci      reg = ureg_dst(sx->prim_id);
757bf215546Sopenharmony_ci      break;
758bf215546Sopenharmony_ci
759bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INPUT:
760bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INDEXABLE_TEMP:
761bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_IMMEDIATE32:
762bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_IMMEDIATE64:
763bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_SAMPLER:
764bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_RESOURCE:
765bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER:
766bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER:
767bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_LABEL:
768bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_NULL:
769bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_RASTERIZER:
770bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_OUTPUT_COVERAGE_MASK:
771bf215546Sopenharmony_ci      /* XXX: Translate more operands types.
772bf215546Sopenharmony_ci       */
773bf215546Sopenharmony_ci      LOG_UNSUPPORTED(TRUE);
774bf215546Sopenharmony_ci      reg = ureg_DECL_temporary(sx->ureg);
775bf215546Sopenharmony_ci   }
776bf215546Sopenharmony_ci
777bf215546Sopenharmony_ci   return reg;
778bf215546Sopenharmony_ci}
779bf215546Sopenharmony_ci
780bf215546Sopenharmony_cistatic struct ureg_src
781bf215546Sopenharmony_citranslate_indexable_temp(struct Shader_xlate *sx,
782bf215546Sopenharmony_ci                         const struct Shader_operand *operand)
783bf215546Sopenharmony_ci{
784bf215546Sopenharmony_ci   struct ureg_src reg;
785bf215546Sopenharmony_ci   switch (operand->index[1].index_rep) {
786bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_INDEX_IMMEDIATE32:
787bf215546Sopenharmony_ci      reg = ureg_src(
788bf215546Sopenharmony_ci         sx->temps[sx->indexable_temp_offsets[operand->index[0].imm] +
789bf215546Sopenharmony_ci                   operand->index[1].imm]);
790bf215546Sopenharmony_ci      break;
791bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_INDEX_RELATIVE:
792bf215546Sopenharmony_ci      reg = ureg_src_indirect(
793bf215546Sopenharmony_ci         ureg_src(sx->temps[
794bf215546Sopenharmony_ci                     sx->indexable_temp_offsets[operand->index[0].imm]]),
795bf215546Sopenharmony_ci         translate_relative_operand(sx,
796bf215546Sopenharmony_ci                                    &operand->index[1].rel));
797bf215546Sopenharmony_ci      break;
798bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE:
799bf215546Sopenharmony_ci      reg = ureg_src_indirect(
800bf215546Sopenharmony_ci         ureg_src(sx->temps[
801bf215546Sopenharmony_ci                     operand->index[1].imm +
802bf215546Sopenharmony_ci                     sx->indexable_temp_offsets[operand->index[0].imm]]),
803bf215546Sopenharmony_ci         translate_relative_operand(sx,
804bf215546Sopenharmony_ci                                    &operand->index[1].rel));
805bf215546Sopenharmony_ci      break;
806bf215546Sopenharmony_ci   default:
807bf215546Sopenharmony_ci      /* XXX: Other index representations.
808bf215546Sopenharmony_ci       */
809bf215546Sopenharmony_ci      LOG_UNSUPPORTED(TRUE);
810bf215546Sopenharmony_ci      reg = ureg_src(ureg_DECL_temporary(sx->ureg));
811bf215546Sopenharmony_ci   }
812bf215546Sopenharmony_ci   return reg;
813bf215546Sopenharmony_ci}
814bf215546Sopenharmony_ci
815bf215546Sopenharmony_cistatic struct ureg_dst
816bf215546Sopenharmony_citranslate_dst_operand(struct Shader_xlate *sx,
817bf215546Sopenharmony_ci                      const struct Shader_dst_operand *operand,
818bf215546Sopenharmony_ci                      boolean saturate)
819bf215546Sopenharmony_ci{
820bf215546Sopenharmony_ci   struct ureg_dst reg;
821bf215546Sopenharmony_ci   unsigned writemask =
822bf215546Sopenharmony_ci      operand->mask >> D3D10_SB_OPERAND_4_COMPONENT_MASK_SHIFT;
823bf215546Sopenharmony_ci
824bf215546Sopenharmony_ci   assert((D3D10_SB_OPERAND_4_COMPONENT_MASK_SHIFT) == 4);
825bf215546Sopenharmony_ci   assert((D3D10_SB_OPERAND_4_COMPONENT_MASK_X >> 4) == TGSI_WRITEMASK_X);
826bf215546Sopenharmony_ci   assert((D3D10_SB_OPERAND_4_COMPONENT_MASK_Y >> 4) == TGSI_WRITEMASK_Y);
827bf215546Sopenharmony_ci   assert((D3D10_SB_OPERAND_4_COMPONENT_MASK_Z >> 4) == TGSI_WRITEMASK_Z);
828bf215546Sopenharmony_ci   assert((D3D10_SB_OPERAND_4_COMPONENT_MASK_W >> 4) == TGSI_WRITEMASK_W);
829bf215546Sopenharmony_ci
830bf215546Sopenharmony_ci   switch (operand->base.type) {
831bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INDEXABLE_TEMP:
832bf215546Sopenharmony_ci      assert(operand->base.index_dim == 2);
833bf215546Sopenharmony_ci      assert(operand->base.index[0].index_rep == D3D10_SB_OPERAND_INDEX_IMMEDIATE32);
834bf215546Sopenharmony_ci      assert(operand->base.index[0].imm < SHADER_MAX_INDEXABLE_TEMPS);
835bf215546Sopenharmony_ci
836bf215546Sopenharmony_ci      reg = ureg_dst(translate_indexable_temp(sx, &operand->base));
837bf215546Sopenharmony_ci      break;
838bf215546Sopenharmony_ci
839bf215546Sopenharmony_ci   default:
840bf215546Sopenharmony_ci      reg = translate_operand(sx, &operand->base, writemask);
841bf215546Sopenharmony_ci   }
842bf215546Sopenharmony_ci
843bf215546Sopenharmony_ci   /* oDepth often has an empty writemask */
844bf215546Sopenharmony_ci   if (operand->base.type != D3D10_SB_OPERAND_TYPE_OUTPUT_DEPTH) {
845bf215546Sopenharmony_ci      reg = ureg_writemask(reg, writemask);
846bf215546Sopenharmony_ci   }
847bf215546Sopenharmony_ci
848bf215546Sopenharmony_ci   if (saturate) {
849bf215546Sopenharmony_ci      reg = ureg_saturate(reg);
850bf215546Sopenharmony_ci   }
851bf215546Sopenharmony_ci
852bf215546Sopenharmony_ci   return reg;
853bf215546Sopenharmony_ci}
854bf215546Sopenharmony_ci
855bf215546Sopenharmony_cistatic struct ureg_src
856bf215546Sopenharmony_citranslate_src_operand(struct Shader_xlate *sx,
857bf215546Sopenharmony_ci                      const struct Shader_src_operand *operand,
858bf215546Sopenharmony_ci                      const enum dx10_opcode_format format)
859bf215546Sopenharmony_ci{
860bf215546Sopenharmony_ci   struct ureg_src reg;
861bf215546Sopenharmony_ci
862bf215546Sopenharmony_ci   switch (operand->base.type) {
863bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INPUT:
864bf215546Sopenharmony_ci      if (operand->base.index_dim == 1) {
865bf215546Sopenharmony_ci         switch (operand->base.index[0].index_rep) {
866bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_INDEX_IMMEDIATE32:
867bf215546Sopenharmony_ci            assert(operand->base.index[0].imm < SHADER_MAX_INPUTS);
868bf215546Sopenharmony_ci            reg = sx->inputs[operand->base.index[0].imm].reg;
869bf215546Sopenharmony_ci            break;
870bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_INDEX_RELATIVE: {
871bf215546Sopenharmony_ci            struct ureg_src tmp =
872bf215546Sopenharmony_ci               translate_relative_operand(sx, &operand->base.index[0].rel);
873bf215546Sopenharmony_ci            reg = ureg_src_indirect(sx->inputs[0].reg, tmp);
874bf215546Sopenharmony_ci         }
875bf215546Sopenharmony_ci            break;
876bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE: {
877bf215546Sopenharmony_ci            struct ureg_src tmp =
878bf215546Sopenharmony_ci               translate_relative_operand(sx, &operand->base.index[0].rel);
879bf215546Sopenharmony_ci            reg = ureg_src_indirect(sx->inputs[operand->base.index[0].imm].reg, tmp);
880bf215546Sopenharmony_ci         }
881bf215546Sopenharmony_ci            break;
882bf215546Sopenharmony_ci         default:
883bf215546Sopenharmony_ci            /* XXX: Other index representations.
884bf215546Sopenharmony_ci             */
885bf215546Sopenharmony_ci            LOG_UNSUPPORTED(TRUE);
886bf215546Sopenharmony_ci
887bf215546Sopenharmony_ci         }
888bf215546Sopenharmony_ci      } else {
889bf215546Sopenharmony_ci         assert(operand->base.index_dim == 2);
890bf215546Sopenharmony_ci         assert(operand->base.index[1].imm < SHADER_MAX_INPUTS);
891bf215546Sopenharmony_ci
892bf215546Sopenharmony_ci         switch (operand->base.index[1].index_rep) {
893bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_INDEX_IMMEDIATE32:
894bf215546Sopenharmony_ci            reg = sx->inputs[operand->base.index[1].imm].reg;
895bf215546Sopenharmony_ci            break;
896bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_INDEX_RELATIVE: {
897bf215546Sopenharmony_ci            struct ureg_src tmp =
898bf215546Sopenharmony_ci               translate_relative_operand(sx, &operand->base.index[1].rel);
899bf215546Sopenharmony_ci            reg = ureg_src_indirect(sx->inputs[0].reg, tmp);
900bf215546Sopenharmony_ci         }
901bf215546Sopenharmony_ci            break;
902bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE: {
903bf215546Sopenharmony_ci            struct ureg_src tmp =
904bf215546Sopenharmony_ci               translate_relative_operand(sx, &operand->base.index[1].rel);
905bf215546Sopenharmony_ci            reg = ureg_src_indirect(sx->inputs[operand->base.index[1].imm].reg, tmp);
906bf215546Sopenharmony_ci         }
907bf215546Sopenharmony_ci            break;
908bf215546Sopenharmony_ci         default:
909bf215546Sopenharmony_ci            /* XXX: Other index representations.
910bf215546Sopenharmony_ci             */
911bf215546Sopenharmony_ci            LOG_UNSUPPORTED(TRUE);
912bf215546Sopenharmony_ci         }
913bf215546Sopenharmony_ci
914bf215546Sopenharmony_ci         switch (operand->base.index[0].index_rep) {
915bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_INDEX_IMMEDIATE32:
916bf215546Sopenharmony_ci            reg = ureg_src_dimension(reg, operand->base.index[0].imm);
917bf215546Sopenharmony_ci            break;
918bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_INDEX_RELATIVE:{
919bf215546Sopenharmony_ci            struct ureg_src tmp =
920bf215546Sopenharmony_ci               translate_relative_operand(sx, &operand->base.index[0].rel);
921bf215546Sopenharmony_ci            reg = ureg_src_dimension_indirect(reg, tmp, 0);
922bf215546Sopenharmony_ci         }
923bf215546Sopenharmony_ci            break;
924bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE: {
925bf215546Sopenharmony_ci            struct ureg_src tmp =
926bf215546Sopenharmony_ci               translate_relative_operand(sx, &operand->base.index[0].rel);
927bf215546Sopenharmony_ci            reg = ureg_src_dimension_indirect(reg, tmp, operand->base.index[0].imm);
928bf215546Sopenharmony_ci         }
929bf215546Sopenharmony_ci            break;
930bf215546Sopenharmony_ci         default:
931bf215546Sopenharmony_ci            /* XXX: Other index representations.
932bf215546Sopenharmony_ci             */
933bf215546Sopenharmony_ci            LOG_UNSUPPORTED(TRUE);
934bf215546Sopenharmony_ci         }
935bf215546Sopenharmony_ci      }
936bf215546Sopenharmony_ci      break;
937bf215546Sopenharmony_ci
938bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INDEXABLE_TEMP:
939bf215546Sopenharmony_ci      assert(operand->base.index_dim == 2);
940bf215546Sopenharmony_ci      assert(operand->base.index[0].index_rep == D3D10_SB_OPERAND_INDEX_IMMEDIATE32);
941bf215546Sopenharmony_ci      assert(operand->base.index[0].imm < SHADER_MAX_INDEXABLE_TEMPS);
942bf215546Sopenharmony_ci
943bf215546Sopenharmony_ci      reg = translate_indexable_temp(sx, &operand->base);
944bf215546Sopenharmony_ci      break;
945bf215546Sopenharmony_ci
946bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_IMMEDIATE32:
947bf215546Sopenharmony_ci      switch (format) {
948bf215546Sopenharmony_ci      case OF_FLOAT:
949bf215546Sopenharmony_ci         reg = ureg_imm4f(sx->ureg,
950bf215546Sopenharmony_ci                          operand->imm[0].f32,
951bf215546Sopenharmony_ci                          operand->imm[1].f32,
952bf215546Sopenharmony_ci                          operand->imm[2].f32,
953bf215546Sopenharmony_ci                          operand->imm[3].f32);
954bf215546Sopenharmony_ci         break;
955bf215546Sopenharmony_ci      case OF_INT:
956bf215546Sopenharmony_ci         reg = ureg_imm4i(sx->ureg,
957bf215546Sopenharmony_ci                          operand->imm[0].i32,
958bf215546Sopenharmony_ci                          operand->imm[1].i32,
959bf215546Sopenharmony_ci                          operand->imm[2].i32,
960bf215546Sopenharmony_ci                          operand->imm[3].i32);
961bf215546Sopenharmony_ci         break;
962bf215546Sopenharmony_ci      case OF_UINT:
963bf215546Sopenharmony_ci         reg = ureg_imm4u(sx->ureg,
964bf215546Sopenharmony_ci                          operand->imm[0].u32,
965bf215546Sopenharmony_ci                          operand->imm[1].u32,
966bf215546Sopenharmony_ci                          operand->imm[2].u32,
967bf215546Sopenharmony_ci                          operand->imm[3].u32);
968bf215546Sopenharmony_ci         break;
969bf215546Sopenharmony_ci      default:
970bf215546Sopenharmony_ci         assert(0);
971bf215546Sopenharmony_ci         reg = ureg_src(ureg_DECL_temporary(sx->ureg));
972bf215546Sopenharmony_ci      }
973bf215546Sopenharmony_ci      break;
974bf215546Sopenharmony_ci
975bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_SAMPLER:
976bf215546Sopenharmony_ci      assert(operand->base.index_dim == 1);
977bf215546Sopenharmony_ci      assert(operand->base.index[0].index_rep == D3D10_SB_OPERAND_INDEX_IMMEDIATE32);
978bf215546Sopenharmony_ci      assert(operand->base.index[0].imm < SHADER_MAX_SAMPLERS);
979bf215546Sopenharmony_ci
980bf215546Sopenharmony_ci      reg = sx->samplers[operand->base.index[0].imm];
981bf215546Sopenharmony_ci      break;
982bf215546Sopenharmony_ci
983bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_RESOURCE:
984bf215546Sopenharmony_ci      assert(operand->base.index_dim == 1);
985bf215546Sopenharmony_ci      assert(operand->base.index[0].index_rep == D3D10_SB_OPERAND_INDEX_IMMEDIATE32);
986bf215546Sopenharmony_ci      assert(operand->base.index[0].imm < SHADER_MAX_RESOURCES);
987bf215546Sopenharmony_ci
988bf215546Sopenharmony_ci      reg = sx->sv[operand->base.index[0].imm];
989bf215546Sopenharmony_ci      break;
990bf215546Sopenharmony_ci
991bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER:
992bf215546Sopenharmony_ci      assert(operand->base.index_dim == 2);
993bf215546Sopenharmony_ci
994bf215546Sopenharmony_ci      assert(operand->base.index[0].index_rep == D3D10_SB_OPERAND_INDEX_IMMEDIATE32);
995bf215546Sopenharmony_ci      assert(operand->base.index[0].imm < PIPE_MAX_CONSTANT_BUFFERS);
996bf215546Sopenharmony_ci
997bf215546Sopenharmony_ci      switch (operand->base.index[1].index_rep) {
998bf215546Sopenharmony_ci      case D3D10_SB_OPERAND_INDEX_IMMEDIATE32:
999bf215546Sopenharmony_ci         assert(operand->base.index[1].imm < SHADER_MAX_CONSTS);
1000bf215546Sopenharmony_ci
1001bf215546Sopenharmony_ci         reg = ureg_src_register(TGSI_FILE_CONSTANT, operand->base.index[1].imm);
1002bf215546Sopenharmony_ci         reg = ureg_src_dimension(reg, operand->base.index[0].imm);
1003bf215546Sopenharmony_ci         break;
1004bf215546Sopenharmony_ci      case D3D10_SB_OPERAND_INDEX_RELATIVE:
1005bf215546Sopenharmony_ci      case D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE:
1006bf215546Sopenharmony_ci         reg = ureg_src_register(TGSI_FILE_CONSTANT, operand->base.index[1].imm);
1007bf215546Sopenharmony_ci         reg = ureg_src_indirect(
1008bf215546Sopenharmony_ci            reg,
1009bf215546Sopenharmony_ci            translate_relative_operand(sx, &operand->base.index[1].rel));
1010bf215546Sopenharmony_ci         reg = ureg_src_dimension(reg, operand->base.index[0].imm);
1011bf215546Sopenharmony_ci         break;
1012bf215546Sopenharmony_ci      default:
1013bf215546Sopenharmony_ci         /* XXX: Other index representations.
1014bf215546Sopenharmony_ci          */
1015bf215546Sopenharmony_ci         LOG_UNSUPPORTED(TRUE);
1016bf215546Sopenharmony_ci      }
1017bf215546Sopenharmony_ci
1018bf215546Sopenharmony_ci      break;
1019bf215546Sopenharmony_ci
1020bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER:
1021bf215546Sopenharmony_ci      assert(operand->base.index_dim == 1);
1022bf215546Sopenharmony_ci
1023bf215546Sopenharmony_ci      switch (operand->base.index[0].index_rep) {
1024bf215546Sopenharmony_ci      case D3D10_SB_OPERAND_INDEX_IMMEDIATE32:
1025bf215546Sopenharmony_ci         reg = sx->imms;
1026bf215546Sopenharmony_ci         reg.Index += operand->base.index[0].imm;
1027bf215546Sopenharmony_ci         break;
1028bf215546Sopenharmony_ci      case D3D10_SB_OPERAND_INDEX_RELATIVE:
1029bf215546Sopenharmony_ci      case D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE:
1030bf215546Sopenharmony_ci         reg = sx->imms;
1031bf215546Sopenharmony_ci         reg.Index += operand->base.index[0].imm;
1032bf215546Sopenharmony_ci         reg = ureg_src_indirect(
1033bf215546Sopenharmony_ci            sx->imms,
1034bf215546Sopenharmony_ci            translate_relative_operand(sx, &operand->base.index[0].rel));
1035bf215546Sopenharmony_ci         break;
1036bf215546Sopenharmony_ci      default:
1037bf215546Sopenharmony_ci         /* XXX: Other index representations.
1038bf215546Sopenharmony_ci          */
1039bf215546Sopenharmony_ci         LOG_UNSUPPORTED(TRUE);
1040bf215546Sopenharmony_ci      }
1041bf215546Sopenharmony_ci      break;
1042bf215546Sopenharmony_ci
1043bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_TYPE_INPUT_PRIMITIVEID:
1044bf215546Sopenharmony_ci      reg = sx->prim_id;
1045bf215546Sopenharmony_ci      break;
1046bf215546Sopenharmony_ci
1047bf215546Sopenharmony_ci   default:
1048bf215546Sopenharmony_ci      reg = ureg_src(translate_operand(sx, &operand->base, 0));
1049bf215546Sopenharmony_ci   }
1050bf215546Sopenharmony_ci
1051bf215546Sopenharmony_ci   reg = ureg_swizzle(reg,
1052bf215546Sopenharmony_ci                      operand->swizzle[0],
1053bf215546Sopenharmony_ci                      operand->swizzle[1],
1054bf215546Sopenharmony_ci                      operand->swizzle[2],
1055bf215546Sopenharmony_ci                      operand->swizzle[3]);
1056bf215546Sopenharmony_ci
1057bf215546Sopenharmony_ci   switch (operand->modifier) {
1058bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_MODIFIER_NONE:
1059bf215546Sopenharmony_ci      break;
1060bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_MODIFIER_NEG:
1061bf215546Sopenharmony_ci      reg = ureg_negate(reg);
1062bf215546Sopenharmony_ci      break;
1063bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_MODIFIER_ABS:
1064bf215546Sopenharmony_ci      reg = ureg_abs(reg);
1065bf215546Sopenharmony_ci      break;
1066bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_MODIFIER_ABSNEG:
1067bf215546Sopenharmony_ci      reg = ureg_negate(ureg_abs(reg));
1068bf215546Sopenharmony_ci      break;
1069bf215546Sopenharmony_ci   default:
1070bf215546Sopenharmony_ci      assert(0);
1071bf215546Sopenharmony_ci   }
1072bf215546Sopenharmony_ci
1073bf215546Sopenharmony_ci   return reg;
1074bf215546Sopenharmony_ci}
1075bf215546Sopenharmony_ci
1076bf215546Sopenharmony_cistatic uint
1077bf215546Sopenharmony_citranslate_resource_dimension(D3D10_SB_RESOURCE_DIMENSION dim)
1078bf215546Sopenharmony_ci{
1079bf215546Sopenharmony_ci   switch (dim) {
1080bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_UNKNOWN:
1081bf215546Sopenharmony_ci      return TGSI_TEXTURE_UNKNOWN;
1082bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_BUFFER:
1083bf215546Sopenharmony_ci      return TGSI_TEXTURE_BUFFER;
1084bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_TEXTURE1D:
1085bf215546Sopenharmony_ci      return TGSI_TEXTURE_1D;
1086bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_TEXTURE2D:
1087bf215546Sopenharmony_ci      return TGSI_TEXTURE_2D;
1088bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_TEXTURE2DMS:
1089bf215546Sopenharmony_ci      return TGSI_TEXTURE_2D_MSAA;
1090bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_TEXTURE3D:
1091bf215546Sopenharmony_ci      return TGSI_TEXTURE_3D;
1092bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_TEXTURECUBE:
1093bf215546Sopenharmony_ci      return TGSI_TEXTURE_CUBE;
1094bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_TEXTURE1DARRAY:
1095bf215546Sopenharmony_ci      return TGSI_TEXTURE_1D_ARRAY;
1096bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_TEXTURE2DARRAY:
1097bf215546Sopenharmony_ci      return TGSI_TEXTURE_2D_ARRAY;
1098bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_TEXTURE2DMSARRAY:
1099bf215546Sopenharmony_ci      return TGSI_TEXTURE_2D_ARRAY_MSAA;
1100bf215546Sopenharmony_ci   case D3D10_SB_RESOURCE_DIMENSION_TEXTURECUBEARRAY:
1101bf215546Sopenharmony_ci      return TGSI_TEXTURE_CUBE_ARRAY;
1102bf215546Sopenharmony_ci   default:
1103bf215546Sopenharmony_ci      assert(0);
1104bf215546Sopenharmony_ci      return TGSI_TEXTURE_UNKNOWN;
1105bf215546Sopenharmony_ci   }
1106bf215546Sopenharmony_ci}
1107bf215546Sopenharmony_ci
1108bf215546Sopenharmony_cistatic uint
1109bf215546Sopenharmony_citexture_dim_from_tgsi_target(unsigned tgsi_target)
1110bf215546Sopenharmony_ci{
1111bf215546Sopenharmony_ci   switch (tgsi_target) {
1112bf215546Sopenharmony_ci   case TGSI_TEXTURE_BUFFER:
1113bf215546Sopenharmony_ci   case TGSI_TEXTURE_1D:
1114bf215546Sopenharmony_ci   case TGSI_TEXTURE_1D_ARRAY:
1115bf215546Sopenharmony_ci      return 1;
1116bf215546Sopenharmony_ci   case TGSI_TEXTURE_2D:
1117bf215546Sopenharmony_ci   case TGSI_TEXTURE_2D_MSAA:
1118bf215546Sopenharmony_ci   case TGSI_TEXTURE_CUBE:
1119bf215546Sopenharmony_ci   case TGSI_TEXTURE_2D_ARRAY:
1120bf215546Sopenharmony_ci   case TGSI_TEXTURE_2D_ARRAY_MSAA:
1121bf215546Sopenharmony_ci      return 2;
1122bf215546Sopenharmony_ci   case TGSI_TEXTURE_3D:
1123bf215546Sopenharmony_ci      return 3;
1124bf215546Sopenharmony_ci   case TGSI_TEXTURE_UNKNOWN:
1125bf215546Sopenharmony_ci   default:
1126bf215546Sopenharmony_ci      assert(0);
1127bf215546Sopenharmony_ci      return 1;
1128bf215546Sopenharmony_ci   }
1129bf215546Sopenharmony_ci}
1130bf215546Sopenharmony_ci
1131bf215546Sopenharmony_cistatic boolean
1132bf215546Sopenharmony_cioperand_is_scalar(const struct Shader_src_operand *operand)
1133bf215546Sopenharmony_ci{
1134bf215546Sopenharmony_ci   return operand->swizzle[0] == operand->swizzle[1] &&
1135bf215546Sopenharmony_ci          operand->swizzle[1] == operand->swizzle[2] &&
1136bf215546Sopenharmony_ci          operand->swizzle[2] == operand->swizzle[3];
1137bf215546Sopenharmony_ci}
1138bf215546Sopenharmony_ci
1139bf215546Sopenharmony_cistatic void
1140bf215546Sopenharmony_ciShader_add_call(struct Shader_xlate *sx,
1141bf215546Sopenharmony_ci                unsigned d3d_label,
1142bf215546Sopenharmony_ci                unsigned tgsi_label_token)
1143bf215546Sopenharmony_ci{
1144bf215546Sopenharmony_ci   ASSERT(sx->num_calls < sx->max_calls);
1145bf215546Sopenharmony_ci
1146bf215546Sopenharmony_ci   sx->calls[sx->num_calls].d3d_label = d3d_label;
1147bf215546Sopenharmony_ci   sx->calls[sx->num_calls].tgsi_label_token = tgsi_label_token;
1148bf215546Sopenharmony_ci   sx->num_calls++;
1149bf215546Sopenharmony_ci}
1150bf215546Sopenharmony_ci
1151bf215546Sopenharmony_cistatic void
1152bf215546Sopenharmony_ciShader_add_label(struct Shader_xlate *sx,
1153bf215546Sopenharmony_ci                 unsigned d3d_label,
1154bf215546Sopenharmony_ci                 unsigned tgsi_insn_no)
1155bf215546Sopenharmony_ci{
1156bf215546Sopenharmony_ci   ASSERT(sx->num_labels < sx->max_labels);
1157bf215546Sopenharmony_ci
1158bf215546Sopenharmony_ci   sx->labels[sx->num_labels].d3d_label = d3d_label;
1159bf215546Sopenharmony_ci   sx->labels[sx->num_labels].tgsi_insn_no = tgsi_insn_no;
1160bf215546Sopenharmony_ci   sx->num_labels++;
1161bf215546Sopenharmony_ci}
1162bf215546Sopenharmony_ci
1163bf215546Sopenharmony_ci
1164bf215546Sopenharmony_cistatic void
1165bf215546Sopenharmony_cisample_ureg_emit(struct ureg_program *ureg,
1166bf215546Sopenharmony_ci                 unsigned tgsi_opcode,
1167bf215546Sopenharmony_ci                 unsigned num_src,
1168bf215546Sopenharmony_ci                 struct Shader_opcode *opcode,
1169bf215546Sopenharmony_ci                 struct ureg_dst dst,
1170bf215546Sopenharmony_ci                 struct ureg_src *src)
1171bf215546Sopenharmony_ci{
1172bf215546Sopenharmony_ci   unsigned num_offsets = 0;
1173bf215546Sopenharmony_ci   struct tgsi_texture_offset texoffsets;
1174bf215546Sopenharmony_ci
1175bf215546Sopenharmony_ci   memset(&texoffsets, 0, sizeof texoffsets);
1176bf215546Sopenharmony_ci
1177bf215546Sopenharmony_ci   if (opcode->imm_texel_offset.u ||
1178bf215546Sopenharmony_ci       opcode->imm_texel_offset.v ||
1179bf215546Sopenharmony_ci       opcode->imm_texel_offset.w) {
1180bf215546Sopenharmony_ci      struct ureg_src offsetreg;
1181bf215546Sopenharmony_ci      num_offsets = 1;
1182bf215546Sopenharmony_ci      /* don't actually always need all 3 values */
1183bf215546Sopenharmony_ci      offsetreg = ureg_imm3i(ureg,
1184bf215546Sopenharmony_ci                             opcode->imm_texel_offset.u,
1185bf215546Sopenharmony_ci                             opcode->imm_texel_offset.v,
1186bf215546Sopenharmony_ci                             opcode->imm_texel_offset.w);
1187bf215546Sopenharmony_ci      texoffsets.File = offsetreg.File;
1188bf215546Sopenharmony_ci      texoffsets.Index = offsetreg.Index;
1189bf215546Sopenharmony_ci      texoffsets.SwizzleX = offsetreg.SwizzleX;
1190bf215546Sopenharmony_ci      texoffsets.SwizzleY = offsetreg.SwizzleY;
1191bf215546Sopenharmony_ci      texoffsets.SwizzleZ = offsetreg.SwizzleZ;
1192bf215546Sopenharmony_ci   }
1193bf215546Sopenharmony_ci
1194bf215546Sopenharmony_ci   ureg_tex_insn(ureg,
1195bf215546Sopenharmony_ci                 tgsi_opcode,
1196bf215546Sopenharmony_ci                 &dst, 1,
1197bf215546Sopenharmony_ci                 TGSI_TEXTURE_UNKNOWN,
1198bf215546Sopenharmony_ci                 TGSI_RETURN_TYPE_UNKNOWN,
1199bf215546Sopenharmony_ci                 &texoffsets, num_offsets,
1200bf215546Sopenharmony_ci                 src, num_src);
1201bf215546Sopenharmony_ci}
1202bf215546Sopenharmony_ci
1203bf215546Sopenharmony_citypedef void (*unary_ureg_func)(struct ureg_program *ureg, struct ureg_dst dst,
1204bf215546Sopenharmony_ci                                struct ureg_src src);
1205bf215546Sopenharmony_cistatic void
1206bf215546Sopenharmony_ciexpand_unary_to_scalarf(struct ureg_program *ureg, unary_ureg_func func,
1207bf215546Sopenharmony_ci                        struct Shader_xlate *sx, struct Shader_opcode *opcode)
1208bf215546Sopenharmony_ci{
1209bf215546Sopenharmony_ci   struct ureg_dst tmp = ureg_DECL_temporary(ureg);
1210bf215546Sopenharmony_ci   struct ureg_dst dst = translate_dst_operand(sx, &opcode->dst[0],
1211bf215546Sopenharmony_ci                                               opcode->saturate);
1212bf215546Sopenharmony_ci   struct ureg_src src = translate_src_operand(sx, &opcode->src[0], OF_FLOAT);
1213bf215546Sopenharmony_ci   struct ureg_dst scalar_dst;
1214bf215546Sopenharmony_ci   ureg_MOV(ureg, tmp, src);
1215bf215546Sopenharmony_ci   src = ureg_src(tmp);
1216bf215546Sopenharmony_ci
1217bf215546Sopenharmony_ci   scalar_dst = ureg_writemask(dst, TGSI_WRITEMASK_X);
1218bf215546Sopenharmony_ci   if (scalar_dst.WriteMask != TGSI_WRITEMASK_NONE) {
1219bf215546Sopenharmony_ci      func(ureg, scalar_dst,
1220bf215546Sopenharmony_ci           ureg_scalar(src, TGSI_SWIZZLE_X));
1221bf215546Sopenharmony_ci   }
1222bf215546Sopenharmony_ci   scalar_dst = ureg_writemask(dst, TGSI_WRITEMASK_Y);
1223bf215546Sopenharmony_ci   if (scalar_dst.WriteMask != TGSI_WRITEMASK_NONE) {
1224bf215546Sopenharmony_ci      func(ureg, scalar_dst,
1225bf215546Sopenharmony_ci           ureg_scalar(src, TGSI_SWIZZLE_Y));
1226bf215546Sopenharmony_ci   }
1227bf215546Sopenharmony_ci   scalar_dst = ureg_writemask(dst, TGSI_WRITEMASK_Z);
1228bf215546Sopenharmony_ci   if (scalar_dst.WriteMask != TGSI_WRITEMASK_NONE) {
1229bf215546Sopenharmony_ci      func(ureg, scalar_dst,
1230bf215546Sopenharmony_ci           ureg_scalar(src, TGSI_SWIZZLE_Z));
1231bf215546Sopenharmony_ci   }
1232bf215546Sopenharmony_ci   scalar_dst = ureg_writemask(dst, TGSI_WRITEMASK_W);
1233bf215546Sopenharmony_ci   if (scalar_dst.WriteMask != TGSI_WRITEMASK_NONE) {
1234bf215546Sopenharmony_ci      func(ureg, scalar_dst,
1235bf215546Sopenharmony_ci           ureg_scalar(src, TGSI_SWIZZLE_W));
1236bf215546Sopenharmony_ci   }
1237bf215546Sopenharmony_ci   ureg_release_temporary(ureg, tmp);
1238bf215546Sopenharmony_ci}
1239bf215546Sopenharmony_ci
1240bf215546Sopenharmony_ciconst struct tgsi_token *
1241bf215546Sopenharmony_ciShader_tgsi_translate(const unsigned *code,
1242bf215546Sopenharmony_ci                      unsigned *output_mapping)
1243bf215546Sopenharmony_ci{
1244bf215546Sopenharmony_ci   struct Shader_xlate sx;
1245bf215546Sopenharmony_ci   struct Shader_parser parser;
1246bf215546Sopenharmony_ci   struct ureg_program *ureg = NULL;
1247bf215546Sopenharmony_ci   struct Shader_opcode opcode;
1248bf215546Sopenharmony_ci   const struct tgsi_token *tokens = NULL;
1249bf215546Sopenharmony_ci   uint nr_tokens;
1250bf215546Sopenharmony_ci   boolean shader_dumped = FALSE;
1251bf215546Sopenharmony_ci   boolean inside_sub = FALSE;
1252bf215546Sopenharmony_ci   uint i, j;
1253bf215546Sopenharmony_ci
1254bf215546Sopenharmony_ci   memset(&sx, 0, sizeof sx);
1255bf215546Sopenharmony_ci
1256bf215546Sopenharmony_ci   Shader_parse_init(&parser, code);
1257bf215546Sopenharmony_ci
1258bf215546Sopenharmony_ci   if (st_debug & ST_DEBUG_TGSI) {
1259bf215546Sopenharmony_ci      dx10_shader_dump_tokens(code);
1260bf215546Sopenharmony_ci      shader_dumped = TRUE;
1261bf215546Sopenharmony_ci   }
1262bf215546Sopenharmony_ci
1263bf215546Sopenharmony_ci   sx.max_calls = 64;
1264bf215546Sopenharmony_ci   sx.calls = (struct Shader_call *)MALLOC(sx.max_calls *
1265bf215546Sopenharmony_ci                                           sizeof(struct Shader_call));
1266bf215546Sopenharmony_ci   sx.num_calls = 0;
1267bf215546Sopenharmony_ci
1268bf215546Sopenharmony_ci   sx.max_labels = 64;
1269bf215546Sopenharmony_ci   sx.labels = (struct Shader_label *)MALLOC(sx.max_labels *
1270bf215546Sopenharmony_ci                                             sizeof(struct Shader_call));
1271bf215546Sopenharmony_ci   sx.num_labels = 0;
1272bf215546Sopenharmony_ci
1273bf215546Sopenharmony_ci
1274bf215546Sopenharmony_ci
1275bf215546Sopenharmony_ci   /* Header. */
1276bf215546Sopenharmony_ci   switch (parser.header.type) {
1277bf215546Sopenharmony_ci   case D3D10_SB_PIXEL_SHADER:
1278bf215546Sopenharmony_ci      ureg = ureg_create(PIPE_SHADER_FRAGMENT);
1279bf215546Sopenharmony_ci      break;
1280bf215546Sopenharmony_ci   case D3D10_SB_VERTEX_SHADER:
1281bf215546Sopenharmony_ci      ureg = ureg_create(PIPE_SHADER_VERTEX);
1282bf215546Sopenharmony_ci      break;
1283bf215546Sopenharmony_ci   case D3D10_SB_GEOMETRY_SHADER:
1284bf215546Sopenharmony_ci      ureg = ureg_create(PIPE_SHADER_GEOMETRY);
1285bf215546Sopenharmony_ci      break;
1286bf215546Sopenharmony_ci   }
1287bf215546Sopenharmony_ci
1288bf215546Sopenharmony_ci   assert(ureg);
1289bf215546Sopenharmony_ci   sx.ureg = ureg;
1290bf215546Sopenharmony_ci
1291bf215546Sopenharmony_ci   while (Shader_parse_opcode(&parser, &opcode)) {
1292bf215546Sopenharmony_ci      const struct dx10_opcode_xlate *ox;
1293bf215546Sopenharmony_ci
1294bf215546Sopenharmony_ci      assert(opcode.type < D3D10_SB_NUM_OPCODES);
1295bf215546Sopenharmony_ci      ox = &opcode_xlate[opcode.type];
1296bf215546Sopenharmony_ci
1297bf215546Sopenharmony_ci      switch (opcode.type) {
1298bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_EXP:
1299bf215546Sopenharmony_ci         expand_unary_to_scalarf(ureg, ureg_EX2, &sx, &opcode);
1300bf215546Sopenharmony_ci         break;
1301bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_SQRT:
1302bf215546Sopenharmony_ci         expand_unary_to_scalarf(ureg, ureg_SQRT, &sx, &opcode);
1303bf215546Sopenharmony_ci         break;
1304bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_RSQ:
1305bf215546Sopenharmony_ci         expand_unary_to_scalarf(ureg, ureg_RSQ, &sx, &opcode);
1306bf215546Sopenharmony_ci         break;
1307bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_LOG:
1308bf215546Sopenharmony_ci         expand_unary_to_scalarf(ureg, ureg_LG2, &sx, &opcode);
1309bf215546Sopenharmony_ci         break;
1310bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_IMUL:
1311bf215546Sopenharmony_ci         if (opcode.dst[0].base.type != D3D10_SB_OPERAND_TYPE_NULL) {
1312bf215546Sopenharmony_ci            ureg_IMUL_HI(ureg,
1313bf215546Sopenharmony_ci                        translate_dst_operand(&sx, &opcode.dst[0], opcode.saturate),
1314bf215546Sopenharmony_ci                        translate_src_operand(&sx, &opcode.src[0], OF_INT),
1315bf215546Sopenharmony_ci                        translate_src_operand(&sx, &opcode.src[1], OF_INT));
1316bf215546Sopenharmony_ci         }
1317bf215546Sopenharmony_ci
1318bf215546Sopenharmony_ci         if (opcode.dst[1].base.type != D3D10_SB_OPERAND_TYPE_NULL) {
1319bf215546Sopenharmony_ci            ureg_UMUL(ureg,
1320bf215546Sopenharmony_ci                      translate_dst_operand(&sx, &opcode.dst[1], opcode.saturate),
1321bf215546Sopenharmony_ci                      translate_src_operand(&sx, &opcode.src[0], OF_INT),
1322bf215546Sopenharmony_ci                      translate_src_operand(&sx, &opcode.src[1], OF_INT));
1323bf215546Sopenharmony_ci         }
1324bf215546Sopenharmony_ci
1325bf215546Sopenharmony_ci         break;
1326bf215546Sopenharmony_ci
1327bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_FTOI: {
1328bf215546Sopenharmony_ci         /* XXX: tgsi (and just about everybody else, c, opencl, glsl) has
1329bf215546Sopenharmony_ci          * out-of-range (and NaN) values undefined for f2i/f2u, but d3d10
1330bf215546Sopenharmony_ci          * requires clamping to min and max representable value (as well as 0
1331bf215546Sopenharmony_ci          * for NaNs) (this applies to both ftoi and ftou). At least the online
1332bf215546Sopenharmony_ci          * docs state that - this is consistent with generic d3d10 conversion
1333bf215546Sopenharmony_ci          * rules.
1334bf215546Sopenharmony_ci          * For FTOI, we cheat a bit here - in particular depending on noone
1335bf215546Sopenharmony_ci          * caring about NaNs, and depending on the (undefined!) behavior of
1336bf215546Sopenharmony_ci          * F2I returning 0x80000000 for too negative values (which works with
1337bf215546Sopenharmony_ci          * x86 sse). Hence only need to clamp too positive values.
1338bf215546Sopenharmony_ci          * Note that it is impossible to clamp using a float, since 2^31 - 1
1339bf215546Sopenharmony_ci          * is not exactly representable with a float.
1340bf215546Sopenharmony_ci          */
1341bf215546Sopenharmony_ci         struct ureg_dst too_large = ureg_DECL_temporary(ureg);
1342bf215546Sopenharmony_ci         struct ureg_dst tmp = ureg_DECL_temporary(ureg);
1343bf215546Sopenharmony_ci         ureg_FSGE(ureg, too_large,
1344bf215546Sopenharmony_ci                   translate_src_operand(&sx, &opcode.src[0], OF_FLOAT),
1345bf215546Sopenharmony_ci                   ureg_imm1f(ureg, 2147483648.0f));
1346bf215546Sopenharmony_ci         ureg_F2I(ureg, tmp,
1347bf215546Sopenharmony_ci                  translate_src_operand(&sx, &opcode.src[0], OF_FLOAT));
1348bf215546Sopenharmony_ci         ureg_UCMP(ureg,
1349bf215546Sopenharmony_ci                   translate_dst_operand(&sx, &opcode.dst[0], opcode.saturate),
1350bf215546Sopenharmony_ci                   ureg_src(too_large),
1351bf215546Sopenharmony_ci                   ureg_imm1i(ureg, 0x7fffffff),
1352bf215546Sopenharmony_ci                   ureg_src(tmp));
1353bf215546Sopenharmony_ci         ureg_release_temporary(ureg, too_large);
1354bf215546Sopenharmony_ci         ureg_release_temporary(ureg, tmp);
1355bf215546Sopenharmony_ci      }
1356bf215546Sopenharmony_ci         break;
1357bf215546Sopenharmony_ci
1358bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_FTOU: {
1359bf215546Sopenharmony_ci         /* For ftou, we need to do both clamps, which as a bonus also
1360bf215546Sopenharmony_ci          * gets us correct NaN behavior.
1361bf215546Sopenharmony_ci          * Note that it is impossible to clamp using a float against the upper
1362bf215546Sopenharmony_ci          * limit, since 2^32 - 1 is not exactly representable with a float,
1363bf215546Sopenharmony_ci          * but the clamp against 0.0 certainly works just fine.
1364bf215546Sopenharmony_ci          */
1365bf215546Sopenharmony_ci         struct ureg_dst too_large = ureg_DECL_temporary(ureg);
1366bf215546Sopenharmony_ci         struct ureg_dst tmp = ureg_DECL_temporary(ureg);
1367bf215546Sopenharmony_ci         ureg_FSGE(ureg, too_large,
1368bf215546Sopenharmony_ci                   translate_src_operand(&sx, &opcode.src[0], OF_FLOAT),
1369bf215546Sopenharmony_ci                   ureg_imm1f(ureg, 4294967296.0f));
1370bf215546Sopenharmony_ci         /* clamp negative values + NaN to zero.
1371bf215546Sopenharmony_ci          * (Could be done slightly more efficient in llvmpipe due to
1372bf215546Sopenharmony_ci          * MAX NaN behavior handling.)
1373bf215546Sopenharmony_ci          */
1374bf215546Sopenharmony_ci         ureg_MAX(ureg, tmp,
1375bf215546Sopenharmony_ci                  ureg_imm1f(ureg, 0.0f),
1376bf215546Sopenharmony_ci                  translate_src_operand(&sx, &opcode.src[0], OF_FLOAT));
1377bf215546Sopenharmony_ci         ureg_F2U(ureg, tmp,
1378bf215546Sopenharmony_ci                  ureg_src(tmp));
1379bf215546Sopenharmony_ci         ureg_UCMP(ureg,
1380bf215546Sopenharmony_ci                   translate_dst_operand(&sx, &opcode.dst[0], opcode.saturate),
1381bf215546Sopenharmony_ci                   ureg_src(too_large),
1382bf215546Sopenharmony_ci                   ureg_imm1u(ureg, 0xffffffff),
1383bf215546Sopenharmony_ci                   ureg_src(tmp));
1384bf215546Sopenharmony_ci         ureg_release_temporary(ureg, too_large);
1385bf215546Sopenharmony_ci         ureg_release_temporary(ureg, tmp);
1386bf215546Sopenharmony_ci      }
1387bf215546Sopenharmony_ci         break;
1388bf215546Sopenharmony_ci
1389bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_LD_MS:
1390bf215546Sopenharmony_ci         /* XXX: We don't support multi-sampling yet, but we need to parse
1391bf215546Sopenharmony_ci          * this opcode regardless, so we just ignore sample index operand
1392bf215546Sopenharmony_ci          * for now */
1393bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_LD:
1394bf215546Sopenharmony_ci         if (st_debug & ST_DEBUG_OLD_TEX_OPS) {
1395bf215546Sopenharmony_ci            unsigned resource = opcode.src[1].base.index[0].imm;
1396bf215546Sopenharmony_ci            assert(opcode.src[1].base.index_dim == 1);
1397bf215546Sopenharmony_ci            assert(opcode.src[1].base.index[0].imm < SHADER_MAX_RESOURCES);
1398bf215546Sopenharmony_ci
1399bf215546Sopenharmony_ci            if (ureg_src_is_undef(sx.samplers[resource])) {
1400bf215546Sopenharmony_ci               sx.samplers[resource] =
1401bf215546Sopenharmony_ci                  ureg_DECL_sampler(ureg, resource);
1402bf215546Sopenharmony_ci            }
1403bf215546Sopenharmony_ci
1404bf215546Sopenharmony_ci            ureg_TXF(ureg,
1405bf215546Sopenharmony_ci                     translate_dst_operand(&sx, &opcode.dst[0], opcode.saturate),
1406bf215546Sopenharmony_ci                     sx.resources[resource].target,
1407bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[0], OF_FLOAT),
1408bf215546Sopenharmony_ci                     sx.samplers[resource]);
1409bf215546Sopenharmony_ci         }
1410bf215546Sopenharmony_ci         else {
1411bf215546Sopenharmony_ci            struct ureg_src srcreg[2];
1412bf215546Sopenharmony_ci            srcreg[0] = translate_src_operand(&sx, &opcode.src[0], OF_INT);
1413bf215546Sopenharmony_ci            srcreg[1] = translate_src_operand(&sx, &opcode.src[1], OF_INT);
1414bf215546Sopenharmony_ci
1415bf215546Sopenharmony_ci            sample_ureg_emit(ureg, TGSI_OPCODE_SAMPLE_I, 2, &opcode,
1416bf215546Sopenharmony_ci                             translate_dst_operand(&sx, &opcode.dst[0],
1417bf215546Sopenharmony_ci                                                   opcode.saturate),
1418bf215546Sopenharmony_ci                             srcreg);
1419bf215546Sopenharmony_ci         }
1420bf215546Sopenharmony_ci         break;
1421bf215546Sopenharmony_ci
1422bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_CUSTOMDATA:
1423bf215546Sopenharmony_ci         if (opcode.customdata._class ==
1424bf215546Sopenharmony_ci             D3D10_SB_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER) {
1425bf215546Sopenharmony_ci            sx.imms =
1426bf215546Sopenharmony_ci               ureg_DECL_immediate_block_uint(ureg,
1427bf215546Sopenharmony_ci                                              opcode.customdata.u.constbuf.data,
1428bf215546Sopenharmony_ci                                              opcode.customdata.u.constbuf.count);
1429bf215546Sopenharmony_ci         } else {
1430bf215546Sopenharmony_ci            assert(0);
1431bf215546Sopenharmony_ci         }
1432bf215546Sopenharmony_ci         break;
1433bf215546Sopenharmony_ci
1434bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_RESINFO:
1435bf215546Sopenharmony_ci         if (st_debug & ST_DEBUG_OLD_TEX_OPS) {
1436bf215546Sopenharmony_ci            unsigned resource = opcode.src[1].base.index[0].imm;
1437bf215546Sopenharmony_ci            assert(opcode.src[1].base.index_dim == 1);
1438bf215546Sopenharmony_ci            assert(opcode.src[1].base.index[0].imm < SHADER_MAX_RESOURCES);
1439bf215546Sopenharmony_ci
1440bf215546Sopenharmony_ci            if (ureg_src_is_undef(sx.samplers[resource])) {
1441bf215546Sopenharmony_ci               sx.samplers[resource] =
1442bf215546Sopenharmony_ci                  ureg_DECL_sampler(ureg, resource);
1443bf215546Sopenharmony_ci            }
1444bf215546Sopenharmony_ci            /* don't bother with swizzle, ret type etc. */
1445bf215546Sopenharmony_ci            ureg_TXQ(ureg,
1446bf215546Sopenharmony_ci                     translate_dst_operand(&sx, &opcode.dst[0],
1447bf215546Sopenharmony_ci                                           opcode.saturate),
1448bf215546Sopenharmony_ci                     sx.resources[resource].target,
1449bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[0], OF_UINT),
1450bf215546Sopenharmony_ci                     sx.samplers[resource]);
1451bf215546Sopenharmony_ci         }
1452bf215546Sopenharmony_ci         else {
1453bf215546Sopenharmony_ci            struct ureg_dst r0 = ureg_DECL_temporary(ureg);
1454bf215546Sopenharmony_ci            struct ureg_src tsrc = translate_src_operand(&sx, &opcode.src[1], OF_UINT);
1455bf215546Sopenharmony_ci            struct ureg_dst dstreg = translate_dst_operand(&sx, &opcode.dst[0],
1456bf215546Sopenharmony_ci                                                           opcode.saturate);
1457bf215546Sopenharmony_ci
1458bf215546Sopenharmony_ci            /* while specs say swizzle is ignored better safe than sorry */
1459bf215546Sopenharmony_ci            tsrc.SwizzleX = TGSI_SWIZZLE_X;
1460bf215546Sopenharmony_ci            tsrc.SwizzleY = TGSI_SWIZZLE_Y;
1461bf215546Sopenharmony_ci            tsrc.SwizzleZ = TGSI_SWIZZLE_Z;
1462bf215546Sopenharmony_ci            tsrc.SwizzleW = TGSI_SWIZZLE_W;
1463bf215546Sopenharmony_ci
1464bf215546Sopenharmony_ci            ureg_SVIEWINFO(ureg, r0,
1465bf215546Sopenharmony_ci                           translate_src_operand(&sx, &opcode.src[0], OF_UINT),
1466bf215546Sopenharmony_ci                           tsrc);
1467bf215546Sopenharmony_ci
1468bf215546Sopenharmony_ci            tsrc = ureg_src(r0);
1469bf215546Sopenharmony_ci            tsrc.SwizzleX = opcode.src[1].swizzle[0];
1470bf215546Sopenharmony_ci            tsrc.SwizzleY = opcode.src[1].swizzle[1];
1471bf215546Sopenharmony_ci            tsrc.SwizzleZ = opcode.src[1].swizzle[2];
1472bf215546Sopenharmony_ci            tsrc.SwizzleW = opcode.src[1].swizzle[3];
1473bf215546Sopenharmony_ci
1474bf215546Sopenharmony_ci            if (opcode.specific.resinfo_ret_type ==
1475bf215546Sopenharmony_ci                D3D10_SB_RESINFO_INSTRUCTION_RETURN_UINT) {
1476bf215546Sopenharmony_ci               ureg_MOV(ureg, dstreg, tsrc);
1477bf215546Sopenharmony_ci            }
1478bf215546Sopenharmony_ci            else if (opcode.specific.resinfo_ret_type ==
1479bf215546Sopenharmony_ci                     D3D10_SB_RESINFO_INSTRUCTION_RETURN_FLOAT) {
1480bf215546Sopenharmony_ci                ureg_I2F(ureg, dstreg, tsrc);
1481bf215546Sopenharmony_ci            }
1482bf215546Sopenharmony_ci            else { /* D3D10_SB_RESINFO_INSTRUCTION_RETURN_RCPFLOAT */
1483bf215546Sopenharmony_ci               unsigned i;
1484bf215546Sopenharmony_ci               /*
1485bf215546Sopenharmony_ci                * Must apply rcp only to parts determined by dims,
1486bf215546Sopenharmony_ci                * (width/height/depth) but NOT to array size nor mip levels
1487bf215546Sopenharmony_ci                * hence need to figure that out here.
1488bf215546Sopenharmony_ci                * This is one sick modifier if you ask me!
1489bf215546Sopenharmony_ci                */
1490bf215546Sopenharmony_ci               unsigned res_index = opcode.src[1].base.index[0].imm;
1491bf215546Sopenharmony_ci               unsigned target = sx.resources[res_index].target;
1492bf215546Sopenharmony_ci               unsigned dims = texture_dim_from_tgsi_target(target);
1493bf215546Sopenharmony_ci
1494bf215546Sopenharmony_ci               ureg_I2F(ureg, r0, ureg_src(r0));
1495bf215546Sopenharmony_ci               tsrc = ureg_src(r0);
1496bf215546Sopenharmony_ci               for (i = 0; i < 4; i++) {
1497bf215546Sopenharmony_ci                  unsigned dst_swizzle = opcode.src[1].swizzle[i];
1498bf215546Sopenharmony_ci                  struct ureg_dst dstregmasked = ureg_writemask(dstreg, 1 << i);
1499bf215546Sopenharmony_ci                  /*
1500bf215546Sopenharmony_ci                   * could do one mov with multiple write mask bits set
1501bf215546Sopenharmony_ci                   * but rcp is scalar anyway.
1502bf215546Sopenharmony_ci                   */
1503bf215546Sopenharmony_ci                  if (dst_swizzle < dims) {
1504bf215546Sopenharmony_ci                     ureg_RCP(ureg, dstregmasked, ureg_scalar(tsrc, dst_swizzle));
1505bf215546Sopenharmony_ci                  }
1506bf215546Sopenharmony_ci                  else {
1507bf215546Sopenharmony_ci                     ureg_MOV(ureg, dstregmasked, ureg_scalar(tsrc, dst_swizzle));
1508bf215546Sopenharmony_ci                  }
1509bf215546Sopenharmony_ci               }
1510bf215546Sopenharmony_ci            }
1511bf215546Sopenharmony_ci            ureg_release_temporary(ureg, r0);
1512bf215546Sopenharmony_ci         }
1513bf215546Sopenharmony_ci         break;
1514bf215546Sopenharmony_ci
1515bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_SAMPLE:
1516bf215546Sopenharmony_ci         if (st_debug & ST_DEBUG_OLD_TEX_OPS) {
1517bf215546Sopenharmony_ci            assert(opcode.src[1].base.index_dim == 1);
1518bf215546Sopenharmony_ci            assert(opcode.src[1].base.index[0].imm < SHADER_MAX_RESOURCES);
1519bf215546Sopenharmony_ci
1520bf215546Sopenharmony_ci            LOG_UNSUPPORTED(opcode.src[1].base.index[0].imm != opcode.src[2].base.index[0].imm);
1521bf215546Sopenharmony_ci
1522bf215546Sopenharmony_ci            ureg_TEX(ureg,
1523bf215546Sopenharmony_ci                     translate_dst_operand(&sx, &opcode.dst[0],
1524bf215546Sopenharmony_ci                                           opcode.saturate),
1525bf215546Sopenharmony_ci                     sx.resources[opcode.src[1].base.index[0].imm].target,
1526bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[0], OF_FLOAT),
1527bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[2], OF_FLOAT));
1528bf215546Sopenharmony_ci         }
1529bf215546Sopenharmony_ci         else {
1530bf215546Sopenharmony_ci            struct ureg_src srcreg[3];
1531bf215546Sopenharmony_ci            srcreg[0] = translate_src_operand(&sx, &opcode.src[0], OF_FLOAT);
1532bf215546Sopenharmony_ci            srcreg[1] = translate_src_operand(&sx, &opcode.src[1], OF_UINT);
1533bf215546Sopenharmony_ci            srcreg[2] = translate_src_operand(&sx, &opcode.src[2], OF_UINT);
1534bf215546Sopenharmony_ci
1535bf215546Sopenharmony_ci            sample_ureg_emit(ureg, TGSI_OPCODE_SAMPLE, 3, &opcode,
1536bf215546Sopenharmony_ci                             translate_dst_operand(&sx, &opcode.dst[0],
1537bf215546Sopenharmony_ci                                                   opcode.saturate),
1538bf215546Sopenharmony_ci                             srcreg);
1539bf215546Sopenharmony_ci         }
1540bf215546Sopenharmony_ci         break;
1541bf215546Sopenharmony_ci
1542bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_SAMPLE_C:
1543bf215546Sopenharmony_ci         if (st_debug & ST_DEBUG_OLD_TEX_OPS) {
1544bf215546Sopenharmony_ci            struct ureg_dst r0 = ureg_DECL_temporary(ureg);
1545bf215546Sopenharmony_ci
1546bf215546Sopenharmony_ci            /* XXX: Support only 2D texture targets for now.
1547bf215546Sopenharmony_ci             *      Need to figure out how to pack the compare value
1548bf215546Sopenharmony_ci             *      for other dimensions and if there is enough space
1549bf215546Sopenharmony_ci             *      in a single operand for all possible cases.
1550bf215546Sopenharmony_ci             */
1551bf215546Sopenharmony_ci            LOG_UNSUPPORTED(sx.resources[opcode.src[1].base.index[0].imm].target !=
1552bf215546Sopenharmony_ci                            TGSI_TEXTURE_2D);
1553bf215546Sopenharmony_ci
1554bf215546Sopenharmony_ci            assert(opcode.src[1].base.index_dim == 1);
1555bf215546Sopenharmony_ci            assert(opcode.src[1].base.index[0].imm < SHADER_MAX_RESOURCES);
1556bf215546Sopenharmony_ci
1557bf215546Sopenharmony_ci            /* Insert the compare value into .z component.
1558bf215546Sopenharmony_ci             */
1559bf215546Sopenharmony_ci            ureg_MOV(ureg,
1560bf215546Sopenharmony_ci                     ureg_writemask(r0, TGSI_WRITEMASK_XYW),
1561bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[0], OF_FLOAT));
1562bf215546Sopenharmony_ci            ureg_MOV(ureg,
1563bf215546Sopenharmony_ci                     ureg_writemask(r0, TGSI_WRITEMASK_Z),
1564bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[3], OF_FLOAT));
1565bf215546Sopenharmony_ci
1566bf215546Sopenharmony_ci            /* XXX: Pass explicit Lod=0 in D3D10_SB_OPCODE_SAMPLE_C_LZ case.
1567bf215546Sopenharmony_ci             */
1568bf215546Sopenharmony_ci
1569bf215546Sopenharmony_ci            ureg_TEX(ureg,
1570bf215546Sopenharmony_ci                     translate_dst_operand(&sx, &opcode.dst[0],
1571bf215546Sopenharmony_ci                                           opcode.saturate),
1572bf215546Sopenharmony_ci                     sx.resources[opcode.src[1].base.index[0].imm].target,
1573bf215546Sopenharmony_ci                     ureg_src(r0),
1574bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[2], OF_FLOAT));
1575bf215546Sopenharmony_ci
1576bf215546Sopenharmony_ci            ureg_release_temporary(ureg, r0);
1577bf215546Sopenharmony_ci         }
1578bf215546Sopenharmony_ci         else {
1579bf215546Sopenharmony_ci            struct ureg_src srcreg[4];
1580bf215546Sopenharmony_ci            srcreg[0] = translate_src_operand(&sx, &opcode.src[0], OF_FLOAT);
1581bf215546Sopenharmony_ci            srcreg[1] = translate_src_operand(&sx, &opcode.src[1], OF_UINT);
1582bf215546Sopenharmony_ci            srcreg[2] = translate_src_operand(&sx, &opcode.src[2], OF_UINT);
1583bf215546Sopenharmony_ci            srcreg[3] = translate_src_operand(&sx, &opcode.src[3], OF_FLOAT);
1584bf215546Sopenharmony_ci
1585bf215546Sopenharmony_ci            sample_ureg_emit(ureg, TGSI_OPCODE_SAMPLE_C, 4, &opcode,
1586bf215546Sopenharmony_ci                             translate_dst_operand(&sx, &opcode.dst[0],
1587bf215546Sopenharmony_ci                                                   opcode.saturate),
1588bf215546Sopenharmony_ci                             srcreg);
1589bf215546Sopenharmony_ci         }
1590bf215546Sopenharmony_ci         break;
1591bf215546Sopenharmony_ci
1592bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_SAMPLE_C_LZ:
1593bf215546Sopenharmony_ci         if (st_debug & ST_DEBUG_OLD_TEX_OPS) {
1594bf215546Sopenharmony_ci            struct ureg_dst r0 = ureg_DECL_temporary(ureg);
1595bf215546Sopenharmony_ci
1596bf215546Sopenharmony_ci            assert(opcode.src[1].base.index_dim == 1);
1597bf215546Sopenharmony_ci            assert(opcode.src[1].base.index[0].imm < SHADER_MAX_RESOURCES);
1598bf215546Sopenharmony_ci
1599bf215546Sopenharmony_ci            /* XXX: Support only 2D texture targets for now.
1600bf215546Sopenharmony_ci             *      Need to figure out how to pack the compare value
1601bf215546Sopenharmony_ci             *      for other dimensions and if there is enough space
1602bf215546Sopenharmony_ci             *      in a single operand for all possible cases.
1603bf215546Sopenharmony_ci             */
1604bf215546Sopenharmony_ci            LOG_UNSUPPORTED(sx.resources[opcode.src[1].base.index[0].imm].target !=
1605bf215546Sopenharmony_ci                            TGSI_TEXTURE_2D);
1606bf215546Sopenharmony_ci
1607bf215546Sopenharmony_ci            /* Insert the compare value into .z component.
1608bf215546Sopenharmony_ci             * Insert 0 into .w component.
1609bf215546Sopenharmony_ci             */
1610bf215546Sopenharmony_ci            ureg_MOV(ureg,
1611bf215546Sopenharmony_ci                     ureg_writemask(r0, TGSI_WRITEMASK_XY),
1612bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[0], OF_FLOAT));
1613bf215546Sopenharmony_ci            ureg_MOV(ureg,
1614bf215546Sopenharmony_ci                     ureg_writemask(r0, TGSI_WRITEMASK_Z),
1615bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[3], OF_FLOAT));
1616bf215546Sopenharmony_ci            ureg_MOV(ureg,
1617bf215546Sopenharmony_ci                     ureg_writemask(r0, TGSI_WRITEMASK_W),
1618bf215546Sopenharmony_ci                     ureg_imm1f(ureg, 0.0f));
1619bf215546Sopenharmony_ci
1620bf215546Sopenharmony_ci            ureg_TXL(ureg,
1621bf215546Sopenharmony_ci                     translate_dst_operand(&sx, &opcode.dst[0],
1622bf215546Sopenharmony_ci                                           opcode.saturate),
1623bf215546Sopenharmony_ci                     sx.resources[opcode.src[1].base.index[0].imm].target,
1624bf215546Sopenharmony_ci                     ureg_src(r0),
1625bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[2], OF_FLOAT));
1626bf215546Sopenharmony_ci
1627bf215546Sopenharmony_ci            ureg_release_temporary(ureg, r0);
1628bf215546Sopenharmony_ci         }
1629bf215546Sopenharmony_ci         else {
1630bf215546Sopenharmony_ci            struct ureg_src srcreg[4];
1631bf215546Sopenharmony_ci            srcreg[0] = translate_src_operand(&sx, &opcode.src[0], OF_FLOAT);
1632bf215546Sopenharmony_ci            srcreg[1] = translate_src_operand(&sx, &opcode.src[1], OF_UINT);
1633bf215546Sopenharmony_ci            srcreg[2] = translate_src_operand(&sx, &opcode.src[2], OF_UINT);
1634bf215546Sopenharmony_ci            srcreg[3] = translate_src_operand(&sx, &opcode.src[3], OF_FLOAT);
1635bf215546Sopenharmony_ci
1636bf215546Sopenharmony_ci            sample_ureg_emit(ureg, TGSI_OPCODE_SAMPLE_C_LZ, 4, &opcode,
1637bf215546Sopenharmony_ci                             translate_dst_operand(&sx, &opcode.dst[0],
1638bf215546Sopenharmony_ci                                                   opcode.saturate),
1639bf215546Sopenharmony_ci                             srcreg);
1640bf215546Sopenharmony_ci         }
1641bf215546Sopenharmony_ci         break;
1642bf215546Sopenharmony_ci
1643bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_SAMPLE_L:
1644bf215546Sopenharmony_ci         if (st_debug & ST_DEBUG_OLD_TEX_OPS) {
1645bf215546Sopenharmony_ci            struct ureg_dst r0 = ureg_DECL_temporary(ureg);
1646bf215546Sopenharmony_ci
1647bf215546Sopenharmony_ci            assert(opcode.src[1].base.index_dim == 1);
1648bf215546Sopenharmony_ci            assert(opcode.src[1].base.index[0].imm < SHADER_MAX_RESOURCES);
1649bf215546Sopenharmony_ci
1650bf215546Sopenharmony_ci            /* Insert LOD into .w component.
1651bf215546Sopenharmony_ci             */
1652bf215546Sopenharmony_ci            ureg_MOV(ureg,
1653bf215546Sopenharmony_ci                     ureg_writemask(r0, TGSI_WRITEMASK_XYZ),
1654bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[0], OF_FLOAT));
1655bf215546Sopenharmony_ci            ureg_MOV(ureg,
1656bf215546Sopenharmony_ci                     ureg_writemask(r0, TGSI_WRITEMASK_W),
1657bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[3], OF_FLOAT));
1658bf215546Sopenharmony_ci
1659bf215546Sopenharmony_ci            ureg_TXL(ureg,
1660bf215546Sopenharmony_ci                     translate_dst_operand(&sx, &opcode.dst[0],
1661bf215546Sopenharmony_ci                                           opcode.saturate),
1662bf215546Sopenharmony_ci                     sx.resources[opcode.src[1].base.index[0].imm].target,
1663bf215546Sopenharmony_ci                     ureg_src(r0),
1664bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[2], OF_FLOAT));
1665bf215546Sopenharmony_ci
1666bf215546Sopenharmony_ci            ureg_release_temporary(ureg, r0);
1667bf215546Sopenharmony_ci         }
1668bf215546Sopenharmony_ci         else {
1669bf215546Sopenharmony_ci            struct ureg_src srcreg[4];
1670bf215546Sopenharmony_ci            srcreg[0] = translate_src_operand(&sx, &opcode.src[0], OF_FLOAT);
1671bf215546Sopenharmony_ci            srcreg[1] = translate_src_operand(&sx, &opcode.src[1], OF_UINT);
1672bf215546Sopenharmony_ci            srcreg[2] = translate_src_operand(&sx, &opcode.src[2], OF_UINT);
1673bf215546Sopenharmony_ci            srcreg[3] = translate_src_operand(&sx, &opcode.src[3], OF_FLOAT);
1674bf215546Sopenharmony_ci
1675bf215546Sopenharmony_ci            sample_ureg_emit(ureg, TGSI_OPCODE_SAMPLE_L, 4, &opcode,
1676bf215546Sopenharmony_ci                             translate_dst_operand(&sx, &opcode.dst[0],
1677bf215546Sopenharmony_ci                                                   opcode.saturate),
1678bf215546Sopenharmony_ci                             srcreg);
1679bf215546Sopenharmony_ci         }
1680bf215546Sopenharmony_ci         break;
1681bf215546Sopenharmony_ci
1682bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_SAMPLE_D:
1683bf215546Sopenharmony_ci         if (st_debug & ST_DEBUG_OLD_TEX_OPS) {
1684bf215546Sopenharmony_ci            assert(opcode.src[1].base.index_dim == 1);
1685bf215546Sopenharmony_ci            assert(opcode.src[1].base.index[0].imm < SHADER_MAX_RESOURCES);
1686bf215546Sopenharmony_ci
1687bf215546Sopenharmony_ci            ureg_TXD(ureg,
1688bf215546Sopenharmony_ci                     translate_dst_operand(&sx, &opcode.dst[0],
1689bf215546Sopenharmony_ci                                           opcode.saturate),
1690bf215546Sopenharmony_ci                     sx.resources[opcode.src[1].base.index[0].imm].target,
1691bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[0], OF_FLOAT),
1692bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[3], OF_FLOAT),
1693bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[4], OF_FLOAT),
1694bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[2], OF_FLOAT));
1695bf215546Sopenharmony_ci         }
1696bf215546Sopenharmony_ci         else {
1697bf215546Sopenharmony_ci            struct ureg_src srcreg[5];
1698bf215546Sopenharmony_ci            srcreg[0] = translate_src_operand(&sx, &opcode.src[0], OF_FLOAT);
1699bf215546Sopenharmony_ci            srcreg[1] = translate_src_operand(&sx, &opcode.src[1], OF_UINT);
1700bf215546Sopenharmony_ci            srcreg[2] = translate_src_operand(&sx, &opcode.src[2], OF_UINT);
1701bf215546Sopenharmony_ci            srcreg[3] = translate_src_operand(&sx, &opcode.src[3], OF_FLOAT);
1702bf215546Sopenharmony_ci            srcreg[4] = translate_src_operand(&sx, &opcode.src[4], OF_FLOAT);
1703bf215546Sopenharmony_ci
1704bf215546Sopenharmony_ci            sample_ureg_emit(ureg, TGSI_OPCODE_SAMPLE_D, 5, &opcode,
1705bf215546Sopenharmony_ci                             translate_dst_operand(&sx, &opcode.dst[0],
1706bf215546Sopenharmony_ci                                                   opcode.saturate),
1707bf215546Sopenharmony_ci                             srcreg);
1708bf215546Sopenharmony_ci         }
1709bf215546Sopenharmony_ci         break;
1710bf215546Sopenharmony_ci
1711bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_SAMPLE_B:
1712bf215546Sopenharmony_ci         if (st_debug & ST_DEBUG_OLD_TEX_OPS) {
1713bf215546Sopenharmony_ci            struct ureg_dst r0 = ureg_DECL_temporary(ureg);
1714bf215546Sopenharmony_ci
1715bf215546Sopenharmony_ci            assert(opcode.src[1].base.index_dim == 1);
1716bf215546Sopenharmony_ci            assert(opcode.src[1].base.index[0].imm < SHADER_MAX_RESOURCES);
1717bf215546Sopenharmony_ci
1718bf215546Sopenharmony_ci            /* Insert LOD bias into .w component.
1719bf215546Sopenharmony_ci             */
1720bf215546Sopenharmony_ci            ureg_MOV(ureg,
1721bf215546Sopenharmony_ci                     ureg_writemask(r0, TGSI_WRITEMASK_XYZ),
1722bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[0], OF_FLOAT));
1723bf215546Sopenharmony_ci            ureg_MOV(ureg,
1724bf215546Sopenharmony_ci                     ureg_writemask(r0, TGSI_WRITEMASK_W),
1725bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[3], OF_FLOAT));
1726bf215546Sopenharmony_ci
1727bf215546Sopenharmony_ci            ureg_TXB(ureg,
1728bf215546Sopenharmony_ci                     translate_dst_operand(&sx, &opcode.dst[0],
1729bf215546Sopenharmony_ci                                           opcode.saturate),
1730bf215546Sopenharmony_ci                     sx.resources[opcode.src[1].base.index[0].imm].target,
1731bf215546Sopenharmony_ci                     ureg_src(r0),
1732bf215546Sopenharmony_ci                     translate_src_operand(&sx, &opcode.src[2], OF_FLOAT));
1733bf215546Sopenharmony_ci
1734bf215546Sopenharmony_ci            ureg_release_temporary(ureg, r0);
1735bf215546Sopenharmony_ci         }
1736bf215546Sopenharmony_ci         else {
1737bf215546Sopenharmony_ci            struct ureg_src srcreg[4];
1738bf215546Sopenharmony_ci            srcreg[0] = translate_src_operand(&sx, &opcode.src[0], OF_FLOAT);
1739bf215546Sopenharmony_ci            srcreg[1] = translate_src_operand(&sx, &opcode.src[1], OF_UINT);
1740bf215546Sopenharmony_ci            srcreg[2] = translate_src_operand(&sx, &opcode.src[2], OF_UINT);
1741bf215546Sopenharmony_ci            srcreg[3] = translate_src_operand(&sx, &opcode.src[3], OF_FLOAT);
1742bf215546Sopenharmony_ci
1743bf215546Sopenharmony_ci            sample_ureg_emit(ureg, TGSI_OPCODE_SAMPLE_B, 4, &opcode,
1744bf215546Sopenharmony_ci                             translate_dst_operand(&sx, &opcode.dst[0],
1745bf215546Sopenharmony_ci                                                   opcode.saturate),
1746bf215546Sopenharmony_ci                             srcreg);
1747bf215546Sopenharmony_ci         }
1748bf215546Sopenharmony_ci         break;
1749bf215546Sopenharmony_ci
1750bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_SINCOS: {
1751bf215546Sopenharmony_ci         struct ureg_dst src0 = ureg_DECL_temporary(ureg);
1752bf215546Sopenharmony_ci         ureg_MOV(ureg, src0, translate_src_operand(&sx, &opcode.src[0], OF_FLOAT));
1753bf215546Sopenharmony_ci         if (opcode.dst[0].base.type != D3D10_SB_OPERAND_TYPE_NULL) {
1754bf215546Sopenharmony_ci            struct ureg_dst dst = translate_dst_operand(&sx, &opcode.dst[0],
1755bf215546Sopenharmony_ci                                                        opcode.saturate);
1756bf215546Sopenharmony_ci            struct ureg_src src = ureg_src(src0);
1757bf215546Sopenharmony_ci            ureg_SIN(ureg, ureg_writemask(dst, TGSI_WRITEMASK_X),
1758bf215546Sopenharmony_ci                     ureg_scalar(src, TGSI_SWIZZLE_X));
1759bf215546Sopenharmony_ci            ureg_SIN(ureg, ureg_writemask(dst, TGSI_WRITEMASK_Y),
1760bf215546Sopenharmony_ci                     ureg_scalar(src, TGSI_SWIZZLE_Y));
1761bf215546Sopenharmony_ci            ureg_SIN(ureg, ureg_writemask(dst, TGSI_WRITEMASK_Z),
1762bf215546Sopenharmony_ci                     ureg_scalar(src, TGSI_SWIZZLE_Z));
1763bf215546Sopenharmony_ci            ureg_SIN(ureg, ureg_writemask(dst, TGSI_WRITEMASK_W),
1764bf215546Sopenharmony_ci                     ureg_scalar(src, TGSI_SWIZZLE_W));
1765bf215546Sopenharmony_ci         }
1766bf215546Sopenharmony_ci         if (opcode.dst[1].base.type != D3D10_SB_OPERAND_TYPE_NULL) {
1767bf215546Sopenharmony_ci            struct ureg_dst dst = translate_dst_operand(&sx, &opcode.dst[1],
1768bf215546Sopenharmony_ci                                                        opcode.saturate);
1769bf215546Sopenharmony_ci            struct ureg_src src = ureg_src(src0);
1770bf215546Sopenharmony_ci            ureg_COS(ureg, ureg_writemask(dst, TGSI_WRITEMASK_X),
1771bf215546Sopenharmony_ci                     ureg_scalar(src, TGSI_SWIZZLE_X));
1772bf215546Sopenharmony_ci            ureg_COS(ureg, ureg_writemask(dst, TGSI_WRITEMASK_Y),
1773bf215546Sopenharmony_ci                     ureg_scalar(src, TGSI_SWIZZLE_Y));
1774bf215546Sopenharmony_ci            ureg_COS(ureg, ureg_writemask(dst, TGSI_WRITEMASK_Z),
1775bf215546Sopenharmony_ci                     ureg_scalar(src, TGSI_SWIZZLE_Z));
1776bf215546Sopenharmony_ci            ureg_COS(ureg, ureg_writemask(dst, TGSI_WRITEMASK_W),
1777bf215546Sopenharmony_ci                     ureg_scalar(src, TGSI_SWIZZLE_W));
1778bf215546Sopenharmony_ci         }
1779bf215546Sopenharmony_ci         ureg_release_temporary(ureg, src0);
1780bf215546Sopenharmony_ci      }
1781bf215546Sopenharmony_ci         break;
1782bf215546Sopenharmony_ci
1783bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_UDIV: {
1784bf215546Sopenharmony_ci         struct ureg_dst src0 = ureg_DECL_temporary(ureg);
1785bf215546Sopenharmony_ci         struct ureg_dst src1 = ureg_DECL_temporary(ureg);
1786bf215546Sopenharmony_ci         ureg_MOV(ureg, src0, translate_src_operand(&sx, &opcode.src[0], OF_UINT));
1787bf215546Sopenharmony_ci         ureg_MOV(ureg, src1, translate_src_operand(&sx, &opcode.src[1], OF_UINT));
1788bf215546Sopenharmony_ci         if (opcode.dst[0].base.type != D3D10_SB_OPERAND_TYPE_NULL) {
1789bf215546Sopenharmony_ci            ureg_UDIV(ureg,
1790bf215546Sopenharmony_ci                      translate_dst_operand(&sx, &opcode.dst[0],
1791bf215546Sopenharmony_ci                                            opcode.saturate),
1792bf215546Sopenharmony_ci                      ureg_src(src0), ureg_src(src1));
1793bf215546Sopenharmony_ci         }
1794bf215546Sopenharmony_ci         if (opcode.dst[1].base.type != D3D10_SB_OPERAND_TYPE_NULL) {
1795bf215546Sopenharmony_ci            ureg_UMOD(ureg,
1796bf215546Sopenharmony_ci                      translate_dst_operand(&sx, &opcode.dst[1],
1797bf215546Sopenharmony_ci                                            opcode.saturate),
1798bf215546Sopenharmony_ci                      ureg_src(src0), ureg_src(src1));
1799bf215546Sopenharmony_ci         }
1800bf215546Sopenharmony_ci         ureg_release_temporary(ureg, src0);
1801bf215546Sopenharmony_ci         ureg_release_temporary(ureg, src1);
1802bf215546Sopenharmony_ci      }
1803bf215546Sopenharmony_ci         break;
1804bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_UMUL: {
1805bf215546Sopenharmony_ci         if (opcode.dst[0].base.type != D3D10_SB_OPERAND_TYPE_NULL) {
1806bf215546Sopenharmony_ci            ureg_UMUL_HI(ureg,
1807bf215546Sopenharmony_ci                         translate_dst_operand(&sx, &opcode.dst[0],
1808bf215546Sopenharmony_ci                                               opcode.saturate),
1809bf215546Sopenharmony_ci                         translate_src_operand(&sx, &opcode.src[0], OF_UINT),
1810bf215546Sopenharmony_ci                         translate_src_operand(&sx, &opcode.src[1], OF_UINT));
1811bf215546Sopenharmony_ci         }
1812bf215546Sopenharmony_ci         if (opcode.dst[1].base.type != D3D10_SB_OPERAND_TYPE_NULL) {
1813bf215546Sopenharmony_ci            ureg_UMUL(ureg,
1814bf215546Sopenharmony_ci                      translate_dst_operand(&sx, &opcode.dst[1],
1815bf215546Sopenharmony_ci                                            opcode.saturate),
1816bf215546Sopenharmony_ci                      translate_src_operand(&sx, &opcode.src[0], OF_UINT),
1817bf215546Sopenharmony_ci                      translate_src_operand(&sx, &opcode.src[1], OF_UINT));
1818bf215546Sopenharmony_ci         }
1819bf215546Sopenharmony_ci      }
1820bf215546Sopenharmony_ci         break;
1821bf215546Sopenharmony_ci
1822bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_RESOURCE:
1823bf215546Sopenharmony_ci      {
1824bf215546Sopenharmony_ci         unsigned target;
1825bf215546Sopenharmony_ci         unsigned res_index = opcode.dst[0].base.index[0].imm;
1826bf215546Sopenharmony_ci         assert(opcode.dst[0].base.index_dim == 1);
1827bf215546Sopenharmony_ci         assert(res_index < SHADER_MAX_RESOURCES);
1828bf215546Sopenharmony_ci
1829bf215546Sopenharmony_ci         target = translate_resource_dimension(opcode.specific.dcl_resource_dimension);
1830bf215546Sopenharmony_ci         sx.resources[res_index].target = target;
1831bf215546Sopenharmony_ci         if (!(st_debug & ST_DEBUG_OLD_TEX_OPS)) {
1832bf215546Sopenharmony_ci            sx.sv[res_index] =
1833bf215546Sopenharmony_ci               ureg_DECL_sampler_view(ureg, res_index, target,
1834bf215546Sopenharmony_ci                                      trans_dcl_ret_type(opcode.dcl_resource_ret_type[0]),
1835bf215546Sopenharmony_ci                                      trans_dcl_ret_type(opcode.dcl_resource_ret_type[1]),
1836bf215546Sopenharmony_ci                                      trans_dcl_ret_type(opcode.dcl_resource_ret_type[2]),
1837bf215546Sopenharmony_ci                                      trans_dcl_ret_type(opcode.dcl_resource_ret_type[3]));
1838bf215546Sopenharmony_ci         }
1839bf215546Sopenharmony_ci         break;
1840bf215546Sopenharmony_ci      }
1841bf215546Sopenharmony_ci
1842bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_CONSTANT_BUFFER: {
1843bf215546Sopenharmony_ci         unsigned num_constants = opcode.src[0].base.index[1].imm;
1844bf215546Sopenharmony_ci
1845bf215546Sopenharmony_ci         assert(opcode.src[0].base.index[0].imm < PIPE_MAX_CONSTANT_BUFFERS);
1846bf215546Sopenharmony_ci
1847bf215546Sopenharmony_ci         if (num_constants == 0) {
1848bf215546Sopenharmony_ci            num_constants = SHADER_MAX_CONSTS;
1849bf215546Sopenharmony_ci         } else {
1850bf215546Sopenharmony_ci            assert(num_constants <= SHADER_MAX_CONSTS);
1851bf215546Sopenharmony_ci         }
1852bf215546Sopenharmony_ci
1853bf215546Sopenharmony_ci         ureg_DECL_constant2D(ureg,
1854bf215546Sopenharmony_ci                              0,
1855bf215546Sopenharmony_ci                              num_constants - 1,
1856bf215546Sopenharmony_ci                              opcode.src[0].base.index[0].imm);
1857bf215546Sopenharmony_ci         break;
1858bf215546Sopenharmony_ci      }
1859bf215546Sopenharmony_ci
1860bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_SAMPLER:
1861bf215546Sopenharmony_ci         assert(opcode.dst[0].base.index_dim == 1);
1862bf215546Sopenharmony_ci         assert(opcode.dst[0].base.index[0].imm < SHADER_MAX_SAMPLERS);
1863bf215546Sopenharmony_ci
1864bf215546Sopenharmony_ci         sx.samplers[opcode.dst[0].base.index[0].imm] =
1865bf215546Sopenharmony_ci            ureg_DECL_sampler(ureg,
1866bf215546Sopenharmony_ci                              opcode.dst[0].base.index[0].imm);
1867bf215546Sopenharmony_ci         break;
1868bf215546Sopenharmony_ci
1869bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY:
1870bf215546Sopenharmony_ci         assert(parser.header.type == D3D10_SB_GEOMETRY_SHADER);
1871bf215546Sopenharmony_ci
1872bf215546Sopenharmony_ci         switch (opcode.specific.dcl_gs_output_primitive_topology) {
1873bf215546Sopenharmony_ci         case D3D10_SB_PRIMITIVE_TOPOLOGY_POINTLIST:
1874bf215546Sopenharmony_ci            ureg_property(sx.ureg,
1875bf215546Sopenharmony_ci                          TGSI_PROPERTY_GS_OUTPUT_PRIM,
1876bf215546Sopenharmony_ci                          PIPE_PRIM_POINTS);
1877bf215546Sopenharmony_ci            break;
1878bf215546Sopenharmony_ci
1879bf215546Sopenharmony_ci         case D3D10_SB_PRIMITIVE_TOPOLOGY_LINESTRIP:
1880bf215546Sopenharmony_ci            ureg_property(sx.ureg,
1881bf215546Sopenharmony_ci                          TGSI_PROPERTY_GS_OUTPUT_PRIM,
1882bf215546Sopenharmony_ci                          PIPE_PRIM_LINE_STRIP);
1883bf215546Sopenharmony_ci            break;
1884bf215546Sopenharmony_ci
1885bf215546Sopenharmony_ci         case D3D10_SB_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:
1886bf215546Sopenharmony_ci            ureg_property(sx.ureg,
1887bf215546Sopenharmony_ci                          TGSI_PROPERTY_GS_OUTPUT_PRIM,
1888bf215546Sopenharmony_ci                          PIPE_PRIM_TRIANGLE_STRIP);
1889bf215546Sopenharmony_ci            break;
1890bf215546Sopenharmony_ci
1891bf215546Sopenharmony_ci         default:
1892bf215546Sopenharmony_ci            assert(0);
1893bf215546Sopenharmony_ci         }
1894bf215546Sopenharmony_ci         break;
1895bf215546Sopenharmony_ci
1896bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_GS_INPUT_PRIMITIVE:
1897bf215546Sopenharmony_ci         assert(parser.header.type == D3D10_SB_GEOMETRY_SHADER);
1898bf215546Sopenharmony_ci
1899bf215546Sopenharmony_ci         /* Figure out the second dimension of GS inputs.
1900bf215546Sopenharmony_ci          */
1901bf215546Sopenharmony_ci         switch (opcode.specific.dcl_gs_input_primitive) {
1902bf215546Sopenharmony_ci         case D3D10_SB_PRIMITIVE_POINT:
1903bf215546Sopenharmony_ci            declare_vertices_in(&sx, 1);
1904bf215546Sopenharmony_ci            ureg_property(sx.ureg,
1905bf215546Sopenharmony_ci                          TGSI_PROPERTY_GS_INPUT_PRIM,
1906bf215546Sopenharmony_ci                          PIPE_PRIM_POINTS);
1907bf215546Sopenharmony_ci            break;
1908bf215546Sopenharmony_ci
1909bf215546Sopenharmony_ci         case D3D10_SB_PRIMITIVE_LINE:
1910bf215546Sopenharmony_ci            declare_vertices_in(&sx, 2);
1911bf215546Sopenharmony_ci            ureg_property(sx.ureg,
1912bf215546Sopenharmony_ci                          TGSI_PROPERTY_GS_INPUT_PRIM,
1913bf215546Sopenharmony_ci                          PIPE_PRIM_LINES);
1914bf215546Sopenharmony_ci            break;
1915bf215546Sopenharmony_ci
1916bf215546Sopenharmony_ci         case D3D10_SB_PRIMITIVE_TRIANGLE:
1917bf215546Sopenharmony_ci            declare_vertices_in(&sx, 3);
1918bf215546Sopenharmony_ci            ureg_property(sx.ureg,
1919bf215546Sopenharmony_ci                          TGSI_PROPERTY_GS_INPUT_PRIM,
1920bf215546Sopenharmony_ci                          PIPE_PRIM_TRIANGLES);
1921bf215546Sopenharmony_ci            break;
1922bf215546Sopenharmony_ci
1923bf215546Sopenharmony_ci         case D3D10_SB_PRIMITIVE_LINE_ADJ:
1924bf215546Sopenharmony_ci            declare_vertices_in(&sx, 4);
1925bf215546Sopenharmony_ci            ureg_property(sx.ureg,
1926bf215546Sopenharmony_ci                          TGSI_PROPERTY_GS_INPUT_PRIM,
1927bf215546Sopenharmony_ci                          PIPE_PRIM_LINES_ADJACENCY);
1928bf215546Sopenharmony_ci            break;
1929bf215546Sopenharmony_ci
1930bf215546Sopenharmony_ci         case D3D10_SB_PRIMITIVE_TRIANGLE_ADJ:
1931bf215546Sopenharmony_ci            declare_vertices_in(&sx, 6);
1932bf215546Sopenharmony_ci            ureg_property(sx.ureg,
1933bf215546Sopenharmony_ci                          TGSI_PROPERTY_GS_INPUT_PRIM,
1934bf215546Sopenharmony_ci                          PIPE_PRIM_TRIANGLES_ADJACENCY);
1935bf215546Sopenharmony_ci            break;
1936bf215546Sopenharmony_ci
1937bf215546Sopenharmony_ci         default:
1938bf215546Sopenharmony_ci            assert(0);
1939bf215546Sopenharmony_ci         }
1940bf215546Sopenharmony_ci         break;
1941bf215546Sopenharmony_ci
1942bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT:
1943bf215546Sopenharmony_ci         assert(parser.header.type == D3D10_SB_GEOMETRY_SHADER);
1944bf215546Sopenharmony_ci
1945bf215546Sopenharmony_ci         ureg_property(sx.ureg,
1946bf215546Sopenharmony_ci                       TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES,
1947bf215546Sopenharmony_ci                       opcode.specific.dcl_max_output_vertex_count);
1948bf215546Sopenharmony_ci         break;
1949bf215546Sopenharmony_ci
1950bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_INPUT:
1951bf215546Sopenharmony_ci         if (parser.header.type == D3D10_SB_VERTEX_SHADER) {
1952bf215546Sopenharmony_ci            dcl_vs_input(&sx, ureg, &opcode.dst[0]);
1953bf215546Sopenharmony_ci         } else {
1954bf215546Sopenharmony_ci            assert(parser.header.type == D3D10_SB_GEOMETRY_SHADER);
1955bf215546Sopenharmony_ci            dcl_gs_input(&sx, ureg, &opcode.dst[0]);
1956bf215546Sopenharmony_ci         }
1957bf215546Sopenharmony_ci         break;
1958bf215546Sopenharmony_ci
1959bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_INPUT_SGV:
1960bf215546Sopenharmony_ci         assert(parser.header.type == D3D10_SB_VERTEX_SHADER);
1961bf215546Sopenharmony_ci         dcl_sgv_input(&sx, ureg, &opcode.dst[0], opcode.dcl_siv_name);
1962bf215546Sopenharmony_ci         break;
1963bf215546Sopenharmony_ci
1964bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_INPUT_SIV:
1965bf215546Sopenharmony_ci         assert(parser.header.type == D3D10_SB_GEOMETRY_SHADER);
1966bf215546Sopenharmony_ci         dcl_siv_input(&sx, ureg, &opcode.dst[0], opcode.dcl_siv_name);
1967bf215546Sopenharmony_ci         break;
1968bf215546Sopenharmony_ci
1969bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_INPUT_PS:
1970bf215546Sopenharmony_ci         assert(parser.header.type == D3D10_SB_PIXEL_SHADER);
1971bf215546Sopenharmony_ci         dcl_ps_input(&sx, ureg, &opcode.dst[0],
1972bf215546Sopenharmony_ci                      opcode.specific.dcl_in_ps_interp);
1973bf215546Sopenharmony_ci         break;
1974bf215546Sopenharmony_ci
1975bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_INPUT_PS_SGV:
1976bf215546Sopenharmony_ci         assert(parser.header.type == D3D10_SB_PIXEL_SHADER);
1977bf215546Sopenharmony_ci         dcl_ps_sgv_input(&sx, ureg, &opcode.dst[0],
1978bf215546Sopenharmony_ci                          opcode.dcl_siv_name);
1979bf215546Sopenharmony_ci         break;
1980bf215546Sopenharmony_ci
1981bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_INPUT_PS_SIV:
1982bf215546Sopenharmony_ci         assert(parser.header.type == D3D10_SB_PIXEL_SHADER);
1983bf215546Sopenharmony_ci         dcl_ps_siv_input(&sx, ureg, &opcode.dst[0],
1984bf215546Sopenharmony_ci                          opcode.dcl_siv_name,
1985bf215546Sopenharmony_ci                          opcode.specific.dcl_in_ps_interp);
1986bf215546Sopenharmony_ci         break;
1987bf215546Sopenharmony_ci
1988bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_OUTPUT:
1989bf215546Sopenharmony_ci         if (parser.header.type == D3D10_SB_PIXEL_SHADER) {
1990bf215546Sopenharmony_ci            /* Pixel shader outputs. */
1991bf215546Sopenharmony_ci            if (opcode.dst[0].base.type == D3D10_SB_OPERAND_TYPE_OUTPUT_DEPTH) {
1992bf215546Sopenharmony_ci               /* Depth output. */
1993bf215546Sopenharmony_ci               assert(opcode.dst[0].base.index_dim == 0);
1994bf215546Sopenharmony_ci
1995bf215546Sopenharmony_ci               sx.output_depth = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_POSITION, 0, TGSI_WRITEMASK_Z, 0, 1);
1996bf215546Sopenharmony_ci               sx.output_depth = ureg_writemask(sx.output_depth, TGSI_WRITEMASK_Z);
1997bf215546Sopenharmony_ci            } else {
1998bf215546Sopenharmony_ci               /* Color outputs. */
1999bf215546Sopenharmony_ci               assert(opcode.dst[0].base.index_dim == 1);
2000bf215546Sopenharmony_ci               assert(opcode.dst[0].base.index[0].imm < SHADER_MAX_OUTPUTS);
2001bf215546Sopenharmony_ci
2002bf215546Sopenharmony_ci               dcl_base_output(&sx, ureg,
2003bf215546Sopenharmony_ci                               ureg_DECL_output(ureg,
2004bf215546Sopenharmony_ci                                                TGSI_SEMANTIC_COLOR,
2005bf215546Sopenharmony_ci                                                opcode.dst[0].base.index[0].imm),
2006bf215546Sopenharmony_ci                               &opcode.dst[0]);
2007bf215546Sopenharmony_ci            }
2008bf215546Sopenharmony_ci         } else {
2009bf215546Sopenharmony_ci            assert(opcode.dst[0].base.index_dim == 1);
2010bf215546Sopenharmony_ci            assert(opcode.dst[0].base.index[0].imm < SHADER_MAX_OUTPUTS);
2011bf215546Sopenharmony_ci
2012bf215546Sopenharmony_ci            if (output_mapping) {
2013bf215546Sopenharmony_ci               unsigned nr_outputs = ureg_get_nr_outputs(ureg);
2014bf215546Sopenharmony_ci               output_mapping[nr_outputs]
2015bf215546Sopenharmony_ci                  = opcode.dst[0].base.index[0].imm;
2016bf215546Sopenharmony_ci            }
2017bf215546Sopenharmony_ci            dcl_base_output(&sx, ureg,
2018bf215546Sopenharmony_ci                            ureg_DECL_output(ureg,
2019bf215546Sopenharmony_ci                                             TGSI_SEMANTIC_GENERIC,
2020bf215546Sopenharmony_ci                                             opcode.dst[0].base.index[0].imm),
2021bf215546Sopenharmony_ci                            &opcode.dst[0]);
2022bf215546Sopenharmony_ci         }
2023bf215546Sopenharmony_ci         break;
2024bf215546Sopenharmony_ci
2025bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_OUTPUT_SIV:
2026bf215546Sopenharmony_ci         assert(opcode.dst[0].base.index_dim == 1);
2027bf215546Sopenharmony_ci         assert(opcode.dst[0].base.index[0].imm < SHADER_MAX_OUTPUTS);
2028bf215546Sopenharmony_ci
2029bf215546Sopenharmony_ci         if (output_mapping) {
2030bf215546Sopenharmony_ci            unsigned nr_outputs = ureg_get_nr_outputs(ureg);
2031bf215546Sopenharmony_ci            output_mapping[nr_outputs]
2032bf215546Sopenharmony_ci               = opcode.dst[0].base.index[0].imm;
2033bf215546Sopenharmony_ci         }
2034bf215546Sopenharmony_ci         if (opcode.dcl_siv_name == D3D10_SB_NAME_CLIP_DISTANCE ||
2035bf215546Sopenharmony_ci             opcode.dcl_siv_name == D3D10_SB_NAME_CULL_DISTANCE) {
2036bf215546Sopenharmony_ci            /*
2037bf215546Sopenharmony_ci             * FIXME: this is quite broken. gallium no longer has separate
2038bf215546Sopenharmony_ci             * clip/cull dists, using (max 2) combined clipdist/culldist regs
2039bf215546Sopenharmony_ci             * instead. Unlike d3d10 though, which is clip and which cull is
2040bf215546Sopenharmony_ci             * simply determined by by number of clip/cull dists (that is,
2041bf215546Sopenharmony_ci             * all clip dists must come first).
2042bf215546Sopenharmony_ci             */
2043bf215546Sopenharmony_ci            unsigned numcliporcull = sx.num_clip_distances_declared +
2044bf215546Sopenharmony_ci                                     sx.num_cull_distances_declared;
2045bf215546Sopenharmony_ci            sx.clip_distance_mapping[numcliporcull].d3d =
2046bf215546Sopenharmony_ci               opcode.dst[0].base.index[0].imm;
2047bf215546Sopenharmony_ci            sx.clip_distance_mapping[numcliporcull].tgsi = numcliporcull;
2048bf215546Sopenharmony_ci            if (opcode.dcl_siv_name == D3D10_SB_NAME_CLIP_DISTANCE) {
2049bf215546Sopenharmony_ci               ++sx.num_clip_distances_declared;
2050bf215546Sopenharmony_ci               /* re-emit should be safe... */
2051bf215546Sopenharmony_ci               ureg_property(ureg, TGSI_PROPERTY_NUM_CLIPDIST_ENABLED,
2052bf215546Sopenharmony_ci                             sx.num_clip_distances_declared);
2053bf215546Sopenharmony_ci            } else {
2054bf215546Sopenharmony_ci               ++sx.num_cull_distances_declared;
2055bf215546Sopenharmony_ci               ureg_property(ureg, TGSI_PROPERTY_NUM_CULLDIST_ENABLED,
2056bf215546Sopenharmony_ci                             sx.num_cull_distances_declared);
2057bf215546Sopenharmony_ci            }
2058bf215546Sopenharmony_ci         } else if (0 && opcode.dcl_siv_name == D3D10_SB_NAME_CULL_DISTANCE) {
2059bf215546Sopenharmony_ci            sx.cull_distance_mapping[sx.num_cull_distances_declared].d3d =
2060bf215546Sopenharmony_ci               opcode.dst[0].base.index[0].imm;
2061bf215546Sopenharmony_ci            sx.cull_distance_mapping[sx.num_cull_distances_declared].tgsi =
2062bf215546Sopenharmony_ci               sx.num_cull_distances_declared;
2063bf215546Sopenharmony_ci            ++sx.num_cull_distances_declared;
2064bf215546Sopenharmony_ci            ureg_property(ureg, TGSI_PROPERTY_NUM_CULLDIST_ENABLED,
2065bf215546Sopenharmony_ci                          sx.num_cull_distances_declared);
2066bf215546Sopenharmony_ci         }
2067bf215546Sopenharmony_ci
2068bf215546Sopenharmony_ci         dcl_base_output(&sx, ureg,
2069bf215546Sopenharmony_ci                         ureg_DECL_output_masked(
2070bf215546Sopenharmony_ci                            ureg,
2071bf215546Sopenharmony_ci                            translate_system_name(opcode.dcl_siv_name),
2072bf215546Sopenharmony_ci                            translate_semantic_index(&sx, opcode.dcl_siv_name,
2073bf215546Sopenharmony_ci                                                     &opcode.dst[0]),
2074bf215546Sopenharmony_ci                            opcode.dst[0].mask >> D3D10_SB_OPERAND_4_COMPONENT_MASK_SHIFT,
2075bf215546Sopenharmony_ci                            0, 1),
2076bf215546Sopenharmony_ci                         &opcode.dst[0]);
2077bf215546Sopenharmony_ci         break;
2078bf215546Sopenharmony_ci
2079bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_OUTPUT_SGV:
2080bf215546Sopenharmony_ci         assert(opcode.dst[0].base.index_dim == 1);
2081bf215546Sopenharmony_ci         assert(opcode.dst[0].base.index[0].imm < SHADER_MAX_OUTPUTS);
2082bf215546Sopenharmony_ci
2083bf215546Sopenharmony_ci         if (output_mapping) {
2084bf215546Sopenharmony_ci            unsigned nr_outputs = ureg_get_nr_outputs(ureg);
2085bf215546Sopenharmony_ci            output_mapping[nr_outputs]
2086bf215546Sopenharmony_ci               = opcode.dst[0].base.index[0].imm;
2087bf215546Sopenharmony_ci         }
2088bf215546Sopenharmony_ci         dcl_base_output(&sx, ureg,
2089bf215546Sopenharmony_ci                         ureg_DECL_output(ureg,
2090bf215546Sopenharmony_ci                                          translate_system_name(opcode.dcl_siv_name),
2091bf215546Sopenharmony_ci                                          0),
2092bf215546Sopenharmony_ci                         &opcode.dst[0]);
2093bf215546Sopenharmony_ci         break;
2094bf215546Sopenharmony_ci
2095bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_TEMPS:
2096bf215546Sopenharmony_ci         {
2097bf215546Sopenharmony_ci            uint i;
2098bf215546Sopenharmony_ci
2099bf215546Sopenharmony_ci            assert(opcode.specific.dcl_num_temps + sx.declared_temps <=
2100bf215546Sopenharmony_ci                   SHADER_MAX_TEMPS);
2101bf215546Sopenharmony_ci
2102bf215546Sopenharmony_ci            sx.temp_offset = sx.declared_temps;
2103bf215546Sopenharmony_ci
2104bf215546Sopenharmony_ci            for (i = 0; i < opcode.specific.dcl_num_temps; i++) {
2105bf215546Sopenharmony_ci               sx.temps[sx.declared_temps + i] = ureg_DECL_temporary(ureg);
2106bf215546Sopenharmony_ci            }
2107bf215546Sopenharmony_ci            sx.declared_temps += opcode.specific.dcl_num_temps;
2108bf215546Sopenharmony_ci         }
2109bf215546Sopenharmony_ci         break;
2110bf215546Sopenharmony_ci
2111bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP:
2112bf215546Sopenharmony_ci         {
2113bf215546Sopenharmony_ci            uint i;
2114bf215546Sopenharmony_ci
2115bf215546Sopenharmony_ci            /* XXX: Add true indexable temps to gallium.
2116bf215546Sopenharmony_ci             */
2117bf215546Sopenharmony_ci
2118bf215546Sopenharmony_ci            assert(opcode.specific.dcl_indexable_temp.index <
2119bf215546Sopenharmony_ci                   SHADER_MAX_INDEXABLE_TEMPS);
2120bf215546Sopenharmony_ci            assert(opcode.specific.dcl_indexable_temp.count + sx.declared_temps <=
2121bf215546Sopenharmony_ci                   SHADER_MAX_TEMPS);
2122bf215546Sopenharmony_ci
2123bf215546Sopenharmony_ci            sx.indexable_temp_offsets[opcode.specific.dcl_indexable_temp.index] =
2124bf215546Sopenharmony_ci               sx.declared_temps;
2125bf215546Sopenharmony_ci
2126bf215546Sopenharmony_ci            for (i = 0; i < opcode.specific.dcl_indexable_temp.count; i++) {
2127bf215546Sopenharmony_ci               sx.temps[sx.declared_temps + i] = ureg_DECL_temporary(ureg);
2128bf215546Sopenharmony_ci            }
2129bf215546Sopenharmony_ci            sx.declared_temps += opcode.specific.dcl_indexable_temp.count;
2130bf215546Sopenharmony_ci         }
2131bf215546Sopenharmony_ci         break;
2132bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_IF: {
2133bf215546Sopenharmony_ci         unsigned label = 0;
2134bf215546Sopenharmony_ci         if (opcode.specific.test_boolean == D3D10_SB_INSTRUCTION_TEST_ZERO) {
2135bf215546Sopenharmony_ci            struct ureg_src src =
2136bf215546Sopenharmony_ci               translate_src_operand(&sx, &opcode.src[0], OF_INT);
2137bf215546Sopenharmony_ci            struct ureg_dst src_nz = ureg_DECL_temporary(ureg);
2138bf215546Sopenharmony_ci            ureg_USEQ(ureg, src_nz, src, ureg_imm1u(ureg, 0));
2139bf215546Sopenharmony_ci            ureg_UIF(ureg, ureg_src(src_nz), &label);
2140bf215546Sopenharmony_ci            ureg_release_temporary(ureg, src_nz);;
2141bf215546Sopenharmony_ci         } else {
2142bf215546Sopenharmony_ci            ureg_UIF(ureg, translate_src_operand(&sx, &opcode.src[0], OF_INT), &label);
2143bf215546Sopenharmony_ci         }
2144bf215546Sopenharmony_ci      }
2145bf215546Sopenharmony_ci         break;
2146bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_RETC:
2147bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_CONTINUEC:
2148bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_CALLC:
2149bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DISCARD:
2150bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_BREAKC:
2151bf215546Sopenharmony_ci      {
2152bf215546Sopenharmony_ci         unsigned label = 0;
2153bf215546Sopenharmony_ci         assert(operand_is_scalar(&opcode.src[0]));
2154bf215546Sopenharmony_ci         if (opcode.specific.test_boolean == D3D10_SB_INSTRUCTION_TEST_ZERO) {
2155bf215546Sopenharmony_ci            struct ureg_src src =
2156bf215546Sopenharmony_ci               translate_src_operand(&sx, &opcode.src[0], OF_INT);
2157bf215546Sopenharmony_ci            struct ureg_dst src_nz = ureg_DECL_temporary(ureg);
2158bf215546Sopenharmony_ci            ureg_USEQ(ureg, src_nz, src, ureg_imm1u(ureg, 0));
2159bf215546Sopenharmony_ci            ureg_UIF(ureg, ureg_src(src_nz), &label);
2160bf215546Sopenharmony_ci            ureg_release_temporary(ureg, src_nz);
2161bf215546Sopenharmony_ci         }
2162bf215546Sopenharmony_ci         else {
2163bf215546Sopenharmony_ci            ureg_UIF(ureg, translate_src_operand(&sx, &opcode.src[0], OF_INT), &label);
2164bf215546Sopenharmony_ci         }
2165bf215546Sopenharmony_ci         switch (opcode.type) {
2166bf215546Sopenharmony_ci         case D3D10_SB_OPCODE_RETC:
2167bf215546Sopenharmony_ci            ureg_RET(ureg);
2168bf215546Sopenharmony_ci            break;
2169bf215546Sopenharmony_ci         case D3D10_SB_OPCODE_CONTINUEC:
2170bf215546Sopenharmony_ci            ureg_CONT(ureg);
2171bf215546Sopenharmony_ci            break;
2172bf215546Sopenharmony_ci         case D3D10_SB_OPCODE_CALLC: {
2173bf215546Sopenharmony_ci            unsigned label = opcode.src[1].base.index[0].imm;
2174bf215546Sopenharmony_ci            unsigned tgsi_token_label = 0;
2175bf215546Sopenharmony_ci            ureg_CAL(ureg, &tgsi_token_label);
2176bf215546Sopenharmony_ci            Shader_add_call(&sx, label, tgsi_token_label);
2177bf215546Sopenharmony_ci         }
2178bf215546Sopenharmony_ci            break;
2179bf215546Sopenharmony_ci         case D3D10_SB_OPCODE_DISCARD:
2180bf215546Sopenharmony_ci            ureg_KILL(ureg);
2181bf215546Sopenharmony_ci            break;
2182bf215546Sopenharmony_ci         case D3D10_SB_OPCODE_BREAKC:
2183bf215546Sopenharmony_ci            ureg_BRK(ureg);
2184bf215546Sopenharmony_ci            break;
2185bf215546Sopenharmony_ci         default:
2186bf215546Sopenharmony_ci            assert(0);
2187bf215546Sopenharmony_ci            break;
2188bf215546Sopenharmony_ci         }
2189bf215546Sopenharmony_ci         ureg_ENDIF(ureg);
2190bf215546Sopenharmony_ci      }
2191bf215546Sopenharmony_ci         break;
2192bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_LABEL: {
2193bf215546Sopenharmony_ci         unsigned label = opcode.src[0].base.index[0].imm;
2194bf215546Sopenharmony_ci         unsigned tgsi_inst_no = 0;
2195bf215546Sopenharmony_ci         if (inside_sub) {
2196bf215546Sopenharmony_ci            ureg_ENDSUB(ureg);
2197bf215546Sopenharmony_ci         }
2198bf215546Sopenharmony_ci         tgsi_inst_no = ureg_get_instruction_number(ureg);
2199bf215546Sopenharmony_ci         ureg_BGNSUB(ureg);
2200bf215546Sopenharmony_ci         inside_sub = TRUE;
2201bf215546Sopenharmony_ci         Shader_add_label(&sx, label, tgsi_inst_no);
2202bf215546Sopenharmony_ci      }
2203bf215546Sopenharmony_ci         break;
2204bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_CALL: {
2205bf215546Sopenharmony_ci         unsigned label = opcode.src[0].base.index[0].imm;
2206bf215546Sopenharmony_ci         unsigned tgsi_token_label = 0;
2207bf215546Sopenharmony_ci         ureg_CAL(ureg, &tgsi_token_label);
2208bf215546Sopenharmony_ci         Shader_add_call(&sx, label, tgsi_token_label);
2209bf215546Sopenharmony_ci      }
2210bf215546Sopenharmony_ci         break;
2211bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_EMIT:
2212bf215546Sopenharmony_ci         ureg_EMIT(ureg, ureg_imm1u(ureg, 0));
2213bf215546Sopenharmony_ci         break;
2214bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_CUT:
2215bf215546Sopenharmony_ci         ureg_ENDPRIM(ureg, ureg_imm1u(ureg, 0));
2216bf215546Sopenharmony_ci         break;
2217bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_EMITTHENCUT:
2218bf215546Sopenharmony_ci         ureg_EMIT(ureg, ureg_imm1u(ureg, 0));
2219bf215546Sopenharmony_ci         ureg_ENDPRIM(ureg, ureg_imm1u(ureg, 0));
2220bf215546Sopenharmony_ci         break;
2221bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_INDEX_RANGE:
2222bf215546Sopenharmony_ci      case D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS:
2223bf215546Sopenharmony_ci         /* Ignore */
2224bf215546Sopenharmony_ci         break;
2225bf215546Sopenharmony_ci      default:
2226bf215546Sopenharmony_ci         {
2227bf215546Sopenharmony_ci            uint i;
2228bf215546Sopenharmony_ci            struct ureg_dst dst[SHADER_MAX_DST_OPERANDS];
2229bf215546Sopenharmony_ci            struct ureg_src src[SHADER_MAX_SRC_OPERANDS];
2230bf215546Sopenharmony_ci
2231bf215546Sopenharmony_ci            assert(ox->tgsi_opcode != TGSI_EXPAND);
2232bf215546Sopenharmony_ci
2233bf215546Sopenharmony_ci            if (ox->tgsi_opcode == TGSI_LOG_UNSUPPORTED) {
2234bf215546Sopenharmony_ci               if (!shader_dumped) {
2235bf215546Sopenharmony_ci                  dx10_shader_dump_tokens(code);
2236bf215546Sopenharmony_ci                  shader_dumped = TRUE;
2237bf215546Sopenharmony_ci               }
2238bf215546Sopenharmony_ci               debug_printf("%s: unsupported opcode %i\n",
2239bf215546Sopenharmony_ci                            __FUNCTION__, ox->type);
2240bf215546Sopenharmony_ci               assert(ox->tgsi_opcode != TGSI_LOG_UNSUPPORTED);
2241bf215546Sopenharmony_ci            }
2242bf215546Sopenharmony_ci
2243bf215546Sopenharmony_ci            /* Destination operands. */
2244bf215546Sopenharmony_ci            for (i = 0; i < opcode.num_dst; i++) {
2245bf215546Sopenharmony_ci               dst[i] = translate_dst_operand(&sx, &opcode.dst[i],
2246bf215546Sopenharmony_ci                                              opcode.saturate);
2247bf215546Sopenharmony_ci            }
2248bf215546Sopenharmony_ci
2249bf215546Sopenharmony_ci            /* Source operands. */
2250bf215546Sopenharmony_ci            for (i = 0; i < opcode.num_src; i++) {
2251bf215546Sopenharmony_ci               src[i] = translate_src_operand(&sx, &opcode.src[i], ox->format);
2252bf215546Sopenharmony_ci            }
2253bf215546Sopenharmony_ci
2254bf215546Sopenharmony_ci            /* Try to re-route output depth to Z channel. */
2255bf215546Sopenharmony_ci            if (opcode.dst[0].base.type == D3D10_SB_OPERAND_TYPE_OUTPUT_DEPTH) {
2256bf215546Sopenharmony_ci               LOG_UNSUPPORTED(opcode.type != D3D10_SB_OPCODE_MOV);
2257bf215546Sopenharmony_ci               dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_Z);
2258bf215546Sopenharmony_ci               src[0] = ureg_scalar(src[0], TGSI_SWIZZLE_X);
2259bf215546Sopenharmony_ci            }
2260bf215546Sopenharmony_ci
2261bf215546Sopenharmony_ci            ureg_insn(ureg,
2262bf215546Sopenharmony_ci                      ox->tgsi_opcode,
2263bf215546Sopenharmony_ci                      dst,
2264bf215546Sopenharmony_ci                      opcode.num_dst,
2265bf215546Sopenharmony_ci                      src,
2266bf215546Sopenharmony_ci                      opcode.num_src, 0);
2267bf215546Sopenharmony_ci         }
2268bf215546Sopenharmony_ci      }
2269bf215546Sopenharmony_ci
2270bf215546Sopenharmony_ci      Shader_opcode_free(&opcode);
2271bf215546Sopenharmony_ci   }
2272bf215546Sopenharmony_ci
2273bf215546Sopenharmony_ci   if (inside_sub) {
2274bf215546Sopenharmony_ci      ureg_ENDSUB(ureg);
2275bf215546Sopenharmony_ci   }
2276bf215546Sopenharmony_ci
2277bf215546Sopenharmony_ci   ureg_END(ureg);
2278bf215546Sopenharmony_ci
2279bf215546Sopenharmony_ci   for (i = 0; i < sx.num_calls; ++i) {
2280bf215546Sopenharmony_ci      for (j = 0; j < sx.num_labels; ++j) {
2281bf215546Sopenharmony_ci         if (sx.calls[i].d3d_label == sx.labels[j].d3d_label) {
2282bf215546Sopenharmony_ci            ureg_fixup_label(sx.ureg,
2283bf215546Sopenharmony_ci                             sx.calls[i].tgsi_label_token,
2284bf215546Sopenharmony_ci                             sx.labels[j].tgsi_insn_no);
2285bf215546Sopenharmony_ci            break;
2286bf215546Sopenharmony_ci         }
2287bf215546Sopenharmony_ci      }
2288bf215546Sopenharmony_ci      ASSERT(j < sx.num_labels);
2289bf215546Sopenharmony_ci   }
2290bf215546Sopenharmony_ci   FREE(sx.labels);
2291bf215546Sopenharmony_ci   FREE(sx.calls);
2292bf215546Sopenharmony_ci
2293bf215546Sopenharmony_ci   tokens = ureg_get_tokens(ureg, &nr_tokens);
2294bf215546Sopenharmony_ci   assert(tokens);
2295bf215546Sopenharmony_ci   ureg_destroy(ureg);
2296bf215546Sopenharmony_ci
2297bf215546Sopenharmony_ci   if (st_debug & ST_DEBUG_TGSI) {
2298bf215546Sopenharmony_ci      tgsi_dump(tokens, 0);
2299bf215546Sopenharmony_ci   }
2300bf215546Sopenharmony_ci
2301bf215546Sopenharmony_ci   return tokens;
2302bf215546Sopenharmony_ci}
2303