Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 1 | /* |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 2 | * Copyright (C) 2004 David Airlie All Rights Reserved. |
| 3 | * |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 5 | * copy of this software and associated documentation files (the "Software"), |
| 6 | * to deal in the Software without restriction, including without limitation |
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 8 | * and/or sell copies of the Software, and to permit persons to whom the |
| 9 | * Software is furnished to do so, subject to the following conditions: |
| 10 | * |
| 11 | * The above copyright notice and this permission notice shall be included |
| 12 | * in all copies or substantial portions of the Software. |
| 13 | * |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 17 | * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| 18 | * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 20 | */ |
| 21 | |
Brian Paul | bbd2871 | 2008-09-18 12:26:54 -0600 | [diff] [blame] | 22 | #include "main/glheader.h" |
| 23 | #include "main/colormac.h" |
| 24 | #include "main/context.h" |
| 25 | #include "main/macros.h" |
Brian | c223c6b | 2007-07-04 13:15:20 -0600 | [diff] [blame] | 26 | #include "shader/program.h" |
| 27 | #include "shader/atifragshader.h" |
| 28 | #include "swrast/s_atifragshader.h" |
Brian Paul | 55187ea | 2005-09-15 00:58:03 +0000 | [diff] [blame] | 29 | |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 30 | |
| 31 | /** |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 32 | * State for executing ATI fragment shader. |
| 33 | */ |
| 34 | struct atifs_machine |
| 35 | { |
| 36 | GLfloat Registers[6][4]; /** six temporary registers */ |
| 37 | GLfloat PrevPassRegisters[6][4]; |
| 38 | GLfloat Inputs[2][4]; /** Primary, secondary input colors */ |
| 39 | }; |
| 40 | |
| 41 | |
| 42 | |
| 43 | /** |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 44 | * Fetch a texel. |
| 45 | */ |
| 46 | static void |
| 47 | fetch_texel(GLcontext * ctx, const GLfloat texcoord[4], GLfloat lambda, |
| 48 | GLuint unit, GLfloat color[4]) |
| 49 | { |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 50 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
| 51 | |
| 52 | /* XXX use a float-valued TextureSample routine here!!! */ |
Brian Paul | aa8abf8 | 2005-09-16 04:16:48 +0000 | [diff] [blame] | 53 | swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, |
| 54 | 1, (const GLfloat(*)[4]) texcoord, |
Brian Paul | de2afd8 | 2009-03-08 13:49:57 -0600 | [diff] [blame] | 55 | &lambda, (GLfloat (*)[4]) color); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 56 | } |
| 57 | |
| 58 | static void |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 59 | apply_swizzle(GLfloat values[4], GLuint swizzle) |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 60 | { |
| 61 | GLfloat s, t, r, q; |
| 62 | |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 63 | s = values[0]; |
| 64 | t = values[1]; |
| 65 | r = values[2]; |
| 66 | q = values[3]; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 67 | |
| 68 | switch (swizzle) { |
| 69 | case GL_SWIZZLE_STR_ATI: |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 70 | values[0] = s; |
| 71 | values[1] = t; |
| 72 | values[2] = r; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 73 | break; |
| 74 | case GL_SWIZZLE_STQ_ATI: |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 75 | values[0] = s; |
| 76 | values[1] = t; |
| 77 | values[2] = q; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 78 | break; |
| 79 | case GL_SWIZZLE_STR_DR_ATI: |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 80 | values[0] = s / r; |
| 81 | values[1] = t / r; |
| 82 | values[2] = 1 / r; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 83 | break; |
| 84 | case GL_SWIZZLE_STQ_DQ_ATI: |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 85 | /* make sure q is not 0 to avoid problems later with infinite values (texture lookup)? */ |
| 86 | if (q == 0.0F) q = 0.000000001; |
| 87 | values[0] = s / q; |
| 88 | values[1] = t / q; |
| 89 | values[2] = 1 / q; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 90 | break; |
| 91 | } |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 92 | values[3] = 0.0; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | static void |
| 96 | apply_src_rep(GLint optype, GLuint rep, GLfloat * val) |
| 97 | { |
| 98 | GLint i; |
| 99 | GLint start, end; |
| 100 | if (!rep) |
| 101 | return; |
| 102 | |
| 103 | start = optype ? 3 : 0; |
Roland Scheidegger | b346213 | 2005-09-09 15:43:11 +0000 | [diff] [blame] | 104 | end = 4; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 105 | |
| 106 | for (i = start; i < end; i++) { |
| 107 | switch (rep) { |
| 108 | case GL_RED: |
| 109 | val[i] = val[0]; |
| 110 | break; |
| 111 | case GL_GREEN: |
| 112 | val[i] = val[1]; |
| 113 | break; |
| 114 | case GL_BLUE: |
| 115 | val[i] = val[2]; |
| 116 | break; |
| 117 | case GL_ALPHA: |
| 118 | val[i] = val[3]; |
| 119 | break; |
| 120 | } |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | static void |
| 125 | apply_src_mod(GLint optype, GLuint mod, GLfloat * val) |
| 126 | { |
| 127 | GLint i; |
| 128 | GLint start, end; |
| 129 | |
| 130 | if (!mod) |
| 131 | return; |
| 132 | |
| 133 | start = optype ? 3 : 0; |
Roland Scheidegger | b346213 | 2005-09-09 15:43:11 +0000 | [diff] [blame] | 134 | end = 4; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 135 | |
| 136 | for (i = start; i < end; i++) { |
| 137 | if (mod & GL_COMP_BIT_ATI) |
| 138 | val[i] = 1 - val[i]; |
| 139 | |
| 140 | if (mod & GL_BIAS_BIT_ATI) |
| 141 | val[i] = val[i] - 0.5; |
| 142 | |
| 143 | if (mod & GL_2X_BIT_ATI) |
| 144 | val[i] = 2 * val[i]; |
| 145 | |
| 146 | if (mod & GL_NEGATE_BIT_ATI) |
| 147 | val[i] = -val[i]; |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | static void |
| 152 | apply_dst_mod(GLuint optype, GLuint mod, GLfloat * val) |
| 153 | { |
| 154 | GLint i; |
| 155 | GLint has_sat = mod & GL_SATURATE_BIT_ATI; |
| 156 | GLint start, end; |
| 157 | |
| 158 | mod &= ~GL_SATURATE_BIT_ATI; |
| 159 | |
| 160 | start = optype ? 3 : 0; |
| 161 | end = optype ? 4 : 3; |
| 162 | |
| 163 | for (i = start; i < end; i++) { |
| 164 | switch (mod) { |
| 165 | case GL_2X_BIT_ATI: |
| 166 | val[i] = 2 * val[i]; |
| 167 | break; |
| 168 | case GL_4X_BIT_ATI: |
| 169 | val[i] = 4 * val[i]; |
| 170 | break; |
| 171 | case GL_8X_BIT_ATI: |
| 172 | val[i] = 8 * val[i]; |
| 173 | break; |
| 174 | case GL_HALF_BIT_ATI: |
| 175 | val[i] = val[i] * 0.5; |
| 176 | break; |
| 177 | case GL_QUARTER_BIT_ATI: |
| 178 | val[i] = val[i] * 0.25; |
| 179 | break; |
| 180 | case GL_EIGHTH_BIT_ATI: |
| 181 | val[i] = val[i] * 0.125; |
| 182 | break; |
| 183 | } |
| 184 | |
| 185 | if (has_sat) { |
| 186 | if (val[i] < 0.0) |
| 187 | val[i] = 0; |
| 188 | else if (val[i] > 1.0) |
| 189 | val[i] = 1.0; |
| 190 | } |
| 191 | else { |
| 192 | if (val[i] < -8.0) |
| 193 | val[i] = -8.0; |
| 194 | else if (val[i] > 8.0) |
| 195 | val[i] = 8.0; |
| 196 | } |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | |
| 201 | static void |
| 202 | write_dst_addr(GLuint optype, GLuint mod, GLuint mask, GLfloat * src, |
| 203 | GLfloat * dst) |
| 204 | { |
| 205 | GLint i; |
| 206 | apply_dst_mod(optype, mod, src); |
| 207 | |
| 208 | if (optype == ATI_FRAGMENT_SHADER_COLOR_OP) { |
| 209 | if (mask) { |
| 210 | if (mask & GL_RED_BIT_ATI) |
| 211 | dst[0] = src[0]; |
| 212 | |
| 213 | if (mask & GL_GREEN_BIT_ATI) |
| 214 | dst[1] = src[1]; |
| 215 | |
| 216 | if (mask & GL_BLUE_BIT_ATI) |
| 217 | dst[2] = src[2]; |
| 218 | } |
| 219 | else { |
| 220 | for (i = 0; i < 3; i++) |
| 221 | dst[i] = src[i]; |
| 222 | } |
| 223 | } |
| 224 | else |
| 225 | dst[3] = src[3]; |
| 226 | } |
| 227 | |
Brian Paul | 6c58dda | 2005-01-17 00:40:29 +0000 | [diff] [blame] | 228 | static void |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 229 | finish_pass(struct atifs_machine *machine) |
| 230 | { |
| 231 | GLint i; |
| 232 | |
| 233 | for (i = 0; i < 6; i++) { |
| 234 | COPY_4V(machine->PrevPassRegisters[i], machine->Registers[i]); |
| 235 | } |
| 236 | } |
| 237 | |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 238 | struct ati_fs_opcode_st ati_fs_opcodes[] = { |
| 239 | {GL_ADD_ATI, 2}, |
| 240 | {GL_SUB_ATI, 2}, |
| 241 | {GL_MUL_ATI, 2}, |
| 242 | {GL_MAD_ATI, 3}, |
| 243 | {GL_LERP_ATI, 3}, |
| 244 | {GL_MOV_ATI, 1}, |
| 245 | {GL_CND_ATI, 3}, |
| 246 | {GL_CND0_ATI, 3}, |
| 247 | {GL_DOT2_ADD_ATI, 3}, |
| 248 | {GL_DOT3_ATI, 2}, |
| 249 | {GL_DOT4_ATI, 2} |
| 250 | }; |
| 251 | |
| 252 | |
| 253 | |
| 254 | static void |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 255 | handle_pass_op(struct atifs_machine *machine, struct atifs_setupinst *texinst, |
Brian Paul | cdb27e8 | 2006-10-01 16:03:05 +0000 | [diff] [blame] | 256 | const SWspan *span, GLuint column, GLuint idx) |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 257 | { |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 258 | GLuint swizzle = texinst->swizzle; |
| 259 | GLuint pass_tex = texinst->src; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 260 | |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 261 | if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) { |
| 262 | pass_tex -= GL_TEXTURE0_ARB; |
| 263 | COPY_4V(machine->Registers[idx], |
Brian | f3e507e | 2007-02-01 09:51:48 -0700 | [diff] [blame] | 264 | span->array->attribs[FRAG_ATTRIB_TEX0 + pass_tex][column]); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 265 | } |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 266 | else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI) { |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 267 | pass_tex -= GL_REG_0_ATI; |
| 268 | COPY_4V(machine->Registers[idx], machine->PrevPassRegisters[pass_tex]); |
| 269 | } |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 270 | apply_swizzle(machine->Registers[idx], swizzle); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 271 | |
| 272 | } |
| 273 | |
| 274 | static void |
| 275 | handle_sample_op(GLcontext * ctx, struct atifs_machine *machine, |
Brian Paul | cdb27e8 | 2006-10-01 16:03:05 +0000 | [diff] [blame] | 276 | struct atifs_setupinst *texinst, const SWspan *span, |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 277 | GLuint column, GLuint idx) |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 278 | { |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 279 | /* sample from unit idx using texinst->src as coords */ |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 280 | GLuint swizzle = texinst->swizzle; |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 281 | GLuint coord_source = texinst->src; |
Vinson Lee | 1e444c9 | 2009-12-12 15:08:01 -0800 | [diff] [blame] | 282 | GLfloat tex_coords[4] = { 0 }; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 283 | |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 284 | if (coord_source >= GL_TEXTURE0_ARB && coord_source <= GL_TEXTURE7_ARB) { |
| 285 | coord_source -= GL_TEXTURE0_ARB; |
Brian | f3e507e | 2007-02-01 09:51:48 -0700 | [diff] [blame] | 286 | COPY_4V(tex_coords, |
| 287 | span->array->attribs[FRAG_ATTRIB_TEX0 + coord_source][column]); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 288 | } |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 289 | else if (coord_source >= GL_REG_0_ATI && coord_source <= GL_REG_5_ATI) { |
| 290 | coord_source -= GL_REG_0_ATI; |
| 291 | COPY_4V(tex_coords, machine->PrevPassRegisters[coord_source]); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 292 | } |
Roland Scheidegger | 3c450b2 | 2005-09-02 12:05:38 +0000 | [diff] [blame] | 293 | apply_swizzle(tex_coords, swizzle); |
| 294 | fetch_texel(ctx, tex_coords, 0.0F, idx, machine->Registers[idx]); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 295 | } |
| 296 | |
Roland Scheidegger | b683b0d | 2005-09-07 21:59:30 +0000 | [diff] [blame] | 297 | #define SETUP_SRC_REG(optype, i, x) \ |
| 298 | do { \ |
| 299 | COPY_4V(src[optype][i], x); \ |
| 300 | } while (0) |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 301 | |
Brian Paul | 919cd2c | 2006-10-21 23:21:35 +0000 | [diff] [blame] | 302 | |
| 303 | |
| 304 | /** |
| 305 | * Execute the given fragment shader. |
| 306 | * NOTE: we do everything in single-precision floating point |
| 307 | * \param ctx - rendering context |
| 308 | * \param shader - the shader to execute |
| 309 | * \param machine - virtual machine state |
| 310 | * \param span - the SWspan we're operating on |
| 311 | * \param column - which pixel [i] we're operating on in the span |
| 312 | */ |
| 313 | static void |
| 314 | execute_shader(GLcontext *ctx, const struct ati_fragment_shader *shader, |
Brian Paul | cdb27e8 | 2006-10-01 16:03:05 +0000 | [diff] [blame] | 315 | struct atifs_machine *machine, const SWspan *span, |
Brian Paul | 919cd2c | 2006-10-21 23:21:35 +0000 | [diff] [blame] | 316 | GLuint column) |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 317 | { |
| 318 | GLuint pc; |
| 319 | struct atifs_instruction *inst; |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 320 | struct atifs_setupinst *texinst; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 321 | GLint optype; |
Brian | 7e85b0a | 2007-01-23 12:50:08 -0700 | [diff] [blame] | 322 | GLuint i; |
| 323 | GLint j, pass; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 324 | GLint dstreg; |
| 325 | GLfloat src[2][3][4]; |
| 326 | GLfloat zeros[4] = { 0.0, 0.0, 0.0, 0.0 }; |
| 327 | GLfloat ones[4] = { 1.0, 1.0, 1.0, 1.0 }; |
| 328 | GLfloat dst[2][4], *dstp; |
| 329 | |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 330 | for (pass = 0; pass < shader->NumPasses; pass++) { |
| 331 | if (pass > 0) |
| 332 | finish_pass(machine); |
| 333 | for (j = 0; j < MAX_NUM_FRAGMENT_REGISTERS_ATI; j++) { |
| 334 | texinst = &shader->SetupInst[pass][j]; |
| 335 | if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP) |
| 336 | handle_pass_op(machine, texinst, span, column, j); |
| 337 | else if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP) |
| 338 | handle_sample_op(ctx, machine, texinst, span, column, j); |
| 339 | } |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 340 | |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 341 | for (pc = 0; pc < shader->numArithInstr[pass]; pc++) { |
| 342 | inst = &shader->Instructions[pass][pc]; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 343 | |
| 344 | /* setup the source registers for color and alpha ops */ |
| 345 | for (optype = 0; optype < 2; optype++) { |
Brian | 7e85b0a | 2007-01-23 12:50:08 -0700 | [diff] [blame] | 346 | for (i = 0; i < inst->ArgCount[optype]; i++) { |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 347 | GLint index = inst->SrcReg[optype][i].Index; |
| 348 | |
| 349 | if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI) |
| 350 | SETUP_SRC_REG(optype, i, |
| 351 | machine->Registers[index - GL_REG_0_ATI]); |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 352 | else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) { |
Brian Paul | 63d6830 | 2005-11-19 16:43:04 +0000 | [diff] [blame] | 353 | if (shader->LocalConstDef & (1 << (index - GL_CON_0_ATI))) { |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 354 | SETUP_SRC_REG(optype, i, |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 355 | shader->Constants[index - GL_CON_0_ATI]); |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 356 | } else { |
| 357 | SETUP_SRC_REG(optype, i, |
Brian Paul | 63d6830 | 2005-11-19 16:43:04 +0000 | [diff] [blame] | 358 | ctx->ATIFragmentShader.GlobalConstants[index - GL_CON_0_ATI]); |
Roland Scheidegger | f519a77 | 2005-09-02 01:11:53 +0000 | [diff] [blame] | 359 | } |
| 360 | } |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 361 | else if (index == GL_ONE) |
| 362 | SETUP_SRC_REG(optype, i, ones); |
| 363 | else if (index == GL_ZERO) |
| 364 | SETUP_SRC_REG(optype, i, zeros); |
| 365 | else if (index == GL_PRIMARY_COLOR_EXT) |
| 366 | SETUP_SRC_REG(optype, i, |
| 367 | machine->Inputs[ATI_FS_INPUT_PRIMARY]); |
| 368 | else if (index == GL_SECONDARY_INTERPOLATOR_ATI) |
| 369 | SETUP_SRC_REG(optype, i, |
| 370 | machine->Inputs[ATI_FS_INPUT_SECONDARY]); |
| 371 | |
| 372 | apply_src_rep(optype, inst->SrcReg[optype][i].argRep, |
| 373 | src[optype][i]); |
| 374 | apply_src_mod(optype, inst->SrcReg[optype][i].argMod, |
| 375 | src[optype][i]); |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | /* Execute the operations - color then alpha */ |
| 380 | for (optype = 0; optype < 2; optype++) { |
| 381 | if (inst->Opcode[optype]) { |
| 382 | switch (inst->Opcode[optype]) { |
| 383 | case GL_ADD_ATI: |
| 384 | if (!optype) |
| 385 | for (i = 0; i < 3; i++) { |
| 386 | dst[optype][i] = |
| 387 | src[optype][0][i] + src[optype][1][i]; |
| 388 | } |
| 389 | else |
| 390 | dst[optype][3] = src[optype][0][3] + src[optype][1][3]; |
| 391 | break; |
| 392 | case GL_SUB_ATI: |
| 393 | if (!optype) |
| 394 | for (i = 0; i < 3; i++) { |
| 395 | dst[optype][i] = |
| 396 | src[optype][0][i] - src[optype][1][i]; |
| 397 | } |
| 398 | else |
| 399 | dst[optype][3] = src[optype][0][3] - src[optype][1][3]; |
| 400 | break; |
| 401 | case GL_MUL_ATI: |
| 402 | if (!optype) |
| 403 | for (i = 0; i < 3; i++) { |
| 404 | dst[optype][i] = |
| 405 | src[optype][0][i] * src[optype][1][i]; |
| 406 | } |
| 407 | else |
| 408 | dst[optype][3] = src[optype][0][3] * src[optype][1][3]; |
| 409 | break; |
| 410 | case GL_MAD_ATI: |
| 411 | if (!optype) |
| 412 | for (i = 0; i < 3; i++) { |
| 413 | dst[optype][i] = |
| 414 | src[optype][0][i] * src[optype][1][i] + |
| 415 | src[optype][2][i]; |
| 416 | } |
| 417 | else |
| 418 | dst[optype][3] = |
| 419 | src[optype][0][3] * src[optype][1][3] + |
| 420 | src[optype][2][3]; |
| 421 | break; |
| 422 | case GL_LERP_ATI: |
| 423 | if (!optype) |
| 424 | for (i = 0; i < 3; i++) { |
| 425 | dst[optype][i] = |
| 426 | src[optype][0][i] * src[optype][1][i] + (1 - |
| 427 | src |
| 428 | [optype] |
| 429 | [0][i]) * |
| 430 | src[optype][2][i]; |
| 431 | } |
| 432 | else |
| 433 | dst[optype][3] = |
| 434 | src[optype][0][3] * src[optype][1][3] + (1 - |
| 435 | src[optype] |
| 436 | [0][3]) * |
| 437 | src[optype][2][3]; |
| 438 | break; |
| 439 | |
| 440 | case GL_MOV_ATI: |
| 441 | if (!optype) |
| 442 | for (i = 0; i < 3; i++) { |
| 443 | dst[optype][i] = src[optype][0][i]; |
| 444 | } |
| 445 | else |
| 446 | dst[optype][3] = src[optype][0][3]; |
| 447 | break; |
| 448 | case GL_CND_ATI: |
| 449 | if (!optype) { |
| 450 | for (i = 0; i < 3; i++) { |
| 451 | dst[optype][i] = |
| 452 | (src[optype][2][i] > |
| 453 | 0.5) ? src[optype][0][i] : src[optype][1][i]; |
| 454 | } |
| 455 | } |
| 456 | else { |
| 457 | dst[optype][3] = |
| 458 | (src[optype][2][3] > |
| 459 | 0.5) ? src[optype][0][3] : src[optype][1][3]; |
| 460 | } |
| 461 | break; |
| 462 | |
| 463 | case GL_CND0_ATI: |
| 464 | if (!optype) |
| 465 | for (i = 0; i < 3; i++) { |
| 466 | dst[optype][i] = |
| 467 | (src[optype][2][i] >= |
| 468 | 0) ? src[optype][0][i] : src[optype][1][i]; |
| 469 | } |
| 470 | else { |
| 471 | dst[optype][3] = |
| 472 | (src[optype][2][3] >= |
| 473 | 0) ? src[optype][0][3] : src[optype][1][3]; |
| 474 | } |
| 475 | break; |
| 476 | case GL_DOT2_ADD_ATI: |
| 477 | { |
| 478 | GLfloat result; |
| 479 | |
| 480 | /* DOT 2 always uses the source from the color op */ |
Roland Scheidegger | b346213 | 2005-09-09 15:43:11 +0000 | [diff] [blame] | 481 | /* could save recalculation of dot products for alpha inst */ |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 482 | result = src[0][0][0] * src[0][1][0] + |
| 483 | src[0][0][1] * src[0][1][1] + src[0][2][2]; |
| 484 | if (!optype) { |
| 485 | for (i = 0; i < 3; i++) { |
| 486 | dst[optype][i] = result; |
| 487 | } |
| 488 | } |
| 489 | else |
| 490 | dst[optype][3] = result; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 491 | } |
| 492 | break; |
| 493 | case GL_DOT3_ATI: |
| 494 | { |
| 495 | GLfloat result; |
| 496 | |
| 497 | /* DOT 3 always uses the source from the color op */ |
| 498 | result = src[0][0][0] * src[0][1][0] + |
| 499 | src[0][0][1] * src[0][1][1] + |
| 500 | src[0][0][2] * src[0][1][2]; |
| 501 | |
| 502 | if (!optype) { |
| 503 | for (i = 0; i < 3; i++) { |
| 504 | dst[optype][i] = result; |
| 505 | } |
| 506 | } |
| 507 | else |
| 508 | dst[optype][3] = result; |
| 509 | } |
| 510 | break; |
| 511 | case GL_DOT4_ATI: |
| 512 | { |
| 513 | GLfloat result; |
| 514 | |
| 515 | /* DOT 4 always uses the source from the color op */ |
Roland Scheidegger | b346213 | 2005-09-09 15:43:11 +0000 | [diff] [blame] | 516 | result = src[0][0][0] * src[0][1][0] + |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 517 | src[0][0][1] * src[0][1][1] + |
| 518 | src[0][0][2] * src[0][1][2] + |
| 519 | src[0][0][3] * src[0][1][3]; |
| 520 | if (!optype) { |
| 521 | for (i = 0; i < 3; i++) { |
| 522 | dst[optype][i] = result; |
| 523 | } |
| 524 | } |
| 525 | else |
| 526 | dst[optype][3] = result; |
| 527 | } |
| 528 | break; |
| 529 | |
| 530 | } |
| 531 | } |
| 532 | } |
| 533 | |
| 534 | /* write out the destination registers */ |
| 535 | for (optype = 0; optype < 2; optype++) { |
| 536 | if (inst->Opcode[optype]) { |
| 537 | dstreg = inst->DstReg[optype].Index; |
| 538 | dstp = machine->Registers[dstreg - GL_REG_0_ATI]; |
| 539 | |
Roland Scheidegger | b346213 | 2005-09-09 15:43:11 +0000 | [diff] [blame] | 540 | if ((optype == 0) || ((inst->Opcode[1] != GL_DOT2_ADD_ATI) && |
| 541 | (inst->Opcode[1] != GL_DOT3_ATI) && (inst->Opcode[1] != GL_DOT4_ATI))) |
| 542 | write_dst_addr(optype, inst->DstReg[optype].dstMod, |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 543 | inst->DstReg[optype].dstMask, dst[optype], |
| 544 | dstp); |
Roland Scheidegger | b346213 | 2005-09-09 15:43:11 +0000 | [diff] [blame] | 545 | else |
| 546 | write_dst_addr(1, inst->DstReg[0].dstMod, 0, dst[1], dstp); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 547 | } |
| 548 | } |
| 549 | } |
| 550 | } |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 551 | } |
| 552 | |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 553 | |
| 554 | /** |
| 555 | * Init fragment shader virtual machine state. |
| 556 | */ |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 557 | static void |
| 558 | init_machine(GLcontext * ctx, struct atifs_machine *machine, |
| 559 | const struct ati_fragment_shader *shader, |
Brian Paul | cdb27e8 | 2006-10-01 16:03:05 +0000 | [diff] [blame] | 560 | const SWspan *span, GLuint col) |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 561 | { |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 562 | GLfloat (*inputs)[4] = machine->Inputs; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 563 | GLint i, j; |
| 564 | |
| 565 | for (i = 0; i < 6; i++) { |
| 566 | for (j = 0; j < 4; j++) |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 567 | machine->Registers[i][j] = 0.0; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 568 | } |
| 569 | |
Brian | f3e507e | 2007-02-01 09:51:48 -0700 | [diff] [blame] | 570 | COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->attribs[FRAG_ATTRIB_COL0][col]); |
| 571 | COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->attribs[FRAG_ATTRIB_COL1][col]); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 572 | } |
| 573 | |
| 574 | |
| 575 | |
| 576 | /** |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 577 | * Execute the current ATI shader program, operating on the given span. |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 578 | */ |
| 579 | void |
Brian Paul | cdb27e8 | 2006-10-01 16:03:05 +0000 | [diff] [blame] | 580 | _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span) |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 581 | { |
| 582 | const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current; |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 583 | struct atifs_machine machine; |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 584 | GLuint i; |
| 585 | |
Brian Paul | c3caaa3 | 2006-10-17 22:23:32 +0000 | [diff] [blame] | 586 | /* incoming colors should be floats */ |
| 587 | ASSERT(span->array->ChanType == GL_FLOAT); |
| 588 | |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 589 | for (i = 0; i < span->end; i++) { |
| 590 | if (span->array->mask[i]) { |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 591 | init_machine(ctx, &machine, shader, span, i); |
Brian Paul | 919cd2c | 2006-10-21 23:21:35 +0000 | [diff] [blame] | 592 | |
| 593 | execute_shader(ctx, shader, &machine, span, i); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 594 | |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 595 | /* store result color */ |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 596 | { |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 597 | const GLfloat *colOut = machine.Registers[0]; |
Brian Paul | c3caaa3 | 2006-10-17 22:23:32 +0000 | [diff] [blame] | 598 | /*fprintf(stderr,"outputs %f %f %f %f\n", |
Brian Paul | c207464 | 2006-10-17 21:12:32 +0000 | [diff] [blame] | 599 | colOut[0], colOut[1], colOut[2], colOut[3]); */ |
Brian | f3e507e | 2007-02-01 09:51:48 -0700 | [diff] [blame] | 600 | COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], colOut); |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 601 | } |
| 602 | } |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 603 | } |
Dave Airlie | 7f752fe | 2004-12-19 03:06:59 +0000 | [diff] [blame] | 604 | } |