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