Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenshader_sm1.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2002-2003 Jason Edmeades 00003 * Copyright 2002-2003 Raphael Junqueira 00004 * Copyright 2004 Christian Costa 00005 * Copyright 2005 Oliver Stieber 00006 * Copyright 2006 Ivan Gyurdiev 00007 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers 00008 * Copyright 2009 Henri Verbeet for CodeWeavers 00009 * 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00023 */ 00024 00025 #include "config.h" 00026 #include "wine/port.h" 00027 00028 #include "wined3d_private.h" 00029 00030 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); 00031 00032 /* DCL usage masks */ 00033 #define WINED3DSP_DCL_USAGE_SHIFT 0 00034 #define WINED3DSP_DCL_USAGE_MASK (0xf << WINED3DSP_DCL_USAGE_SHIFT) 00035 #define WINED3DSP_DCL_USAGEINDEX_SHIFT 16 00036 #define WINED3DSP_DCL_USAGEINDEX_MASK (0xf << WINED3DSP_DCL_USAGEINDEX_SHIFT) 00037 00038 /* DCL sampler type */ 00039 #define WINED3DSP_TEXTURETYPE_SHIFT 27 00040 #define WINED3DSP_TEXTURETYPE_MASK (0xf << WINED3DSP_TEXTURETYPE_SHIFT) 00041 00042 /* Opcode-related masks */ 00043 #define WINED3DSI_OPCODE_MASK 0x0000ffff 00044 00045 #define WINED3D_OPCODESPECIFICCONTROL_SHIFT 16 00046 #define WINED3D_OPCODESPECIFICCONTROL_MASK (0xff << WINED3D_OPCODESPECIFICCONTROL_SHIFT) 00047 00048 #define WINED3DSI_INSTLENGTH_SHIFT 24 00049 #define WINED3DSI_INSTLENGTH_MASK (0xf << WINED3DSI_INSTLENGTH_SHIFT) 00050 00051 #define WINED3DSI_COISSUE (1 << 30) 00052 00053 #define WINED3DSI_COMMENTSIZE_SHIFT 16 00054 #define WINED3DSI_COMMENTSIZE_MASK (0x7fff << WINED3DSI_COMMENTSIZE_SHIFT) 00055 00056 #define WINED3DSHADER_INSTRUCTION_PREDICATED (1 << 28) 00057 00058 /* Register number mask */ 00059 #define WINED3DSP_REGNUM_MASK 0x000007ff 00060 00061 /* Register type masks */ 00062 #define WINED3DSP_REGTYPE_SHIFT 28 00063 #define WINED3DSP_REGTYPE_MASK (0x7 << WINED3DSP_REGTYPE_SHIFT) 00064 #define WINED3DSP_REGTYPE_SHIFT2 8 00065 #define WINED3DSP_REGTYPE_MASK2 (0x18 << WINED3DSP_REGTYPE_SHIFT2) 00066 00067 /* Relative addressing mask */ 00068 #define WINED3DSHADER_ADDRESSMODE_SHIFT 13 00069 #define WINED3DSHADER_ADDRESSMODE_MASK (1 << WINED3DSHADER_ADDRESSMODE_SHIFT) 00070 00071 /* Destination modifier mask */ 00072 #define WINED3DSP_DSTMOD_SHIFT 20 00073 #define WINED3DSP_DSTMOD_MASK (0xf << WINED3DSP_DSTMOD_SHIFT) 00074 00075 /* Destination shift mask */ 00076 #define WINED3DSP_DSTSHIFT_SHIFT 24 00077 #define WINED3DSP_DSTSHIFT_MASK (0xf << WINED3DSP_DSTSHIFT_SHIFT) 00078 00079 /* Write mask */ 00080 #define WINED3D_SM1_WRITEMASK_SHIFT 16 00081 #define WINED3D_SM1_WRITEMASK_MASK (0xf << WINED3D_SM1_WRITEMASK_SHIFT) 00082 00083 /* Swizzle mask */ 00084 #define WINED3DSP_SWIZZLE_SHIFT 16 00085 #define WINED3DSP_SWIZZLE_MASK (0xff << WINED3DSP_SWIZZLE_SHIFT) 00086 00087 /* Source modifier mask */ 00088 #define WINED3DSP_SRCMOD_SHIFT 24 00089 #define WINED3DSP_SRCMOD_MASK (0xf << WINED3DSP_SRCMOD_SHIFT) 00090 00091 #define WINED3DSP_END 0x0000ffff 00092 00093 #define WINED3D_SM1_VERSION_MAJOR(version) (((version) >> 8) & 0xff) 00094 #define WINED3D_SM1_VERSION_MINOR(version) (((version) >> 0) & 0xff) 00095 00096 enum WINED3DSHADER_ADDRESSMODE_TYPE 00097 { 00098 WINED3DSHADER_ADDRMODE_ABSOLUTE = 0 << WINED3DSHADER_ADDRESSMODE_SHIFT, 00099 WINED3DSHADER_ADDRMODE_RELATIVE = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT, 00100 }; 00101 00102 enum wined3d_sm1_opcode 00103 { 00104 WINED3D_SM1_OP_NOP = 0x00, 00105 WINED3D_SM1_OP_MOV = 0x01, 00106 WINED3D_SM1_OP_ADD = 0x02, 00107 WINED3D_SM1_OP_SUB = 0x03, 00108 WINED3D_SM1_OP_MAD = 0x04, 00109 WINED3D_SM1_OP_MUL = 0x05, 00110 WINED3D_SM1_OP_RCP = 0x06, 00111 WINED3D_SM1_OP_RSQ = 0x07, 00112 WINED3D_SM1_OP_DP3 = 0x08, 00113 WINED3D_SM1_OP_DP4 = 0x09, 00114 WINED3D_SM1_OP_MIN = 0x0a, 00115 WINED3D_SM1_OP_MAX = 0x0b, 00116 WINED3D_SM1_OP_SLT = 0x0c, 00117 WINED3D_SM1_OP_SGE = 0x0d, 00118 WINED3D_SM1_OP_EXP = 0x0e, 00119 WINED3D_SM1_OP_LOG = 0x0f, 00120 WINED3D_SM1_OP_LIT = 0x10, 00121 WINED3D_SM1_OP_DST = 0x11, 00122 WINED3D_SM1_OP_LRP = 0x12, 00123 WINED3D_SM1_OP_FRC = 0x13, 00124 WINED3D_SM1_OP_M4x4 = 0x14, 00125 WINED3D_SM1_OP_M4x3 = 0x15, 00126 WINED3D_SM1_OP_M3x4 = 0x16, 00127 WINED3D_SM1_OP_M3x3 = 0x17, 00128 WINED3D_SM1_OP_M3x2 = 0x18, 00129 WINED3D_SM1_OP_CALL = 0x19, 00130 WINED3D_SM1_OP_CALLNZ = 0x1a, 00131 WINED3D_SM1_OP_LOOP = 0x1b, 00132 WINED3D_SM1_OP_RET = 0x1c, 00133 WINED3D_SM1_OP_ENDLOOP = 0x1d, 00134 WINED3D_SM1_OP_LABEL = 0x1e, 00135 WINED3D_SM1_OP_DCL = 0x1f, 00136 WINED3D_SM1_OP_POW = 0x20, 00137 WINED3D_SM1_OP_CRS = 0x21, 00138 WINED3D_SM1_OP_SGN = 0x22, 00139 WINED3D_SM1_OP_ABS = 0x23, 00140 WINED3D_SM1_OP_NRM = 0x24, 00141 WINED3D_SM1_OP_SINCOS = 0x25, 00142 WINED3D_SM1_OP_REP = 0x26, 00143 WINED3D_SM1_OP_ENDREP = 0x27, 00144 WINED3D_SM1_OP_IF = 0x28, 00145 WINED3D_SM1_OP_IFC = 0x29, 00146 WINED3D_SM1_OP_ELSE = 0x2a, 00147 WINED3D_SM1_OP_ENDIF = 0x2b, 00148 WINED3D_SM1_OP_BREAK = 0x2c, 00149 WINED3D_SM1_OP_BREAKC = 0x2d, 00150 WINED3D_SM1_OP_MOVA = 0x2e, 00151 WINED3D_SM1_OP_DEFB = 0x2f, 00152 WINED3D_SM1_OP_DEFI = 0x30, 00153 00154 WINED3D_SM1_OP_TEXCOORD = 0x40, 00155 WINED3D_SM1_OP_TEXKILL = 0x41, 00156 WINED3D_SM1_OP_TEX = 0x42, 00157 WINED3D_SM1_OP_TEXBEM = 0x43, 00158 WINED3D_SM1_OP_TEXBEML = 0x44, 00159 WINED3D_SM1_OP_TEXREG2AR = 0x45, 00160 WINED3D_SM1_OP_TEXREG2GB = 0x46, 00161 WINED3D_SM1_OP_TEXM3x2PAD = 0x47, 00162 WINED3D_SM1_OP_TEXM3x2TEX = 0x48, 00163 WINED3D_SM1_OP_TEXM3x3PAD = 0x49, 00164 WINED3D_SM1_OP_TEXM3x3TEX = 0x4a, 00165 WINED3D_SM1_OP_TEXM3x3DIFF = 0x4b, 00166 WINED3D_SM1_OP_TEXM3x3SPEC = 0x4c, 00167 WINED3D_SM1_OP_TEXM3x3VSPEC = 0x4d, 00168 WINED3D_SM1_OP_EXPP = 0x4e, 00169 WINED3D_SM1_OP_LOGP = 0x4f, 00170 WINED3D_SM1_OP_CND = 0x50, 00171 WINED3D_SM1_OP_DEF = 0x51, 00172 WINED3D_SM1_OP_TEXREG2RGB = 0x52, 00173 WINED3D_SM1_OP_TEXDP3TEX = 0x53, 00174 WINED3D_SM1_OP_TEXM3x2DEPTH = 0x54, 00175 WINED3D_SM1_OP_TEXDP3 = 0x55, 00176 WINED3D_SM1_OP_TEXM3x3 = 0x56, 00177 WINED3D_SM1_OP_TEXDEPTH = 0x57, 00178 WINED3D_SM1_OP_CMP = 0x58, 00179 WINED3D_SM1_OP_BEM = 0x59, 00180 WINED3D_SM1_OP_DP2ADD = 0x5a, 00181 WINED3D_SM1_OP_DSX = 0x5b, 00182 WINED3D_SM1_OP_DSY = 0x5c, 00183 WINED3D_SM1_OP_TEXLDD = 0x5d, 00184 WINED3D_SM1_OP_SETP = 0x5e, 00185 WINED3D_SM1_OP_TEXLDL = 0x5f, 00186 WINED3D_SM1_OP_BREAKP = 0x60, 00187 00188 WINED3D_SM1_OP_PHASE = 0xfffd, 00189 WINED3D_SM1_OP_COMMENT = 0xfffe, 00190 WINED3D_SM1_OP_END = 0Xffff, 00191 }; 00192 00193 struct wined3d_sm1_opcode_info 00194 { 00195 enum wined3d_sm1_opcode opcode; 00196 UINT dst_count; 00197 UINT param_count; 00198 enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx; 00199 DWORD min_version; 00200 DWORD max_version; 00201 }; 00202 00203 struct wined3d_sm1_data 00204 { 00205 struct wined3d_shader_version shader_version; 00206 const struct wined3d_sm1_opcode_info *opcode_table; 00207 }; 00208 00209 /* This table is not order or position dependent. */ 00210 static const struct wined3d_sm1_opcode_info vs_opcode_table[] = 00211 { 00212 /* Arithmetic */ 00213 {WINED3D_SM1_OP_NOP, 0, 0, WINED3DSIH_NOP, 0, 0 }, 00214 {WINED3D_SM1_OP_MOV, 1, 2, WINED3DSIH_MOV, 0, 0 }, 00215 {WINED3D_SM1_OP_MOVA, 1, 2, WINED3DSIH_MOVA, WINED3D_SHADER_VERSION(2,0), -1 }, 00216 {WINED3D_SM1_OP_ADD, 1, 3, WINED3DSIH_ADD, 0, 0 }, 00217 {WINED3D_SM1_OP_SUB, 1, 3, WINED3DSIH_SUB, 0, 0 }, 00218 {WINED3D_SM1_OP_MAD, 1, 4, WINED3DSIH_MAD, 0, 0 }, 00219 {WINED3D_SM1_OP_MUL, 1, 3, WINED3DSIH_MUL, 0, 0 }, 00220 {WINED3D_SM1_OP_RCP, 1, 2, WINED3DSIH_RCP, 0, 0 }, 00221 {WINED3D_SM1_OP_RSQ, 1, 2, WINED3DSIH_RSQ, 0, 0 }, 00222 {WINED3D_SM1_OP_DP3, 1, 3, WINED3DSIH_DP3, 0, 0 }, 00223 {WINED3D_SM1_OP_DP4, 1, 3, WINED3DSIH_DP4, 0, 0 }, 00224 {WINED3D_SM1_OP_MIN, 1, 3, WINED3DSIH_MIN, 0, 0 }, 00225 {WINED3D_SM1_OP_MAX, 1, 3, WINED3DSIH_MAX, 0, 0 }, 00226 {WINED3D_SM1_OP_SLT, 1, 3, WINED3DSIH_SLT, 0, 0 }, 00227 {WINED3D_SM1_OP_SGE, 1, 3, WINED3DSIH_SGE, 0, 0 }, 00228 {WINED3D_SM1_OP_ABS, 1, 2, WINED3DSIH_ABS, 0, 0 }, 00229 {WINED3D_SM1_OP_EXP, 1, 2, WINED3DSIH_EXP, 0, 0 }, 00230 {WINED3D_SM1_OP_LOG, 1, 2, WINED3DSIH_LOG, 0, 0 }, 00231 {WINED3D_SM1_OP_EXPP, 1, 2, WINED3DSIH_EXPP, 0, 0 }, 00232 {WINED3D_SM1_OP_LOGP, 1, 2, WINED3DSIH_LOGP, 0, 0 }, 00233 {WINED3D_SM1_OP_LIT, 1, 2, WINED3DSIH_LIT, 0, 0 }, 00234 {WINED3D_SM1_OP_DST, 1, 3, WINED3DSIH_DST, 0, 0 }, 00235 {WINED3D_SM1_OP_LRP, 1, 4, WINED3DSIH_LRP, 0, 0 }, 00236 {WINED3D_SM1_OP_FRC, 1, 2, WINED3DSIH_FRC, 0, 0 }, 00237 {WINED3D_SM1_OP_POW, 1, 3, WINED3DSIH_POW, 0, 0 }, 00238 {WINED3D_SM1_OP_CRS, 1, 3, WINED3DSIH_CRS, 0, 0 }, 00239 {WINED3D_SM1_OP_SGN, 1, 4, WINED3DSIH_SGN, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)}, 00240 {WINED3D_SM1_OP_SGN, 1, 2, WINED3DSIH_SGN, WINED3D_SHADER_VERSION(3,0), -1 }, 00241 {WINED3D_SM1_OP_NRM, 1, 2, WINED3DSIH_NRM, 0, 0 }, 00242 {WINED3D_SM1_OP_SINCOS, 1, 4, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)}, 00243 {WINED3D_SM1_OP_SINCOS, 1, 2, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(3,0), -1 }, 00244 /* Matrix */ 00245 {WINED3D_SM1_OP_M4x4, 1, 3, WINED3DSIH_M4x4, 0, 0 }, 00246 {WINED3D_SM1_OP_M4x3, 1, 3, WINED3DSIH_M4x3, 0, 0 }, 00247 {WINED3D_SM1_OP_M3x4, 1, 3, WINED3DSIH_M3x4, 0, 0 }, 00248 {WINED3D_SM1_OP_M3x3, 1, 3, WINED3DSIH_M3x3, 0, 0 }, 00249 {WINED3D_SM1_OP_M3x2, 1, 3, WINED3DSIH_M3x2, 0, 0 }, 00250 /* Declare registers */ 00251 {WINED3D_SM1_OP_DCL, 0, 2, WINED3DSIH_DCL, 0, 0 }, 00252 /* Constant definitions */ 00253 {WINED3D_SM1_OP_DEF, 1, 5, WINED3DSIH_DEF, 0, 0 }, 00254 {WINED3D_SM1_OP_DEFB, 1, 2, WINED3DSIH_DEFB, 0, 0 }, 00255 {WINED3D_SM1_OP_DEFI, 1, 5, WINED3DSIH_DEFI, 0, 0 }, 00256 /* Flow control */ 00257 {WINED3D_SM1_OP_REP, 0, 1, WINED3DSIH_REP, WINED3D_SHADER_VERSION(2,0), -1 }, 00258 {WINED3D_SM1_OP_ENDREP, 0, 0, WINED3DSIH_ENDREP, WINED3D_SHADER_VERSION(2,0), -1 }, 00259 {WINED3D_SM1_OP_IF, 0, 1, WINED3DSIH_IF, WINED3D_SHADER_VERSION(2,0), -1 }, 00260 {WINED3D_SM1_OP_IFC, 0, 2, WINED3DSIH_IFC, WINED3D_SHADER_VERSION(2,1), -1 }, 00261 {WINED3D_SM1_OP_ELSE, 0, 0, WINED3DSIH_ELSE, WINED3D_SHADER_VERSION(2,0), -1 }, 00262 {WINED3D_SM1_OP_ENDIF, 0, 0, WINED3DSIH_ENDIF, WINED3D_SHADER_VERSION(2,0), -1 }, 00263 {WINED3D_SM1_OP_BREAK, 0, 0, WINED3DSIH_BREAK, WINED3D_SHADER_VERSION(2,1), -1 }, 00264 {WINED3D_SM1_OP_BREAKC, 0, 2, WINED3DSIH_BREAKC, WINED3D_SHADER_VERSION(2,1), -1 }, 00265 {WINED3D_SM1_OP_BREAKP, 0, 1, WINED3DSIH_BREAKP, 0, 0 }, 00266 {WINED3D_SM1_OP_CALL, 0, 1, WINED3DSIH_CALL, WINED3D_SHADER_VERSION(2,0), -1 }, 00267 {WINED3D_SM1_OP_CALLNZ, 0, 2, WINED3DSIH_CALLNZ, WINED3D_SHADER_VERSION(2,0), -1 }, 00268 {WINED3D_SM1_OP_LOOP, 0, 2, WINED3DSIH_LOOP, WINED3D_SHADER_VERSION(2,0), -1 }, 00269 {WINED3D_SM1_OP_RET, 0, 0, WINED3DSIH_RET, WINED3D_SHADER_VERSION(2,0), -1 }, 00270 {WINED3D_SM1_OP_ENDLOOP, 0, 0, WINED3DSIH_ENDLOOP, WINED3D_SHADER_VERSION(2,0), -1 }, 00271 {WINED3D_SM1_OP_LABEL, 0, 1, WINED3DSIH_LABEL, WINED3D_SHADER_VERSION(2,0), -1 }, 00272 00273 {WINED3D_SM1_OP_SETP, 1, 3, WINED3DSIH_SETP, 0, 0 }, 00274 {WINED3D_SM1_OP_TEXLDL, 1, 3, WINED3DSIH_TEXLDL, WINED3D_SHADER_VERSION(3,0), -1 }, 00275 {0, 0, 0, WINED3DSIH_TABLE_SIZE, 0, 0 }, 00276 }; 00277 00278 static const struct wined3d_sm1_opcode_info ps_opcode_table[] = 00279 { 00280 /* Arithmetic */ 00281 {WINED3D_SM1_OP_NOP, 0, 0, WINED3DSIH_NOP, 0, 0 }, 00282 {WINED3D_SM1_OP_MOV, 1, 2, WINED3DSIH_MOV, 0, 0 }, 00283 {WINED3D_SM1_OP_ADD, 1, 3, WINED3DSIH_ADD, 0, 0 }, 00284 {WINED3D_SM1_OP_SUB, 1, 3, WINED3DSIH_SUB, 0, 0 }, 00285 {WINED3D_SM1_OP_MAD, 1, 4, WINED3DSIH_MAD, 0, 0 }, 00286 {WINED3D_SM1_OP_MUL, 1, 3, WINED3DSIH_MUL, 0, 0 }, 00287 {WINED3D_SM1_OP_RCP, 1, 2, WINED3DSIH_RCP, 0, 0 }, 00288 {WINED3D_SM1_OP_RSQ, 1, 2, WINED3DSIH_RSQ, 0, 0 }, 00289 {WINED3D_SM1_OP_DP3, 1, 3, WINED3DSIH_DP3, 0, 0 }, 00290 {WINED3D_SM1_OP_DP4, 1, 3, WINED3DSIH_DP4, 0, 0 }, 00291 {WINED3D_SM1_OP_MIN, 1, 3, WINED3DSIH_MIN, 0, 0 }, 00292 {WINED3D_SM1_OP_MAX, 1, 3, WINED3DSIH_MAX, 0, 0 }, 00293 {WINED3D_SM1_OP_SLT, 1, 3, WINED3DSIH_SLT, 0, 0 }, 00294 {WINED3D_SM1_OP_SGE, 1, 3, WINED3DSIH_SGE, 0, 0 }, 00295 {WINED3D_SM1_OP_ABS, 1, 2, WINED3DSIH_ABS, 0, 0 }, 00296 {WINED3D_SM1_OP_EXP, 1, 2, WINED3DSIH_EXP, 0, 0 }, 00297 {WINED3D_SM1_OP_LOG, 1, 2, WINED3DSIH_LOG, 0, 0 }, 00298 {WINED3D_SM1_OP_EXPP, 1, 2, WINED3DSIH_EXPP, 0, 0 }, 00299 {WINED3D_SM1_OP_LOGP, 1, 2, WINED3DSIH_LOGP, 0, 0 }, 00300 {WINED3D_SM1_OP_DST, 1, 3, WINED3DSIH_DST, 0, 0 }, 00301 {WINED3D_SM1_OP_LRP, 1, 4, WINED3DSIH_LRP, 0, 0 }, 00302 {WINED3D_SM1_OP_FRC, 1, 2, WINED3DSIH_FRC, 0, 0 }, 00303 {WINED3D_SM1_OP_CND, 1, 4, WINED3DSIH_CND, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,4)}, 00304 {WINED3D_SM1_OP_CMP, 1, 4, WINED3DSIH_CMP, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(3,0)}, 00305 {WINED3D_SM1_OP_POW, 1, 3, WINED3DSIH_POW, 0, 0 }, 00306 {WINED3D_SM1_OP_CRS, 1, 3, WINED3DSIH_CRS, 0, 0 }, 00307 {WINED3D_SM1_OP_NRM, 1, 2, WINED3DSIH_NRM, 0, 0 }, 00308 {WINED3D_SM1_OP_SINCOS, 1, 4, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)}, 00309 {WINED3D_SM1_OP_SINCOS, 1, 2, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(3,0), -1 }, 00310 {WINED3D_SM1_OP_DP2ADD, 1, 4, WINED3DSIH_DP2ADD, WINED3D_SHADER_VERSION(2,0), -1 }, 00311 /* Matrix */ 00312 {WINED3D_SM1_OP_M4x4, 1, 3, WINED3DSIH_M4x4, 0, 0 }, 00313 {WINED3D_SM1_OP_M4x3, 1, 3, WINED3DSIH_M4x3, 0, 0 }, 00314 {WINED3D_SM1_OP_M3x4, 1, 3, WINED3DSIH_M3x4, 0, 0 }, 00315 {WINED3D_SM1_OP_M3x3, 1, 3, WINED3DSIH_M3x3, 0, 0 }, 00316 {WINED3D_SM1_OP_M3x2, 1, 3, WINED3DSIH_M3x2, 0, 0 }, 00317 /* Register declarations */ 00318 {WINED3D_SM1_OP_DCL, 0, 2, WINED3DSIH_DCL, 0, 0 }, 00319 /* Flow control */ 00320 {WINED3D_SM1_OP_REP, 0, 1, WINED3DSIH_REP, WINED3D_SHADER_VERSION(2,1), -1 }, 00321 {WINED3D_SM1_OP_ENDREP, 0, 0, WINED3DSIH_ENDREP, WINED3D_SHADER_VERSION(2,1), -1 }, 00322 {WINED3D_SM1_OP_IF, 0, 1, WINED3DSIH_IF, WINED3D_SHADER_VERSION(2,1), -1 }, 00323 {WINED3D_SM1_OP_IFC, 0, 2, WINED3DSIH_IFC, WINED3D_SHADER_VERSION(2,1), -1 }, 00324 {WINED3D_SM1_OP_ELSE, 0, 0, WINED3DSIH_ELSE, WINED3D_SHADER_VERSION(2,1), -1 }, 00325 {WINED3D_SM1_OP_ENDIF, 0, 0, WINED3DSIH_ENDIF, WINED3D_SHADER_VERSION(2,1), -1 }, 00326 {WINED3D_SM1_OP_BREAK, 0, 0, WINED3DSIH_BREAK, WINED3D_SHADER_VERSION(2,1), -1 }, 00327 {WINED3D_SM1_OP_BREAKC, 0, 2, WINED3DSIH_BREAKC, WINED3D_SHADER_VERSION(2,1), -1 }, 00328 {WINED3D_SM1_OP_BREAKP, 0, 1, WINED3DSIH_BREAKP, 0, 0 }, 00329 {WINED3D_SM1_OP_CALL, 0, 1, WINED3DSIH_CALL, WINED3D_SHADER_VERSION(2,1), -1 }, 00330 {WINED3D_SM1_OP_CALLNZ, 0, 2, WINED3DSIH_CALLNZ, WINED3D_SHADER_VERSION(2,1), -1 }, 00331 {WINED3D_SM1_OP_LOOP, 0, 2, WINED3DSIH_LOOP, WINED3D_SHADER_VERSION(3,0), -1 }, 00332 {WINED3D_SM1_OP_RET, 0, 0, WINED3DSIH_RET, WINED3D_SHADER_VERSION(2,1), -1 }, 00333 {WINED3D_SM1_OP_ENDLOOP, 0, 0, WINED3DSIH_ENDLOOP, WINED3D_SHADER_VERSION(3,0), -1 }, 00334 {WINED3D_SM1_OP_LABEL, 0, 1, WINED3DSIH_LABEL, WINED3D_SHADER_VERSION(2,1), -1 }, 00335 /* Constant definitions */ 00336 {WINED3D_SM1_OP_DEF, 1, 5, WINED3DSIH_DEF, 0, 0 }, 00337 {WINED3D_SM1_OP_DEFB, 1, 2, WINED3DSIH_DEFB, 0, 0 }, 00338 {WINED3D_SM1_OP_DEFI, 1, 5, WINED3DSIH_DEFI, 0, 0 }, 00339 /* Texture */ 00340 {WINED3D_SM1_OP_TEXCOORD, 1, 1, WINED3DSIH_TEXCOORD, 0, WINED3D_SHADER_VERSION(1,3)}, 00341 {WINED3D_SM1_OP_TEXCOORD, 1, 2, WINED3DSIH_TEXCOORD, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)}, 00342 {WINED3D_SM1_OP_TEXKILL, 1, 1, WINED3DSIH_TEXKILL, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(3,0)}, 00343 {WINED3D_SM1_OP_TEX, 1, 1, WINED3DSIH_TEX, 0, WINED3D_SHADER_VERSION(1,3)}, 00344 {WINED3D_SM1_OP_TEX, 1, 2, WINED3DSIH_TEX, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)}, 00345 {WINED3D_SM1_OP_TEX, 1, 3, WINED3DSIH_TEX, WINED3D_SHADER_VERSION(2,0), -1 }, 00346 {WINED3D_SM1_OP_TEXBEM, 1, 2, WINED3DSIH_TEXBEM, 0, WINED3D_SHADER_VERSION(1,3)}, 00347 {WINED3D_SM1_OP_TEXBEML, 1, 2, WINED3DSIH_TEXBEML, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)}, 00348 {WINED3D_SM1_OP_TEXREG2AR, 1, 2, WINED3DSIH_TEXREG2AR, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)}, 00349 {WINED3D_SM1_OP_TEXREG2GB, 1, 2, WINED3DSIH_TEXREG2GB, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)}, 00350 {WINED3D_SM1_OP_TEXREG2RGB, 1, 2, WINED3DSIH_TEXREG2RGB, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)}, 00351 {WINED3D_SM1_OP_TEXM3x2PAD, 1, 2, WINED3DSIH_TEXM3x2PAD, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)}, 00352 {WINED3D_SM1_OP_TEXM3x2TEX, 1, 2, WINED3DSIH_TEXM3x2TEX, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)}, 00353 {WINED3D_SM1_OP_TEXM3x3PAD, 1, 2, WINED3DSIH_TEXM3x3PAD, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)}, 00354 {WINED3D_SM1_OP_TEXM3x3DIFF, 1, 2, WINED3DSIH_TEXM3x3DIFF, WINED3D_SHADER_VERSION(0,0), WINED3D_SHADER_VERSION(0,0)}, 00355 {WINED3D_SM1_OP_TEXM3x3SPEC, 1, 3, WINED3DSIH_TEXM3x3SPEC, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)}, 00356 {WINED3D_SM1_OP_TEXM3x3VSPEC, 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)}, 00357 {WINED3D_SM1_OP_TEXM3x3TEX, 1, 2, WINED3DSIH_TEXM3x3TEX, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)}, 00358 {WINED3D_SM1_OP_TEXDP3TEX, 1, 2, WINED3DSIH_TEXDP3TEX, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)}, 00359 {WINED3D_SM1_OP_TEXM3x2DEPTH, 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3D_SHADER_VERSION(1,3), WINED3D_SHADER_VERSION(1,3)}, 00360 {WINED3D_SM1_OP_TEXDP3, 1, 2, WINED3DSIH_TEXDP3, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)}, 00361 {WINED3D_SM1_OP_TEXM3x3, 1, 2, WINED3DSIH_TEXM3x3, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)}, 00362 {WINED3D_SM1_OP_TEXDEPTH, 1, 1, WINED3DSIH_TEXDEPTH, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)}, 00363 {WINED3D_SM1_OP_BEM, 1, 3, WINED3DSIH_BEM, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)}, 00364 {WINED3D_SM1_OP_DSX, 1, 2, WINED3DSIH_DSX, WINED3D_SHADER_VERSION(2,1), -1 }, 00365 {WINED3D_SM1_OP_DSY, 1, 2, WINED3DSIH_DSY, WINED3D_SHADER_VERSION(2,1), -1 }, 00366 {WINED3D_SM1_OP_TEXLDD, 1, 5, WINED3DSIH_TEXLDD, WINED3D_SHADER_VERSION(2,1), -1 }, 00367 {WINED3D_SM1_OP_SETP, 1, 3, WINED3DSIH_SETP, 0, 0 }, 00368 {WINED3D_SM1_OP_TEXLDL, 1, 3, WINED3DSIH_TEXLDL, WINED3D_SHADER_VERSION(3,0), -1 }, 00369 {WINED3D_SM1_OP_PHASE, 0, 0, WINED3DSIH_PHASE, 0, 0 }, 00370 {0, 0, 0, WINED3DSIH_TABLE_SIZE, 0, 0 }, 00371 }; 00372 00373 /* Read a parameter opcode from the input stream, 00374 * and possibly a relative addressing token. 00375 * Return the number of tokens read */ 00376 static int shader_get_param(const struct wined3d_sm1_data *priv, const DWORD *ptr, DWORD *token, DWORD *addr_token) 00377 { 00378 UINT count = 1; 00379 00380 *token = *ptr; 00381 00382 /* PS >= 3.0 have relative addressing (with token) 00383 * VS >= 2.0 have relative addressing (with token) 00384 * VS >= 1.0 < 2.0 have relative addressing (without token) 00385 * The version check below should work in general */ 00386 if (*ptr & WINED3DSHADER_ADDRMODE_RELATIVE) 00387 { 00388 if (priv->shader_version.major < 2) 00389 { 00390 *addr_token = (1 << 31) 00391 | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT2) & WINED3DSP_REGTYPE_MASK2) 00392 | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT) & WINED3DSP_REGTYPE_MASK) 00393 | (WINED3DSP_NOSWIZZLE << WINED3DSP_SWIZZLE_SHIFT); 00394 } 00395 else 00396 { 00397 *addr_token = *(ptr + 1); 00398 ++count; 00399 } 00400 } 00401 00402 return count; 00403 } 00404 00405 static const struct wined3d_sm1_opcode_info *shader_get_opcode(const struct wined3d_sm1_data *priv, DWORD code) 00406 { 00407 DWORD shader_version = WINED3D_SHADER_VERSION(priv->shader_version.major, priv->shader_version.minor); 00408 const struct wined3d_sm1_opcode_info *opcode_table = priv->opcode_table; 00409 DWORD i = 0; 00410 00411 while (opcode_table[i].handler_idx != WINED3DSIH_TABLE_SIZE) 00412 { 00413 if ((code & WINED3DSI_OPCODE_MASK) == opcode_table[i].opcode 00414 && shader_version >= opcode_table[i].min_version 00415 && (!opcode_table[i].max_version || shader_version <= opcode_table[i].max_version)) 00416 { 00417 return &opcode_table[i]; 00418 } 00419 ++i; 00420 } 00421 00422 FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n", 00423 code, code, code & WINED3DSI_OPCODE_MASK, shader_version); 00424 00425 return NULL; 00426 } 00427 00428 /* Return the number of parameters to skip for an opcode */ 00429 static int shader_skip_opcode(const struct wined3d_sm1_data *priv, 00430 const struct wined3d_sm1_opcode_info *opcode_info, DWORD opcode_token) 00431 { 00432 /* Shaders >= 2.0 may contain address tokens, but fortunately they 00433 * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */ 00434 return (priv->shader_version.major >= 2) 00435 ? ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT) : opcode_info->param_count; 00436 } 00437 00438 static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, 00439 struct wined3d_shader_src_param *src) 00440 { 00441 src->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) 00442 | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); 00443 src->reg.idx = param & WINED3DSP_REGNUM_MASK; 00444 src->reg.array_idx = ~0U; 00445 src->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT; 00446 src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT; 00447 src->reg.rel_addr = rel_addr; 00448 } 00449 00450 static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, 00451 struct wined3d_shader_dst_param *dst) 00452 { 00453 dst->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) 00454 | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); 00455 dst->reg.idx = param & WINED3DSP_REGNUM_MASK; 00456 dst->reg.array_idx = ~0U; 00457 dst->write_mask = (param & WINED3D_SM1_WRITEMASK_MASK) >> WINED3D_SM1_WRITEMASK_SHIFT; 00458 dst->modifiers = (param & WINED3DSP_DSTMOD_MASK) >> WINED3DSP_DSTMOD_SHIFT; 00459 dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; 00460 dst->reg.rel_addr = rel_addr; 00461 } 00462 00463 /* Read the parameters of an unrecognized opcode from the input stream 00464 * Return the number of tokens read. 00465 * 00466 * Note: This function assumes source or destination token format. 00467 * It will not work with specially-formatted tokens like DEF or DCL, 00468 * but hopefully those would be recognized */ 00469 static int shader_skip_unrecognized(const struct wined3d_sm1_data *priv, const DWORD *ptr) 00470 { 00471 int tokens_read = 0; 00472 int i = 0; 00473 00474 /* TODO: Think of a good name for 0x80000000 and replace it with a constant */ 00475 while (*ptr & 0x80000000) 00476 { 00477 DWORD token, addr_token = 0; 00478 struct wined3d_shader_src_param rel_addr; 00479 00480 tokens_read += shader_get_param(priv, ptr, &token, &addr_token); 00481 ptr += tokens_read; 00482 00483 FIXME("Unrecognized opcode param: token=0x%08x addr_token=0x%08x name=", token, addr_token); 00484 00485 if (token & WINED3DSHADER_ADDRMODE_RELATIVE) shader_parse_src_param(addr_token, NULL, &rel_addr); 00486 00487 if (!i) 00488 { 00489 struct wined3d_shader_dst_param dst; 00490 00491 shader_parse_dst_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &dst); 00492 shader_dump_dst_param(&dst, &priv->shader_version); 00493 } 00494 else 00495 { 00496 struct wined3d_shader_src_param src; 00497 00498 shader_parse_src_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &src); 00499 shader_dump_src_param(&src, &priv->shader_version); 00500 } 00501 FIXME("\n"); 00502 ++i; 00503 } 00504 return tokens_read; 00505 } 00506 00507 static void *shader_sm1_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature) 00508 { 00509 struct wined3d_sm1_data *priv; 00510 BYTE major, minor; 00511 00512 major = WINED3D_SM1_VERSION_MAJOR(*byte_code); 00513 minor = WINED3D_SM1_VERSION_MINOR(*byte_code); 00514 if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 0)) 00515 { 00516 WARN("Invalid shader version %u.%u (%#x).\n", major, minor, *byte_code); 00517 return NULL; 00518 } 00519 00520 priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)); 00521 if (!priv) 00522 { 00523 ERR("Failed to allocate private data\n"); 00524 return NULL; 00525 } 00526 00527 if (output_signature) 00528 { 00529 FIXME("SM 1-3 shader shouldn't have output signatures.\n"); 00530 } 00531 00532 switch (*byte_code >> 16) 00533 { 00534 case WINED3D_SM1_VS: 00535 priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX; 00536 priv->opcode_table = vs_opcode_table; 00537 break; 00538 00539 case WINED3D_SM1_PS: 00540 priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL; 00541 priv->opcode_table = ps_opcode_table; 00542 break; 00543 00544 default: 00545 FIXME("Unrecognized shader type %#x\n", *byte_code >> 16); 00546 HeapFree(GetProcessHeap(), 0, priv); 00547 return NULL; 00548 } 00549 00550 return priv; 00551 } 00552 00553 static void shader_sm1_free(void *data) 00554 { 00555 HeapFree(GetProcessHeap(), 0, data); 00556 } 00557 00558 static void shader_sm1_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version) 00559 { 00560 struct wined3d_sm1_data *priv = data; 00561 DWORD version_token; 00562 00563 version_token = *(*ptr)++; 00564 TRACE("version: 0x%08x\n", version_token); 00565 00566 priv->shader_version.major = WINED3D_SM1_VERSION_MAJOR(version_token); 00567 priv->shader_version.minor = WINED3D_SM1_VERSION_MINOR(version_token); 00568 *shader_version = priv->shader_version; 00569 } 00570 00571 static void shader_sm1_read_opcode(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins, 00572 UINT *param_size) 00573 { 00574 struct wined3d_sm1_data *priv = data; 00575 const struct wined3d_sm1_opcode_info *opcode_info; 00576 DWORD opcode_token; 00577 00578 opcode_token = *(*ptr)++; 00579 opcode_info = shader_get_opcode(priv, opcode_token); 00580 if (!opcode_info) 00581 { 00582 FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token); 00583 ins->handler_idx = WINED3DSIH_TABLE_SIZE; 00584 *param_size = shader_skip_unrecognized(priv, *ptr); 00585 return; 00586 } 00587 00588 ins->handler_idx = opcode_info->handler_idx; 00589 ins->flags = (opcode_token & WINED3D_OPCODESPECIFICCONTROL_MASK) >> WINED3D_OPCODESPECIFICCONTROL_SHIFT; 00590 ins->coissue = opcode_token & WINED3DSI_COISSUE; 00591 ins->predicate = opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED; 00592 ins->dst_count = opcode_info->dst_count ? 1 : 0; 00593 ins->src_count = opcode_info->param_count - opcode_info->dst_count; 00594 *param_size = shader_skip_opcode(priv, opcode_info, opcode_token); 00595 } 00596 00597 static void shader_sm1_read_src_param(void *data, const DWORD **ptr, struct wined3d_shader_src_param *src_param, 00598 struct wined3d_shader_src_param *src_rel_addr) 00599 { 00600 struct wined3d_sm1_data *priv = data; 00601 DWORD token, addr_token; 00602 00603 *ptr += shader_get_param(priv, *ptr, &token, &addr_token); 00604 if (token & WINED3DSHADER_ADDRMODE_RELATIVE) 00605 { 00606 shader_parse_src_param(addr_token, NULL, src_rel_addr); 00607 shader_parse_src_param(token, src_rel_addr, src_param); 00608 } 00609 else 00610 { 00611 shader_parse_src_param(token, NULL, src_param); 00612 } 00613 } 00614 00615 static void shader_sm1_read_dst_param(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param, 00616 struct wined3d_shader_src_param *dst_rel_addr) 00617 { 00618 struct wined3d_sm1_data *priv = data; 00619 DWORD token, addr_token; 00620 00621 *ptr += shader_get_param(priv, *ptr, &token, &addr_token); 00622 if (token & WINED3DSHADER_ADDRMODE_RELATIVE) 00623 { 00624 shader_parse_src_param(addr_token, NULL, dst_rel_addr); 00625 shader_parse_dst_param(token, dst_rel_addr, dst_param); 00626 } 00627 else 00628 { 00629 shader_parse_dst_param(token, NULL, dst_param); 00630 } 00631 } 00632 00633 static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic) 00634 { 00635 DWORD usage_token = *(*ptr)++; 00636 DWORD dst_token = *(*ptr)++; 00637 00638 semantic->usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; 00639 semantic->usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; 00640 semantic->sampler_type = (usage_token & WINED3DSP_TEXTURETYPE_MASK) >> WINED3DSP_TEXTURETYPE_SHIFT; 00641 shader_parse_dst_param(dst_token, NULL, &semantic->reg); 00642 } 00643 00644 static void shader_sm1_read_comment(const DWORD **ptr, const char **comment, UINT *comment_size) 00645 { 00646 DWORD token = **ptr; 00647 UINT size; 00648 00649 if ((token & WINED3DSI_OPCODE_MASK) != WINED3D_SM1_OP_COMMENT) 00650 { 00651 *comment = NULL; 00652 return; 00653 } 00654 00655 size = (token & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT; 00656 *comment = (const char *)++(*ptr); 00657 *comment_size = size * sizeof(DWORD); 00658 *ptr += size; 00659 } 00660 00661 static BOOL shader_sm1_is_end(void *data, const DWORD **ptr) 00662 { 00663 if (**ptr == WINED3DSP_END) 00664 { 00665 ++(*ptr); 00666 return TRUE; 00667 } 00668 00669 return FALSE; 00670 } 00671 00672 const struct wined3d_shader_frontend sm1_shader_frontend = 00673 { 00674 shader_sm1_init, 00675 shader_sm1_free, 00676 shader_sm1_read_header, 00677 shader_sm1_read_opcode, 00678 shader_sm1_read_src_param, 00679 shader_sm1_read_dst_param, 00680 shader_sm1_read_semantic, 00681 shader_sm1_read_comment, 00682 shader_sm1_is_end, 00683 }; Generated on Sat May 26 2012 04:20:50 for ReactOS by
1.7.6.1
|