Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenatifragshader.c
Go to the documentation of this file.
00001 00024 #include "main/glheader.h" 00025 #include "main/context.h" 00026 #include "main/hash.h" 00027 #include "main/imports.h" 00028 #include "main/macros.h" 00029 #include "main/enums.h" 00030 #include "main/mtypes.h" 00031 #include "atifragshader.h" 00032 00033 #define MESA_DEBUG_ATI_FS 0 00034 00035 static struct ati_fragment_shader DummyShader; 00036 00037 00041 struct ati_fragment_shader * 00042 _mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id) 00043 { 00044 struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader); 00045 (void) ctx; 00046 if (s) { 00047 s->Id = id; 00048 s->RefCount = 1; 00049 } 00050 return s; 00051 } 00052 00053 00057 void 00058 _mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s) 00059 { 00060 GLuint i; 00061 for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { 00062 if (s->Instructions[i]) 00063 _mesa_free(s->Instructions[i]); 00064 if (s->SetupInst[i]) 00065 _mesa_free(s->SetupInst[i]); 00066 } 00067 _mesa_free(s); 00068 } 00069 00070 00071 00072 static void 00073 new_arith_inst(struct ati_fragment_shader *prog) 00074 { 00075 /* set "default" instruction as not all may get defined. 00076 there is no specified way to express a nop with ati fragment shaders we use 00077 GL_NONE as the op enum and just set some params to 0 - so nothing to do here */ 00078 prog->numArithInstr[prog->cur_pass >> 1]++; 00079 } 00080 00081 static void 00082 new_tex_inst(struct ati_fragment_shader *prog) 00083 { 00084 } 00085 00086 static void match_pair_inst(struct ati_fragment_shader *curProg, GLuint optype) 00087 { 00088 if (optype == curProg->last_optype) { 00089 curProg->last_optype = 1; 00090 } 00091 } 00092 00093 #if MESA_DEBUG_ATI_FS 00094 static char * 00095 create_dst_mod_str(GLuint mod) 00096 { 00097 static char ret_str[1024]; 00098 00099 _mesa_memset(ret_str, 0, 1024); 00100 if (mod & GL_2X_BIT_ATI) 00101 _mesa_strncat(ret_str, "|2X", 1024); 00102 00103 if (mod & GL_4X_BIT_ATI) 00104 _mesa_strncat(ret_str, "|4X", 1024); 00105 00106 if (mod & GL_8X_BIT_ATI) 00107 _mesa_strncat(ret_str, "|8X", 1024); 00108 if (mod & GL_HALF_BIT_ATI) 00109 _mesa_strncat(ret_str, "|HA", 1024); 00110 if (mod & GL_QUARTER_BIT_ATI) 00111 _mesa_strncat(ret_str, "|QU", 1024); 00112 if (mod & GL_EIGHTH_BIT_ATI) 00113 _mesa_strncat(ret_str, "|EI", 1024); 00114 00115 if (mod & GL_SATURATE_BIT_ATI) 00116 _mesa_strncat(ret_str, "|SAT", 1024); 00117 00118 if (_mesa_strlen(ret_str) == 0) 00119 _mesa_strncat(ret_str, "NONE", 1024); 00120 return ret_str; 00121 } 00122 00123 static char *atifs_ops[] = {"ColorFragmentOp1ATI", "ColorFragmentOp2ATI", "ColorFragmentOp3ATI", 00124 "AlphaFragmentOp1ATI", "AlphaFragmentOp2ATI", "AlphaFragmentOp3ATI" }; 00125 00126 static void debug_op(GLint optype, GLuint arg_count, GLenum op, GLuint dst, 00127 GLuint dstMask, GLuint dstMod, GLuint arg1, 00128 GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, 00129 GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, 00130 GLuint arg3Rep, GLuint arg3Mod) 00131 { 00132 char *op_name; 00133 00134 op_name = atifs_ops[(arg_count-1)+(optype?3:0)]; 00135 00136 fprintf(stderr, "%s(%s, %s", op_name, _mesa_lookup_enum_by_nr(op), 00137 _mesa_lookup_enum_by_nr(dst)); 00138 if (!optype) 00139 fprintf(stderr, ", %d", dstMask); 00140 00141 fprintf(stderr, ", %s", create_dst_mod_str(dstMod)); 00142 00143 fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg1), 00144 _mesa_lookup_enum_by_nr(arg1Rep), arg1Mod); 00145 if (arg_count>1) 00146 fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg2), 00147 _mesa_lookup_enum_by_nr(arg2Rep), arg2Mod); 00148 if (arg_count>2) 00149 fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg3), 00150 _mesa_lookup_enum_by_nr(arg3Rep), arg3Mod); 00151 00152 fprintf(stderr,")\n"); 00153 00154 } 00155 #endif 00156 00157 static int check_arith_arg(struct ati_fragment_shader *curProg, 00158 GLuint optype, GLuint arg, GLuint argRep) 00159 { 00160 GET_CURRENT_CONTEXT(ctx); 00161 00162 if (((arg < GL_CON_0_ATI) || (arg > GL_CON_7_ATI)) && 00163 ((arg < GL_REG_0_ATI) || (arg > GL_REG_5_ATI)) && 00164 (arg != GL_ZERO) && (arg != GL_ONE) && 00165 (arg != GL_PRIMARY_COLOR_ARB) && (arg != GL_SECONDARY_INTERPOLATOR_ATI)) { 00166 _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(arg)"); 00167 return 0; 00168 } 00169 if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) || 00170 ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) { 00171 _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)"); 00172 return 0; 00173 } 00174 if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) || 00175 ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) { 00176 _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)"); 00177 return 0; 00178 } 00179 if ((curProg->cur_pass == 1) && 00180 ((arg == GL_PRIMARY_COLOR_ARB) || (arg == GL_SECONDARY_INTERPOLATOR_ATI))) { 00181 curProg->interpinp1 = GL_TRUE; 00182 } 00183 return 1; 00184 } 00185 00186 GLuint GLAPIENTRY 00187 _mesa_GenFragmentShadersATI(GLuint range) 00188 { 00189 GLuint first; 00190 GLuint i; 00191 GET_CURRENT_CONTEXT(ctx); 00192 00193 if (range == 0) { 00194 _mesa_error(ctx, GL_INVALID_VALUE, "glGenFragmentShadersATI(range)"); 00195 return 0; 00196 } 00197 00198 if (ctx->ATIFragmentShader.Compiling) { 00199 _mesa_error(ctx, GL_INVALID_OPERATION, "glGenFragmentShadersATI(insideShader)"); 00200 return 0; 00201 } 00202 00203 first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range); 00204 for (i = 0; i < range; i++) { 00205 _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader); 00206 } 00207 00208 return first; 00209 } 00210 00211 void GLAPIENTRY 00212 _mesa_BindFragmentShaderATI(GLuint id) 00213 { 00214 GET_CURRENT_CONTEXT(ctx); 00215 struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; 00216 struct ati_fragment_shader *newProg; 00217 00218 if (ctx->ATIFragmentShader.Compiling) { 00219 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragmentShaderATI(insideShader)"); 00220 return; 00221 } 00222 00223 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00224 00225 if (curProg->Id == id) { 00226 return; 00227 } 00228 00229 /* unbind current */ 00230 if (curProg->Id != 0) { 00231 curProg->RefCount--; 00232 if (curProg->RefCount <= 0) { 00233 _mesa_HashRemove(ctx->Shared->ATIShaders, id); 00234 } 00235 } 00236 00237 /* find new shader */ 00238 if (id == 0) { 00239 newProg = ctx->Shared->DefaultFragmentShader; 00240 } 00241 else { 00242 newProg = (struct ati_fragment_shader *) 00243 _mesa_HashLookup(ctx->Shared->ATIShaders, id); 00244 if (!newProg || newProg == &DummyShader) { 00245 /* allocate a new program now */ 00246 newProg = _mesa_new_ati_fragment_shader(ctx, id); 00247 if (!newProg) { 00248 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI"); 00249 return; 00250 } 00251 _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg); 00252 } 00253 00254 } 00255 00256 /* do actual bind */ 00257 ctx->ATIFragmentShader.Current = newProg; 00258 00259 ASSERT(ctx->ATIFragmentShader.Current); 00260 if (newProg) 00261 newProg->RefCount++; 00262 00263 /*if (ctx->Driver.BindProgram) 00264 ctx->Driver.BindProgram(ctx, target, prog); */ 00265 } 00266 00267 void GLAPIENTRY 00268 _mesa_DeleteFragmentShaderATI(GLuint id) 00269 { 00270 GET_CURRENT_CONTEXT(ctx); 00271 00272 if (ctx->ATIFragmentShader.Compiling) { 00273 _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteFragmentShaderATI(insideShader)"); 00274 return; 00275 } 00276 00277 if (id != 0) { 00278 struct ati_fragment_shader *prog = (struct ati_fragment_shader *) 00279 _mesa_HashLookup(ctx->Shared->ATIShaders, id); 00280 if (prog == &DummyShader) { 00281 _mesa_HashRemove(ctx->Shared->ATIShaders, id); 00282 } 00283 else if (prog) { 00284 if (ctx->ATIFragmentShader.Current && 00285 ctx->ATIFragmentShader.Current->Id == id) { 00286 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00287 _mesa_BindFragmentShaderATI(0); 00288 } 00289 } 00290 00291 /* The ID is immediately available for re-use now */ 00292 _mesa_HashRemove(ctx->Shared->ATIShaders, id); 00293 prog->RefCount--; 00294 if (prog->RefCount <= 0) { 00295 _mesa_free(prog); 00296 } 00297 } 00298 } 00299 00300 00301 void GLAPIENTRY 00302 _mesa_BeginFragmentShaderATI(void) 00303 { 00304 GLint i; 00305 GET_CURRENT_CONTEXT(ctx); 00306 00307 if (ctx->ATIFragmentShader.Compiling) { 00308 _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginFragmentShaderATI(insideShader)"); 00309 return; 00310 } 00311 00312 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00313 00314 /* if the shader was already defined free instructions and get new ones 00315 (or, could use the same mem but would need to reinitialize) */ 00316 /* no idea if it's allowed to redefine a shader */ 00317 for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { 00318 if (ctx->ATIFragmentShader.Current->Instructions[i]) 00319 _mesa_free(ctx->ATIFragmentShader.Current->Instructions[i]); 00320 if (ctx->ATIFragmentShader.Current->SetupInst[i]) 00321 _mesa_free(ctx->ATIFragmentShader.Current->SetupInst[i]); 00322 } 00323 00324 /* malloc the instructions here - not sure if the best place but its 00325 a start */ 00326 for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { 00327 ctx->ATIFragmentShader.Current->Instructions[i] = 00328 (struct atifs_instruction *) 00329 _mesa_calloc(sizeof(struct atifs_instruction) * 00330 (MAX_NUM_INSTRUCTIONS_PER_PASS_ATI)); 00331 ctx->ATIFragmentShader.Current->SetupInst[i] = 00332 (struct atifs_setupinst *) 00333 _mesa_calloc(sizeof(struct atifs_setupinst) * 00334 (MAX_NUM_FRAGMENT_REGISTERS_ATI)); 00335 } 00336 00337 /* can't rely on calloc for initialization as it's possible to redefine a shader (?) */ 00338 ctx->ATIFragmentShader.Current->LocalConstDef = 0; 00339 ctx->ATIFragmentShader.Current->numArithInstr[0] = 0; 00340 ctx->ATIFragmentShader.Current->numArithInstr[1] = 0; 00341 ctx->ATIFragmentShader.Current->regsAssigned[0] = 0; 00342 ctx->ATIFragmentShader.Current->regsAssigned[1] = 0; 00343 ctx->ATIFragmentShader.Current->NumPasses = 0; 00344 ctx->ATIFragmentShader.Current->cur_pass = 0; 00345 ctx->ATIFragmentShader.Current->last_optype = 0; 00346 ctx->ATIFragmentShader.Current->interpinp1 = GL_FALSE; 00347 ctx->ATIFragmentShader.Current->isValid = GL_FALSE; 00348 ctx->ATIFragmentShader.Current->swizzlerq = 0; 00349 ctx->ATIFragmentShader.Compiling = 1; 00350 } 00351 00352 void GLAPIENTRY 00353 _mesa_EndFragmentShaderATI(void) 00354 { 00355 GET_CURRENT_CONTEXT(ctx); 00356 struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; 00357 #if MESA_DEBUG_ATI_FS 00358 GLint i, j; 00359 #endif 00360 00361 if (!ctx->ATIFragmentShader.Compiling) { 00362 _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(outsideShader)"); 00363 return; 00364 } 00365 if (curProg->interpinp1 && (ctx->ATIFragmentShader.Current->cur_pass > 1)) { 00366 _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(interpinfirstpass)"); 00367 /* according to spec, DON'T return here */ 00368 } 00369 00370 match_pair_inst(curProg, 0); 00371 ctx->ATIFragmentShader.Compiling = 0; 00372 ctx->ATIFragmentShader.Current->isValid = GL_TRUE; 00373 if ((ctx->ATIFragmentShader.Current->cur_pass == 0) || 00374 (ctx->ATIFragmentShader.Current->cur_pass == 2)) { 00375 _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(noarithinst)"); 00376 } 00377 if (ctx->ATIFragmentShader.Current->cur_pass > 1) 00378 ctx->ATIFragmentShader.Current->NumPasses = 2; 00379 else ctx->ATIFragmentShader.Current->NumPasses = 1; 00380 ctx->ATIFragmentShader.Current->cur_pass=0; 00381 #if MESA_DEBUG_ATI_FS 00382 for (j = 0; j < MAX_NUM_PASSES_ATI; j++) { 00383 for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) { 00384 GLuint op = curProg->SetupInst[j][i].Opcode; 00385 const char *op_enum = op > 5 ? _mesa_lookup_enum_by_nr(op) : "0"; 00386 GLuint src = curProg->SetupInst[j][i].src; 00387 GLuint swizzle = curProg->SetupInst[j][i].swizzle; 00388 fprintf(stderr, "%2d %04X %s %d %04X\n", i, op, op_enum, src, 00389 swizzle); 00390 } 00391 for (i = 0; i < curProg->numArithInstr[j]; i++) { 00392 GLuint op0 = curProg->Instructions[j][i].Opcode[0]; 00393 GLuint op1 = curProg->Instructions[j][i].Opcode[1]; 00394 const char *op0_enum = op0 > 5 ? _mesa_lookup_enum_by_nr(op0) : "0"; 00395 const char *op1_enum = op1 > 5 ? _mesa_lookup_enum_by_nr(op1) : "0"; 00396 GLuint count0 = curProg->Instructions[j][i].ArgCount[0]; 00397 GLuint count1 = curProg->Instructions[j][i].ArgCount[1]; 00398 fprintf(stderr, "%2d %04X %s %d %04X %s %d\n", i, op0, op0_enum, count0, 00399 op1, op1_enum, count1); 00400 } 00401 } 00402 #endif 00403 if (ctx->Driver.ProgramStringNotify) 00404 ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_SHADER_ATI, NULL ); 00405 } 00406 00407 void GLAPIENTRY 00408 _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle) 00409 { 00410 GET_CURRENT_CONTEXT(ctx); 00411 struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; 00412 struct atifs_setupinst *curI; 00413 00414 if (!ctx->ATIFragmentShader.Compiling) { 00415 _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(outsideShader)"); 00416 return; 00417 } 00418 00419 if (curProg->cur_pass == 1) { 00420 match_pair_inst(curProg, 0); 00421 curProg->cur_pass = 2; 00422 } 00423 if ((curProg->cur_pass > 2) || 00424 ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) { 00425 _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoord(pass)"); 00426 return; 00427 } 00428 if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) || 00429 ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) { 00430 _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(dst)"); 00431 return; 00432 } 00433 if (((coord < GL_REG_0_ATI) || (coord > GL_REG_5_ATI)) && 00434 ((coord < GL_TEXTURE0_ARB) || (coord > GL_TEXTURE7_ARB) || 00435 ((coord - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) { 00436 _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(coord)"); 00437 return; 00438 } 00439 if ((curProg->cur_pass == 0) && (coord >= GL_REG_0_ATI)) { 00440 _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)"); 00441 return; 00442 } 00443 if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) { 00444 _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)"); 00445 return; 00446 } 00447 if ((swizzle & 1) && (coord >= GL_REG_0_ATI)) { 00448 _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)"); 00449 return; 00450 } 00451 if (coord <= GL_TEXTURE7_ARB) { 00452 GLuint tmp = coord - GL_TEXTURE0_ARB; 00453 if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) && 00454 (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) { 00455 _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)"); 00456 return; 00457 } else { 00458 curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2)); 00459 } 00460 } 00461 00462 curProg->regsAssigned[curProg->cur_pass >> 1] |= 1 << (dst - GL_REG_0_ATI); 00463 new_tex_inst(curProg); 00464 00465 /* add the instructions */ 00466 curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI]; 00467 00468 curI->Opcode = ATI_FRAGMENT_SHADER_PASS_OP; 00469 curI->src = coord; 00470 curI->swizzle = swizzle; 00471 00472 #if MESA_DEBUG_ATI_FS 00473 _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__, 00474 _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord), 00475 _mesa_lookup_enum_by_nr(swizzle)); 00476 #endif 00477 } 00478 00479 void GLAPIENTRY 00480 _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle) 00481 { 00482 GET_CURRENT_CONTEXT(ctx); 00483 struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; 00484 struct atifs_setupinst *curI; 00485 00486 if (!ctx->ATIFragmentShader.Compiling) { 00487 _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(outsideShader)"); 00488 return; 00489 } 00490 00491 if (curProg->cur_pass == 1) { 00492 match_pair_inst(curProg, 0); 00493 curProg->cur_pass = 2; 00494 } 00495 if ((curProg->cur_pass > 2) || 00496 ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) { 00497 _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(pass)"); 00498 return; 00499 } 00500 if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) || 00501 ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) { 00502 _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(dst)"); 00503 return; 00504 } 00505 if (((interp < GL_REG_0_ATI) || (interp > GL_REG_5_ATI)) && 00506 ((interp < GL_TEXTURE0_ARB) || (interp > GL_TEXTURE7_ARB) || 00507 ((interp - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) { 00508 /* is this texture5 or texture7? spec is a bit unclear there */ 00509 _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(interp)"); 00510 return; 00511 } 00512 if ((curProg->cur_pass == 0) && (interp >= GL_REG_0_ATI)) { 00513 _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)"); 00514 return; 00515 } 00516 if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) { 00517 _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)"); 00518 return; 00519 } 00520 if ((swizzle & 1) && (interp >= GL_REG_0_ATI)) { 00521 _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)"); 00522 return; 00523 } 00524 if (interp <= GL_TEXTURE7_ARB) { 00525 GLuint tmp = interp - GL_TEXTURE0_ARB; 00526 if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) && 00527 (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) { 00528 _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)"); 00529 return; 00530 } else { 00531 curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2)); 00532 } 00533 } 00534 00535 curProg->regsAssigned[curProg->cur_pass >> 1] |= 1 << (dst - GL_REG_0_ATI); 00536 new_tex_inst(curProg); 00537 00538 /* add the instructions */ 00539 curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI]; 00540 00541 curI->Opcode = ATI_FRAGMENT_SHADER_SAMPLE_OP; 00542 curI->src = interp; 00543 curI->swizzle = swizzle; 00544 00545 #if MESA_DEBUG_ATI_FS 00546 _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__, 00547 _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp), 00548 _mesa_lookup_enum_by_nr(swizzle)); 00549 #endif 00550 } 00551 00552 static void 00553 _mesa_FragmentOpXATI(GLint optype, GLuint arg_count, GLenum op, GLuint dst, 00554 GLuint dstMask, GLuint dstMod, GLuint arg1, 00555 GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, 00556 GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, 00557 GLuint arg3Rep, GLuint arg3Mod) 00558 { 00559 GET_CURRENT_CONTEXT(ctx); 00560 struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; 00561 GLint ci; 00562 struct atifs_instruction *curI; 00563 GLuint modtemp = dstMod & ~GL_SATURATE_BIT_ATI; 00564 00565 if (!ctx->ATIFragmentShader.Compiling) { 00566 _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(outsideShader)"); 00567 return; 00568 } 00569 00570 if (curProg->cur_pass==0) 00571 curProg->cur_pass=1; 00572 00573 else if (curProg->cur_pass==2) 00574 curProg->cur_pass=3; 00575 00576 /* decide whether this is a new instruction or not ... all color instructions are new, 00577 and alpha instructions might also be new if there was no preceding color inst */ 00578 if ((optype == 0) || (curProg->last_optype == optype)) { 00579 if (curProg->numArithInstr[curProg->cur_pass >> 1] > 7) { 00580 _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(instrCount)"); 00581 return; 00582 } 00583 /* easier to do that here slight side effect invalid instr will still be inserted as nops */ 00584 match_pair_inst(curProg, optype); 00585 new_arith_inst(curProg); 00586 } 00587 curProg->last_optype = optype; 00588 ci = curProg->numArithInstr[curProg->cur_pass >> 1] - 1; 00589 00590 /* add the instructions */ 00591 curI = &curProg->Instructions[curProg->cur_pass >> 1][ci]; 00592 00593 /* error checking */ 00594 if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI)) { 00595 _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dst)"); 00596 return; 00597 } 00598 if ((modtemp != GL_NONE) && (modtemp != GL_2X_BIT_ATI) && 00599 (modtemp != GL_4X_BIT_ATI) && (modtemp != GL_8X_BIT_ATI) && 00600 (modtemp != GL_HALF_BIT_ATI) && !(modtemp != GL_QUARTER_BIT_ATI) && 00601 (modtemp != GL_EIGHTH_BIT_ATI)) { 00602 _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dstMod)%x", modtemp); 00603 return; 00604 } 00605 /* op checking? Actually looks like that's missing in the spec but we'll do it anyway */ 00606 if (((op < GL_ADD_ATI) || (op > GL_DOT2_ADD_ATI)) && !(op == GL_MOV_ATI)) { 00607 _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(op)"); 00608 return; 00609 } 00610 if (optype == 1) { 00611 if (((op == GL_DOT2_ADD_ATI) && (curI->Opcode[0] != GL_DOT2_ADD_ATI)) || 00612 ((op == GL_DOT3_ATI) && (curI->Opcode[0] != GL_DOT3_ATI)) || 00613 ((op == GL_DOT4_ATI) && (curI->Opcode[0] != GL_DOT4_ATI)) || 00614 ((op != GL_DOT4_ATI) && (curI->Opcode[0] == GL_DOT4_ATI))) { 00615 _mesa_error(ctx, GL_INVALID_OPERATION, "AFragmentOpATI(op)"); 00616 return; 00617 } 00618 } 00619 if ((op == GL_DOT4_ATI) && 00620 (((arg1 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg1Rep == GL_ALPHA) || (arg1Rep == GL_NONE))) || 00621 (((arg2 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg2Rep == GL_ALPHA) || (arg2Rep == GL_NONE)))))) { 00622 _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)"); 00623 } 00624 00625 if (!check_arith_arg(curProg, optype, arg1, arg1Rep)) { 00626 return; 00627 } 00628 if (arg2) { 00629 if (!check_arith_arg(curProg, optype, arg2, arg2Rep)) { 00630 return; 00631 } 00632 } 00633 if (arg3) { 00634 if (!check_arith_arg(curProg, optype, arg3, arg3Rep)) { 00635 return; 00636 } 00637 if ((arg1 >= GL_CON_0_ATI) && (arg1 <= GL_CON_7_ATI) && 00638 (arg2 >= GL_CON_0_ATI) && (arg2 <= GL_CON_7_ATI) && 00639 (arg3 >= GL_CON_0_ATI) && (arg3 <= GL_CON_7_ATI) && 00640 (arg1 != arg2) && (arg1 != arg3) && (arg2 != arg3)) { 00641 _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(3Consts)"); 00642 return; 00643 } 00644 } 00645 00646 /* all ok - not all fully validated though (e.g. argNMod - spec doesn't say anything) */ 00647 00648 curI->Opcode[optype] = op; 00649 curI->SrcReg[optype][0].Index = arg1; 00650 curI->SrcReg[optype][0].argRep = arg1Rep; 00651 curI->SrcReg[optype][0].argMod = arg1Mod; 00652 curI->ArgCount[optype] = arg_count; 00653 00654 if (arg2) { 00655 curI->SrcReg[optype][1].Index = arg2; 00656 curI->SrcReg[optype][1].argRep = arg2Rep; 00657 curI->SrcReg[optype][1].argMod = arg2Mod; 00658 } 00659 00660 if (arg3) { 00661 curI->SrcReg[optype][2].Index = arg3; 00662 curI->SrcReg[optype][2].argRep = arg3Rep; 00663 curI->SrcReg[optype][2].argMod = arg3Mod; 00664 } 00665 00666 curI->DstReg[optype].Index = dst; 00667 curI->DstReg[optype].dstMod = dstMod; 00668 curI->DstReg[optype].dstMask = dstMask; 00669 00670 #if MESA_DEBUG_ATI_FS 00671 debug_op(optype, arg_count, op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod); 00672 #endif 00673 00674 } 00675 00676 void GLAPIENTRY 00677 _mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask, 00678 GLuint dstMod, GLuint arg1, GLuint arg1Rep, 00679 GLuint arg1Mod) 00680 { 00681 _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 1, op, dst, dstMask, 00682 dstMod, arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0); 00683 } 00684 00685 void GLAPIENTRY 00686 _mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask, 00687 GLuint dstMod, GLuint arg1, GLuint arg1Rep, 00688 GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, 00689 GLuint arg2Mod) 00690 { 00691 _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 2, op, dst, dstMask, 00692 dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, 00693 arg2Mod, 0, 0, 0); 00694 } 00695 00696 void GLAPIENTRY 00697 _mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask, 00698 GLuint dstMod, GLuint arg1, GLuint arg1Rep, 00699 GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, 00700 GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, 00701 GLuint arg3Mod) 00702 { 00703 _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 3, op, dst, dstMask, 00704 dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, 00705 arg2Mod, arg3, arg3Rep, arg3Mod); 00706 } 00707 00708 void GLAPIENTRY 00709 _mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, 00710 GLuint arg1Rep, GLuint arg1Mod) 00711 { 00712 _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 1, op, dst, 0, dstMod, 00713 arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0); 00714 } 00715 00716 void GLAPIENTRY 00717 _mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, 00718 GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, 00719 GLuint arg2Rep, GLuint arg2Mod) 00720 { 00721 _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 2, op, dst, 0, dstMod, 00722 arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, 0, 0, 00723 0); 00724 } 00725 00726 void GLAPIENTRY 00727 _mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, 00728 GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, 00729 GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, 00730 GLuint arg3Rep, GLuint arg3Mod) 00731 { 00732 _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 3, op, dst, 0, dstMod, 00733 arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, 00734 arg3Rep, arg3Mod); 00735 } 00736 00737 void GLAPIENTRY 00738 _mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value) 00739 { 00740 GLuint dstindex; 00741 GET_CURRENT_CONTEXT(ctx); 00742 00743 if ((dst < GL_CON_0_ATI) || (dst > GL_CON_7_ATI)) { 00744 /* spec says nothing about what should happen here but we can't just segfault...*/ 00745 _mesa_error(ctx, GL_INVALID_ENUM, "glSetFragmentShaderConstantATI(dst)"); 00746 return; 00747 } 00748 00749 dstindex = dst - GL_CON_0_ATI; 00750 if (ctx->ATIFragmentShader.Compiling) { 00751 struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; 00752 COPY_4V(curProg->Constants[dstindex], value); 00753 curProg->LocalConstDef |= 1 << dstindex; 00754 } 00755 else { 00756 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00757 COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value); 00758 } 00759 } Generated on Sun May 27 2012 04:20:33 for ReactOS by
1.7.6.1
|