Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygens_atifragshader.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2004 David Airlie All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00017 * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00018 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00019 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00020 */ 00021 00022 #include "main/glheader.h" 00023 #include "main/colormac.h" 00024 #include "main/context.h" 00025 #include "main/macros.h" 00026 #include "shader/program.h" 00027 #include "shader/atifragshader.h" 00028 #include "swrast/s_atifragshader.h" 00029 00030 00034 struct atifs_machine 00035 { 00036 GLfloat Registers[6][4]; 00037 GLfloat PrevPassRegisters[6][4]; 00038 GLfloat Inputs[2][4]; 00039 }; 00040 00041 00042 00046 static void 00047 fetch_texel(GLcontext * ctx, const GLfloat texcoord[4], GLfloat lambda, 00048 GLuint unit, GLfloat color[4]) 00049 { 00050 GLchan rgba[4]; 00051 SWcontext *swrast = SWRAST_CONTEXT(ctx); 00052 00053 /* XXX use a float-valued TextureSample routine here!!! */ 00054 swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, 00055 1, (const GLfloat(*)[4]) texcoord, 00056 &lambda, &rgba); 00057 color[0] = CHAN_TO_FLOAT(rgba[0]); 00058 color[1] = CHAN_TO_FLOAT(rgba[1]); 00059 color[2] = CHAN_TO_FLOAT(rgba[2]); 00060 color[3] = CHAN_TO_FLOAT(rgba[3]); 00061 } 00062 00063 static void 00064 apply_swizzle(GLfloat values[4], GLuint swizzle) 00065 { 00066 GLfloat s, t, r, q; 00067 00068 s = values[0]; 00069 t = values[1]; 00070 r = values[2]; 00071 q = values[3]; 00072 00073 switch (swizzle) { 00074 case GL_SWIZZLE_STR_ATI: 00075 values[0] = s; 00076 values[1] = t; 00077 values[2] = r; 00078 break; 00079 case GL_SWIZZLE_STQ_ATI: 00080 values[0] = s; 00081 values[1] = t; 00082 values[2] = q; 00083 break; 00084 case GL_SWIZZLE_STR_DR_ATI: 00085 values[0] = s / r; 00086 values[1] = t / r; 00087 values[2] = 1 / r; 00088 break; 00089 case GL_SWIZZLE_STQ_DQ_ATI: 00090 /* make sure q is not 0 to avoid problems later with infinite values (texture lookup)? */ 00091 if (q == 0.0F) q = 0.000000001; 00092 values[0] = s / q; 00093 values[1] = t / q; 00094 values[2] = 1 / q; 00095 break; 00096 } 00097 values[3] = 0.0; 00098 } 00099 00100 static void 00101 apply_src_rep(GLint optype, GLuint rep, GLfloat * val) 00102 { 00103 GLint i; 00104 GLint start, end; 00105 if (!rep) 00106 return; 00107 00108 start = optype ? 3 : 0; 00109 end = 4; 00110 00111 for (i = start; i < end; i++) { 00112 switch (rep) { 00113 case GL_RED: 00114 val[i] = val[0]; 00115 break; 00116 case GL_GREEN: 00117 val[i] = val[1]; 00118 break; 00119 case GL_BLUE: 00120 val[i] = val[2]; 00121 break; 00122 case GL_ALPHA: 00123 val[i] = val[3]; 00124 break; 00125 } 00126 } 00127 } 00128 00129 static void 00130 apply_src_mod(GLint optype, GLuint mod, GLfloat * val) 00131 { 00132 GLint i; 00133 GLint start, end; 00134 00135 if (!mod) 00136 return; 00137 00138 start = optype ? 3 : 0; 00139 end = 4; 00140 00141 for (i = start; i < end; i++) { 00142 if (mod & GL_COMP_BIT_ATI) 00143 val[i] = 1 - val[i]; 00144 00145 if (mod & GL_BIAS_BIT_ATI) 00146 val[i] = val[i] - 0.5; 00147 00148 if (mod & GL_2X_BIT_ATI) 00149 val[i] = 2 * val[i]; 00150 00151 if (mod & GL_NEGATE_BIT_ATI) 00152 val[i] = -val[i]; 00153 } 00154 } 00155 00156 static void 00157 apply_dst_mod(GLuint optype, GLuint mod, GLfloat * val) 00158 { 00159 GLint i; 00160 GLint has_sat = mod & GL_SATURATE_BIT_ATI; 00161 GLint start, end; 00162 00163 mod &= ~GL_SATURATE_BIT_ATI; 00164 00165 start = optype ? 3 : 0; 00166 end = optype ? 4 : 3; 00167 00168 for (i = start; i < end; i++) { 00169 switch (mod) { 00170 case GL_2X_BIT_ATI: 00171 val[i] = 2 * val[i]; 00172 break; 00173 case GL_4X_BIT_ATI: 00174 val[i] = 4 * val[i]; 00175 break; 00176 case GL_8X_BIT_ATI: 00177 val[i] = 8 * val[i]; 00178 break; 00179 case GL_HALF_BIT_ATI: 00180 val[i] = val[i] * 0.5; 00181 break; 00182 case GL_QUARTER_BIT_ATI: 00183 val[i] = val[i] * 0.25; 00184 break; 00185 case GL_EIGHTH_BIT_ATI: 00186 val[i] = val[i] * 0.125; 00187 break; 00188 } 00189 00190 if (has_sat) { 00191 if (val[i] < 0.0) 00192 val[i] = 0; 00193 else if (val[i] > 1.0) 00194 val[i] = 1.0; 00195 } 00196 else { 00197 if (val[i] < -8.0) 00198 val[i] = -8.0; 00199 else if (val[i] > 8.0) 00200 val[i] = 8.0; 00201 } 00202 } 00203 } 00204 00205 00206 static void 00207 write_dst_addr(GLuint optype, GLuint mod, GLuint mask, GLfloat * src, 00208 GLfloat * dst) 00209 { 00210 GLint i; 00211 apply_dst_mod(optype, mod, src); 00212 00213 if (optype == ATI_FRAGMENT_SHADER_COLOR_OP) { 00214 if (mask) { 00215 if (mask & GL_RED_BIT_ATI) 00216 dst[0] = src[0]; 00217 00218 if (mask & GL_GREEN_BIT_ATI) 00219 dst[1] = src[1]; 00220 00221 if (mask & GL_BLUE_BIT_ATI) 00222 dst[2] = src[2]; 00223 } 00224 else { 00225 for (i = 0; i < 3; i++) 00226 dst[i] = src[i]; 00227 } 00228 } 00229 else 00230 dst[3] = src[3]; 00231 } 00232 00233 static void 00234 finish_pass(struct atifs_machine *machine) 00235 { 00236 GLint i; 00237 00238 for (i = 0; i < 6; i++) { 00239 COPY_4V(machine->PrevPassRegisters[i], machine->Registers[i]); 00240 } 00241 } 00242 00243 struct ati_fs_opcode_st ati_fs_opcodes[] = { 00244 {GL_ADD_ATI, 2}, 00245 {GL_SUB_ATI, 2}, 00246 {GL_MUL_ATI, 2}, 00247 {GL_MAD_ATI, 3}, 00248 {GL_LERP_ATI, 3}, 00249 {GL_MOV_ATI, 1}, 00250 {GL_CND_ATI, 3}, 00251 {GL_CND0_ATI, 3}, 00252 {GL_DOT2_ADD_ATI, 3}, 00253 {GL_DOT3_ATI, 2}, 00254 {GL_DOT4_ATI, 2} 00255 }; 00256 00257 00258 00259 static void 00260 handle_pass_op(struct atifs_machine *machine, struct atifs_setupinst *texinst, 00261 const SWspan *span, GLuint column, GLuint idx) 00262 { 00263 GLuint swizzle = texinst->swizzle; 00264 GLuint pass_tex = texinst->src; 00265 00266 if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) { 00267 pass_tex -= GL_TEXTURE0_ARB; 00268 COPY_4V(machine->Registers[idx], 00269 span->array->attribs[FRAG_ATTRIB_TEX0 + pass_tex][column]); 00270 } 00271 else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI) { 00272 pass_tex -= GL_REG_0_ATI; 00273 COPY_4V(machine->Registers[idx], machine->PrevPassRegisters[pass_tex]); 00274 } 00275 apply_swizzle(machine->Registers[idx], swizzle); 00276 00277 } 00278 00279 static void 00280 handle_sample_op(GLcontext * ctx, struct atifs_machine *machine, 00281 struct atifs_setupinst *texinst, const SWspan *span, 00282 GLuint column, GLuint idx) 00283 { 00284 /* sample from unit idx using texinst->src as coords */ 00285 GLuint swizzle = texinst->swizzle; 00286 GLuint coord_source = texinst->src; 00287 GLfloat tex_coords[4]; 00288 00289 if (coord_source >= GL_TEXTURE0_ARB && coord_source <= GL_TEXTURE7_ARB) { 00290 coord_source -= GL_TEXTURE0_ARB; 00291 COPY_4V(tex_coords, 00292 span->array->attribs[FRAG_ATTRIB_TEX0 + coord_source][column]); 00293 } 00294 else if (coord_source >= GL_REG_0_ATI && coord_source <= GL_REG_5_ATI) { 00295 coord_source -= GL_REG_0_ATI; 00296 COPY_4V(tex_coords, machine->PrevPassRegisters[coord_source]); 00297 } 00298 apply_swizzle(tex_coords, swizzle); 00299 fetch_texel(ctx, tex_coords, 0.0F, idx, machine->Registers[idx]); 00300 } 00301 00302 #define SETUP_SRC_REG(optype, i, x) \ 00303 do { \ 00304 COPY_4V(src[optype][i], x); \ 00305 } while (0) 00306 00307 00308 00318 static void 00319 execute_shader(GLcontext *ctx, const struct ati_fragment_shader *shader, 00320 struct atifs_machine *machine, const SWspan *span, 00321 GLuint column) 00322 { 00323 GLuint pc; 00324 struct atifs_instruction *inst; 00325 struct atifs_setupinst *texinst; 00326 GLint optype; 00327 GLuint i; 00328 GLint j, pass; 00329 GLint dstreg; 00330 GLfloat src[2][3][4]; 00331 GLfloat zeros[4] = { 0.0, 0.0, 0.0, 0.0 }; 00332 GLfloat ones[4] = { 1.0, 1.0, 1.0, 1.0 }; 00333 GLfloat dst[2][4], *dstp; 00334 00335 for (pass = 0; pass < shader->NumPasses; pass++) { 00336 if (pass > 0) 00337 finish_pass(machine); 00338 for (j = 0; j < MAX_NUM_FRAGMENT_REGISTERS_ATI; j++) { 00339 texinst = &shader->SetupInst[pass][j]; 00340 if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP) 00341 handle_pass_op(machine, texinst, span, column, j); 00342 else if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP) 00343 handle_sample_op(ctx, machine, texinst, span, column, j); 00344 } 00345 00346 for (pc = 0; pc < shader->numArithInstr[pass]; pc++) { 00347 inst = &shader->Instructions[pass][pc]; 00348 00349 /* setup the source registers for color and alpha ops */ 00350 for (optype = 0; optype < 2; optype++) { 00351 for (i = 0; i < inst->ArgCount[optype]; i++) { 00352 GLint index = inst->SrcReg[optype][i].Index; 00353 00354 if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI) 00355 SETUP_SRC_REG(optype, i, 00356 machine->Registers[index - GL_REG_0_ATI]); 00357 else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) { 00358 if (shader->LocalConstDef & (1 << (index - GL_CON_0_ATI))) { 00359 SETUP_SRC_REG(optype, i, 00360 shader->Constants[index - GL_CON_0_ATI]); 00361 } else { 00362 SETUP_SRC_REG(optype, i, 00363 ctx->ATIFragmentShader.GlobalConstants[index - GL_CON_0_ATI]); 00364 } 00365 } 00366 else if (index == GL_ONE) 00367 SETUP_SRC_REG(optype, i, ones); 00368 else if (index == GL_ZERO) 00369 SETUP_SRC_REG(optype, i, zeros); 00370 else if (index == GL_PRIMARY_COLOR_EXT) 00371 SETUP_SRC_REG(optype, i, 00372 machine->Inputs[ATI_FS_INPUT_PRIMARY]); 00373 else if (index == GL_SECONDARY_INTERPOLATOR_ATI) 00374 SETUP_SRC_REG(optype, i, 00375 machine->Inputs[ATI_FS_INPUT_SECONDARY]); 00376 00377 apply_src_rep(optype, inst->SrcReg[optype][i].argRep, 00378 src[optype][i]); 00379 apply_src_mod(optype, inst->SrcReg[optype][i].argMod, 00380 src[optype][i]); 00381 } 00382 } 00383 00384 /* Execute the operations - color then alpha */ 00385 for (optype = 0; optype < 2; optype++) { 00386 if (inst->Opcode[optype]) { 00387 switch (inst->Opcode[optype]) { 00388 case GL_ADD_ATI: 00389 if (!optype) 00390 for (i = 0; i < 3; i++) { 00391 dst[optype][i] = 00392 src[optype][0][i] + src[optype][1][i]; 00393 } 00394 else 00395 dst[optype][3] = src[optype][0][3] + src[optype][1][3]; 00396 break; 00397 case GL_SUB_ATI: 00398 if (!optype) 00399 for (i = 0; i < 3; i++) { 00400 dst[optype][i] = 00401 src[optype][0][i] - src[optype][1][i]; 00402 } 00403 else 00404 dst[optype][3] = src[optype][0][3] - src[optype][1][3]; 00405 break; 00406 case GL_MUL_ATI: 00407 if (!optype) 00408 for (i = 0; i < 3; i++) { 00409 dst[optype][i] = 00410 src[optype][0][i] * src[optype][1][i]; 00411 } 00412 else 00413 dst[optype][3] = src[optype][0][3] * src[optype][1][3]; 00414 break; 00415 case GL_MAD_ATI: 00416 if (!optype) 00417 for (i = 0; i < 3; i++) { 00418 dst[optype][i] = 00419 src[optype][0][i] * src[optype][1][i] + 00420 src[optype][2][i]; 00421 } 00422 else 00423 dst[optype][3] = 00424 src[optype][0][3] * src[optype][1][3] + 00425 src[optype][2][3]; 00426 break; 00427 case GL_LERP_ATI: 00428 if (!optype) 00429 for (i = 0; i < 3; i++) { 00430 dst[optype][i] = 00431 src[optype][0][i] * src[optype][1][i] + (1 - 00432 src 00433 [optype] 00434 [0][i]) * 00435 src[optype][2][i]; 00436 } 00437 else 00438 dst[optype][3] = 00439 src[optype][0][3] * src[optype][1][3] + (1 - 00440 src[optype] 00441 [0][3]) * 00442 src[optype][2][3]; 00443 break; 00444 00445 case GL_MOV_ATI: 00446 if (!optype) 00447 for (i = 0; i < 3; i++) { 00448 dst[optype][i] = src[optype][0][i]; 00449 } 00450 else 00451 dst[optype][3] = src[optype][0][3]; 00452 break; 00453 case GL_CND_ATI: 00454 if (!optype) { 00455 for (i = 0; i < 3; i++) { 00456 dst[optype][i] = 00457 (src[optype][2][i] > 00458 0.5) ? src[optype][0][i] : src[optype][1][i]; 00459 } 00460 } 00461 else { 00462 dst[optype][3] = 00463 (src[optype][2][3] > 00464 0.5) ? src[optype][0][3] : src[optype][1][3]; 00465 } 00466 break; 00467 00468 case GL_CND0_ATI: 00469 if (!optype) 00470 for (i = 0; i < 3; i++) { 00471 dst[optype][i] = 00472 (src[optype][2][i] >= 00473 0) ? src[optype][0][i] : src[optype][1][i]; 00474 } 00475 else { 00476 dst[optype][3] = 00477 (src[optype][2][3] >= 00478 0) ? src[optype][0][3] : src[optype][1][3]; 00479 } 00480 break; 00481 case GL_DOT2_ADD_ATI: 00482 { 00483 GLfloat result; 00484 00485 /* DOT 2 always uses the source from the color op */ 00486 /* could save recalculation of dot products for alpha inst */ 00487 result = src[0][0][0] * src[0][1][0] + 00488 src[0][0][1] * src[0][1][1] + src[0][2][2]; 00489 if (!optype) { 00490 for (i = 0; i < 3; i++) { 00491 dst[optype][i] = result; 00492 } 00493 } 00494 else 00495 dst[optype][3] = result; 00496 } 00497 break; 00498 case GL_DOT3_ATI: 00499 { 00500 GLfloat result; 00501 00502 /* DOT 3 always uses the source from the color op */ 00503 result = src[0][0][0] * src[0][1][0] + 00504 src[0][0][1] * src[0][1][1] + 00505 src[0][0][2] * src[0][1][2]; 00506 00507 if (!optype) { 00508 for (i = 0; i < 3; i++) { 00509 dst[optype][i] = result; 00510 } 00511 } 00512 else 00513 dst[optype][3] = result; 00514 } 00515 break; 00516 case GL_DOT4_ATI: 00517 { 00518 GLfloat result; 00519 00520 /* DOT 4 always uses the source from the color op */ 00521 result = src[0][0][0] * src[0][1][0] + 00522 src[0][0][1] * src[0][1][1] + 00523 src[0][0][2] * src[0][1][2] + 00524 src[0][0][3] * src[0][1][3]; 00525 if (!optype) { 00526 for (i = 0; i < 3; i++) { 00527 dst[optype][i] = result; 00528 } 00529 } 00530 else 00531 dst[optype][3] = result; 00532 } 00533 break; 00534 00535 } 00536 } 00537 } 00538 00539 /* write out the destination registers */ 00540 for (optype = 0; optype < 2; optype++) { 00541 if (inst->Opcode[optype]) { 00542 dstreg = inst->DstReg[optype].Index; 00543 dstp = machine->Registers[dstreg - GL_REG_0_ATI]; 00544 00545 if ((optype == 0) || ((inst->Opcode[1] != GL_DOT2_ADD_ATI) && 00546 (inst->Opcode[1] != GL_DOT3_ATI) && (inst->Opcode[1] != GL_DOT4_ATI))) 00547 write_dst_addr(optype, inst->DstReg[optype].dstMod, 00548 inst->DstReg[optype].dstMask, dst[optype], 00549 dstp); 00550 else 00551 write_dst_addr(1, inst->DstReg[0].dstMod, 0, dst[1], dstp); 00552 } 00553 } 00554 } 00555 } 00556 } 00557 00558 00562 static void 00563 init_machine(GLcontext * ctx, struct atifs_machine *machine, 00564 const struct ati_fragment_shader *shader, 00565 const SWspan *span, GLuint col) 00566 { 00567 GLfloat (*inputs)[4] = machine->Inputs; 00568 GLint i, j; 00569 00570 for (i = 0; i < 6; i++) { 00571 for (j = 0; j < 4; j++) 00572 machine->Registers[i][j] = 0.0; 00573 } 00574 00575 COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->attribs[FRAG_ATTRIB_COL0][col]); 00576 COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->attribs[FRAG_ATTRIB_COL1][col]); 00577 } 00578 00579 00580 00584 void 00585 _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span) 00586 { 00587 const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current; 00588 struct atifs_machine machine; 00589 GLuint i; 00590 00591 /* incoming colors should be floats */ 00592 ASSERT(span->array->ChanType == GL_FLOAT); 00593 00594 ctx->_CurrentProgram = GL_FRAGMENT_SHADER_ATI; 00595 00596 for (i = 0; i < span->end; i++) { 00597 if (span->array->mask[i]) { 00598 init_machine(ctx, &machine, shader, span, i); 00599 00600 execute_shader(ctx, shader, &machine, span, i); 00601 00602 /* store result color */ 00603 { 00604 const GLfloat *colOut = machine.Registers[0]; 00605 /*fprintf(stderr,"outputs %f %f %f %f\n", 00606 colOut[0], colOut[1], colOut[2], colOut[3]); */ 00607 COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], colOut); 00608 } 00609 } 00610 } 00611 00612 ctx->_CurrentProgram = 0; 00613 } Generated on Sat May 26 2012 04:19:30 for ReactOS by
1.7.6.1
|