s_fragprog.c revision f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3
1865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/* 2865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Mesa 3-D graphics library 3865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Version: 6.5.2 4865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * 5865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * 7865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Permission is hereby granted, free of charge, to any person obtaining a 8865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * copy of this software and associated documentation files (the "Software"), 9865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * to deal in the Software without restriction, including without limitation 10865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * and/or sell copies of the Software, and to permit persons to whom the 12865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Software is furnished to do so, subject to the following conditions: 13865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * 14865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * The above copyright notice and this permission notice shall be included 15865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * in all copies or substantial portions of the Software. 16865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * 17865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 24865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 25865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#include "glheader.h" 26865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#include "colormac.h" 27865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#include "context.h" 28865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#include "prog_instruction.h" 29865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#include "prog_parameter.h" 30865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#include "prog_print.h" 31865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#include "program.h" 32865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 33c968d3d410a1897ecbb41d3557adaef69a4c627aBrian#include "s_fragprog.h" 34865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#include "s_span.h" 357aece10039ad4786d7f85d61ec8614b9f287ea23Brian#include "slang_library_noise.h" 36865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 37865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 38865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/* See comments below for info about this */ 39865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#define LAMBDA_ZERO 1 40865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 41865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/* debug predicate */ 42865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#define DEBUG_FRAG 0 43865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 44865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 45865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 46865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Virtual machine state used during execution of a fragment programs. 47865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 48865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstruct fp_machine 49865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 50f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian /** Fragment Input attributes */ 51f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*Attribs)[MAX_WIDTH][4]; 52f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLuint CurFrag; /**< Index into Attribs arrays */ 53f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 54865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat Temporaries[MAX_PROGRAM_TEMPS][4]; 55865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat Outputs[FRAG_RESULT_MAX][4]; 56865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ 57865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 58865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ 59865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint StackDepth; /**< Index/ptr to top of CallStack[] */ 60865f88afc0d59d886fb2ad50429e584ecf17fa81Brian}; 61865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 62865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 63865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#if FEATURE_MESA_program_debug 64865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic struct fp_machine *CurrentMachine = NULL; 65865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 66865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 67865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * For GL_MESA_program_debug. 68865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Return current value (4*GLfloat) of a fragment program register. 69865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Called via ctx->Driver.GetFragmentProgramRegister(). 70865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 71865f88afc0d59d886fb2ad50429e584ecf17fa81Brianvoid 72865f88afc0d59d886fb2ad50429e584ecf17fa81Brian_swrast_get_program_register(GLcontext *ctx, enum register_file file, 73865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint index, GLfloat val[4]) 74865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 75865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (CurrentMachine) { 76865f88afc0d59d886fb2ad50429e584ecf17fa81Brian switch (file) { 77865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_INPUT: 78f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian COPY_4V(val, CurrentMachine->Attribs[index][CurrentMachine->CurFrag]); 79865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 80865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_OUTPUT: 81865f88afc0d59d886fb2ad50429e584ecf17fa81Brian COPY_4V(val, CurrentMachine->Outputs[index]); 82865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 83865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_TEMPORARY: 84865f88afc0d59d886fb2ad50429e584ecf17fa81Brian COPY_4V(val, CurrentMachine->Temporaries[index]); 85865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 86865f88afc0d59d886fb2ad50429e584ecf17fa81Brian default: 87865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_problem(NULL, 88865f88afc0d59d886fb2ad50429e584ecf17fa81Brian "bad register file in _swrast_get_program_register"); 89865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 90865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 91865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 92865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#endif /* FEATURE_MESA_program_debug */ 93865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 94865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 95865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 96865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Fetch a texel. 97865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 98865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic void 99865f88afc0d59d886fb2ad50429e584ecf17fa81Brianfetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, 100865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint unit, GLfloat color[4] ) 101865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 102865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLchan rgba[4]; 103865f88afc0d59d886fb2ad50429e584ecf17fa81Brian SWcontext *swrast = SWRAST_CONTEXT(ctx); 104865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 105865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* XXX use a float-valued TextureSample routine here!!! */ 106865f88afc0d59d886fb2ad50429e584ecf17fa81Brian swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, 107865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1, (const GLfloat (*)[4]) texcoord, 108865f88afc0d59d886fb2ad50429e584ecf17fa81Brian &lambda, &rgba); 109865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color[0] = CHAN_TO_FLOAT(rgba[0]); 110865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color[1] = CHAN_TO_FLOAT(rgba[1]); 111865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color[2] = CHAN_TO_FLOAT(rgba[2]); 112865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color[3] = CHAN_TO_FLOAT(rgba[3]); 113865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 114865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 115865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 116865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 117865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Fetch a texel with the given partial derivatives to compute a level 118865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * of detail in the mipmap. 119865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 120865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic void 121865f88afc0d59d886fb2ad50429e584ecf17fa81Brianfetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], 122865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat texdx[4], const GLfloat texdy[4], 123865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint unit, GLfloat color[4] ) 124865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 125865f88afc0d59d886fb2ad50429e584ecf17fa81Brian SWcontext *swrast = SWRAST_CONTEXT(ctx); 126865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; 127865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; 128865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat texW = (GLfloat) texImg->WidthScale; 129865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat texH = (GLfloat) texImg->HeightScale; 130865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLchan rgba[4]; 131865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 132865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ 133865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texdx[1], texdy[1], /* dt/dx, dt/dy */ 134865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texdx[3], texdy[2], /* dq/dx, dq/dy */ 135865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texW, texH, 136865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texcoord[0], texcoord[1], texcoord[3], 137865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1.0F / texcoord[3]); 138865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 139865f88afc0d59d886fb2ad50429e584ecf17fa81Brian swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, 140865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1, (const GLfloat (*)[4]) texcoord, 141865f88afc0d59d886fb2ad50429e584ecf17fa81Brian &lambda, &rgba); 142865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color[0] = CHAN_TO_FLOAT(rgba[0]); 143865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color[1] = CHAN_TO_FLOAT(rgba[1]); 144865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color[2] = CHAN_TO_FLOAT(rgba[2]); 145865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color[3] = CHAN_TO_FLOAT(rgba[3]); 146865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 147865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 148865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 149865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 150865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Return a pointer to the 4-element float vector specified by the given 151865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * source register. 152865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 153865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic INLINE const GLfloat * 154865f88afc0d59d886fb2ad50429e584ecf17fa81Brianget_register_pointer( GLcontext *ctx, 155865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct prog_src_register *source, 156865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct fp_machine *machine, 157865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_fragment_program *program ) 158865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 159ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian /* XXX relative addressing... */ 160865f88afc0d59d886fb2ad50429e584ecf17fa81Brian switch (source->File) { 161865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_TEMPORARY: 162865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(source->Index < MAX_PROGRAM_TEMPS); 163865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return machine->Temporaries[source->Index]; 164865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_INPUT: 165865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(source->Index < FRAG_ATTRIB_MAX); 166f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian return machine->Attribs[source->Index][machine->CurFrag]; 167865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_OUTPUT: 168865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* This is only for PRINT */ 169865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(source->Index < FRAG_RESULT_MAX); 170865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return machine->Outputs[source->Index]; 171865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_LOCAL_PARAM: 172865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); 173865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return program->Base.LocalParams[source->Index]; 174865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_ENV_PARAM: 175865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS); 176865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return ctx->FragmentProgram.Parameters[source->Index]; 177865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_STATE_VAR: 178865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Fallthrough */ 179865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_CONSTANT: 180865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Fallthrough */ 181865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_UNIFORM: 182865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Fallthrough */ 183865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_NAMED_PARAM: 184865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters); 185865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return program->Base.Parameters->ParameterValues[source->Index]; 186865f88afc0d59d886fb2ad50429e584ecf17fa81Brian default: 187865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_problem(ctx, "Invalid input register file %d in fp " 188865f88afc0d59d886fb2ad50429e584ecf17fa81Brian "get_register_pointer", source->File); 189865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return NULL; 190865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 191865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 192865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 193865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 194865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 195865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Fetch a 4-element float vector from the given source register. 196865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Apply swizzling and negating as needed. 197865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 198865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic void 199865f88afc0d59d886fb2ad50429e584ecf17fa81Brianfetch_vector4( GLcontext *ctx, 200865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct prog_src_register *source, 201865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct fp_machine *machine, 202865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_fragment_program *program, 203865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat result[4] ) 204865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 205865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat *src = get_register_pointer(ctx, source, machine, program); 206865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(src); 207865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 208223d7cb3c785ad58c869a3ee0fbf2f1d42c3310dBrian if (source->Swizzle == SWIZZLE_NOOP) { 209865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* no swizzling */ 210865f88afc0d59d886fb2ad50429e584ecf17fa81Brian COPY_4V(result, src); 211865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 212865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 213f673b24017b8b5e850a1be5c04bd28cefa811329Brian ASSERT(GET_SWZ(source->Swizzle, 0) <= 3); 214f673b24017b8b5e850a1be5c04bd28cefa811329Brian ASSERT(GET_SWZ(source->Swizzle, 1) <= 3); 215f673b24017b8b5e850a1be5c04bd28cefa811329Brian ASSERT(GET_SWZ(source->Swizzle, 2) <= 3); 216f673b24017b8b5e850a1be5c04bd28cefa811329Brian ASSERT(GET_SWZ(source->Swizzle, 3) <= 3); 217865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = src[GET_SWZ(source->Swizzle, 0)]; 218865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = src[GET_SWZ(source->Swizzle, 1)]; 219865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = src[GET_SWZ(source->Swizzle, 2)]; 220865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = src[GET_SWZ(source->Swizzle, 3)]; 221865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 222865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 223865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->NegateBase) { 224865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = -result[0]; 225865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = -result[1]; 226865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = -result[2]; 227865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = -result[3]; 228865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 229865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->Abs) { 230865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = FABSF(result[0]); 231865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = FABSF(result[1]); 232865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = FABSF(result[2]); 233865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = FABSF(result[3]); 234865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 235865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->NegateAbs) { 236865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = -result[0]; 237865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = -result[1]; 238865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = -result[2]; 239865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = -result[3]; 240865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 241865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 242865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 243865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 244865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 245865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Fetch the derivative with respect to X for the given register. 246865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \return GL_TRUE if it was easily computed or GL_FALSE if we 247865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * need to execute another instance of the program (ugh)! 248865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 249865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic GLboolean 250865f88afc0d59d886fb2ad50429e584ecf17fa81Brianfetch_vector4_deriv( GLcontext *ctx, 251865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct prog_src_register *source, 252865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const SWspan *span, 253865f88afc0d59d886fb2ad50429e584ecf17fa81Brian char xOrY, GLint column, GLfloat result[4] ) 254865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 255865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat src[4]; 256865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 257865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(xOrY == 'X' || xOrY == 'Y'); 258865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 259865f88afc0d59d886fb2ad50429e584ecf17fa81Brian switch (source->Index) { 260865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_WPOS: 261865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 262865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = 1.0; 263865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = 0.0; 264865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = span->dzdx / ctx->DrawBuffer->_DepthMaxF; 265865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = span->dwdx; 266865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 267865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 268865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = 0.0; 269865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = 1.0; 270865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = span->dzdy / ctx->DrawBuffer->_DepthMaxF; 271865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = span->dwdy; 272865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 273865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 274865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_COL0: 275865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 276865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = span->drdx * (1.0F / CHAN_MAXF); 277865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = span->dgdx * (1.0F / CHAN_MAXF); 278865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = span->dbdx * (1.0F / CHAN_MAXF); 279865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = span->dadx * (1.0F / CHAN_MAXF); 280865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 281865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 282865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = span->drdy * (1.0F / CHAN_MAXF); 283865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = span->dgdy * (1.0F / CHAN_MAXF); 284865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = span->dbdy * (1.0F / CHAN_MAXF); 285865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = span->dady * (1.0F / CHAN_MAXF); 286865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 287865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 288865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_COL1: 289865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 290865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = span->dsrdx * (1.0F / CHAN_MAXF); 291865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = span->dsgdx * (1.0F / CHAN_MAXF); 292865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = span->dsbdx * (1.0F / CHAN_MAXF); 293865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = 0.0; /* XXX need this */ 294865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 295865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 296865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = span->dsrdy * (1.0F / CHAN_MAXF); 297865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = span->dsgdy * (1.0F / CHAN_MAXF); 298865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = span->dsbdy * (1.0F / CHAN_MAXF); 299865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = 0.0; /* XXX need this */ 300865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 301865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 302865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_FOGC: 303865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 304865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = span->dfogdx; 305865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = 0.0; 306865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = 0.0; 307865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = 0.0; 308865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 309865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 310865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = span->dfogdy; 311865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = 0.0; 312865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = 0.0; 313865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = 0.0; 314865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 315865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 316865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_TEX0: 317865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_TEX1: 318865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_TEX2: 319865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_TEX3: 320865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_TEX4: 321865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_TEX5: 322865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_TEX6: 323865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case FRAG_ATTRIB_TEX7: 324865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 325865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint u = source->Index - FRAG_ATTRIB_TEX0; 326865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* this is a little tricky - I think I've got it right */ 327865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat invQ = 1.0f / (span->tex[u][3] 328865f88afc0d59d886fb2ad50429e584ecf17fa81Brian + span->texStepX[u][3] * column); 329865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = span->texStepX[u][0] * invQ; 330865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = span->texStepX[u][1] * invQ; 331865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = span->texStepX[u][2] * invQ; 332865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = span->texStepX[u][3] * invQ; 333865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 334865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 335865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint u = source->Index - FRAG_ATTRIB_TEX0; 336865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Tricky, as above, but in Y direction */ 337865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat invQ = 1.0f / (span->tex[u][3] + span->texStepY[u][3]); 338865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[0] = span->texStepY[u][0] * invQ; 339865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[1] = span->texStepY[u][1] * invQ; 340865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[2] = span->texStepY[u][2] * invQ; 341865f88afc0d59d886fb2ad50429e584ecf17fa81Brian src[3] = span->texStepY[u][3] * invQ; 342865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 343865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 344865f88afc0d59d886fb2ad50429e584ecf17fa81Brian default: 345865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return GL_FALSE; 346865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 347865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 348865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = src[GET_SWZ(source->Swizzle, 0)]; 349865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = src[GET_SWZ(source->Swizzle, 1)]; 350865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = src[GET_SWZ(source->Swizzle, 2)]; 351865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = src[GET_SWZ(source->Swizzle, 3)]; 352865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 353865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->NegateBase) { 354865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = -result[0]; 355865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = -result[1]; 356865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = -result[2]; 357865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = -result[3]; 358865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 359865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->Abs) { 360865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = FABSF(result[0]); 361865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = FABSF(result[1]); 362865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = FABSF(result[2]); 363865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = FABSF(result[3]); 364865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 365865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->NegateAbs) { 366865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = -result[0]; 367865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = -result[1]; 368865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = -result[2]; 369865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = -result[3]; 370865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 371865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return GL_TRUE; 372865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 373865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 374865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 375865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 376865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * As above, but only return result[0] element. 377865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 378865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic void 379865f88afc0d59d886fb2ad50429e584ecf17fa81Brianfetch_vector1( GLcontext *ctx, 380865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct prog_src_register *source, 381865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct fp_machine *machine, 382865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_fragment_program *program, 383865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat result[4] ) 384865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 385865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat *src = get_register_pointer(ctx, source, machine, program); 386865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(src); 387865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 388865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = src[GET_SWZ(source->Swizzle, 0)]; 389865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 390865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->NegateBase) { 391865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = -result[0]; 392865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 393865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->Abs) { 394865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = FABSF(result[0]); 395865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 396865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->NegateAbs) { 397865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = -result[0]; 398865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 399865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 400865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 401865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 402865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 403865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Test value against zero and return GT, LT, EQ or UN if NaN. 404865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 405865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic INLINE GLuint 406865f88afc0d59d886fb2ad50429e584ecf17fa81Briangenerate_cc( float value ) 407865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 408865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (value != value) 409865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return COND_UN; /* NaN */ 410865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (value > 0.0F) 411865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return COND_GT; 412865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (value < 0.0F) 413865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return COND_LT; 414865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return COND_EQ; 415865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 416865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 417865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 418865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 419865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Test if the ccMaskRule is satisfied by the given condition code. 420865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Used to mask destination writes according to the current condition code. 421865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 422865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic INLINE GLboolean 423865f88afc0d59d886fb2ad50429e584ecf17fa81Briantest_cc(GLuint condCode, GLuint ccMaskRule) 424865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 425865f88afc0d59d886fb2ad50429e584ecf17fa81Brian switch (ccMaskRule) { 426865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case COND_EQ: return (condCode == COND_EQ); 427865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case COND_NE: return (condCode != COND_EQ); 428865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case COND_LT: return (condCode == COND_LT); 429865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case COND_GE: return (condCode == COND_GT || condCode == COND_EQ); 430865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case COND_LE: return (condCode == COND_LT || condCode == COND_EQ); 431865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case COND_GT: return (condCode == COND_GT); 432865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case COND_TR: return GL_TRUE; 433865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case COND_FL: return GL_FALSE; 434865f88afc0d59d886fb2ad50429e584ecf17fa81Brian default: return GL_TRUE; 435865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 436865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 437865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 438865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 439865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 440865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Store 4 floats into a register. Observe the instructions saturate and 441865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * set-condition-code flags. 442865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 443865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic void 444865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstore_vector4( const struct prog_instruction *inst, 445865f88afc0d59d886fb2ad50429e584ecf17fa81Brian struct fp_machine *machine, 446865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat value[4] ) 447865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 448865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct prog_dst_register *dest = &(inst->DstReg); 449865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE; 450865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat *dstReg; 451865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat dummyReg[4]; 452865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat clampedValue[4]; 453865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint writeMask = dest->WriteMask; 454865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 455865f88afc0d59d886fb2ad50429e584ecf17fa81Brian switch (dest->File) { 456865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_OUTPUT: 457865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dstReg = machine->Outputs[dest->Index]; 458865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 459865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_TEMPORARY: 460865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dstReg = machine->Temporaries[dest->Index]; 461865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 462865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case PROGRAM_WRITE_ONLY: 463865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dstReg = dummyReg; 464865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return; 465865f88afc0d59d886fb2ad50429e584ecf17fa81Brian default: 466865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_problem(NULL, "bad register file in store_vector4(fp)"); 467865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return; 468865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 469865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 470865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#if 0 471865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (value[0] > 1.0e10 || 472865f88afc0d59d886fb2ad50429e584ecf17fa81Brian IS_INF_OR_NAN(value[0]) || 473865f88afc0d59d886fb2ad50429e584ecf17fa81Brian IS_INF_OR_NAN(value[1]) || 474865f88afc0d59d886fb2ad50429e584ecf17fa81Brian IS_INF_OR_NAN(value[2]) || 475865f88afc0d59d886fb2ad50429e584ecf17fa81Brian IS_INF_OR_NAN(value[3]) ) 476865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]); 477865f88afc0d59d886fb2ad50429e584ecf17fa81Brian#endif 478865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 479865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (clamp) { 480865f88afc0d59d886fb2ad50429e584ecf17fa81Brian clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F); 481865f88afc0d59d886fb2ad50429e584ecf17fa81Brian clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F); 482865f88afc0d59d886fb2ad50429e584ecf17fa81Brian clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F); 483865f88afc0d59d886fb2ad50429e584ecf17fa81Brian clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F); 484865f88afc0d59d886fb2ad50429e584ecf17fa81Brian value = clampedValue; 485865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 486865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 487865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (dest->CondMask != COND_TR) { 488865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* condition codes may turn off some writes */ 489865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_X) { 490865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)], 491865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dest->CondMask)) 492865f88afc0d59d886fb2ad50429e584ecf17fa81Brian writeMask &= ~WRITEMASK_X; 493865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 494865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_Y) { 495865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)], 496865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dest->CondMask)) 497865f88afc0d59d886fb2ad50429e584ecf17fa81Brian writeMask &= ~WRITEMASK_Y; 498865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 499865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_Z) { 500865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)], 501865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dest->CondMask)) 502865f88afc0d59d886fb2ad50429e584ecf17fa81Brian writeMask &= ~WRITEMASK_Z; 503865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 504865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_W) { 505865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)], 506865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dest->CondMask)) 507865f88afc0d59d886fb2ad50429e584ecf17fa81Brian writeMask &= ~WRITEMASK_W; 508865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 509865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 510865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 511865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_X) 512865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dstReg[0] = value[0]; 513865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_Y) 514865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dstReg[1] = value[1]; 515865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_Z) 516865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dstReg[2] = value[2]; 517865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_W) 518865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dstReg[3] = value[3]; 519865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 520865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (inst->CondUpdate) { 521865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_X) 522865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->CondCodes[0] = generate_cc(value[0]); 523865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_Y) 524865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->CondCodes[1] = generate_cc(value[1]); 525865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_Z) 526865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->CondCodes[2] = generate_cc(value[2]); 527865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (writeMask & WRITEMASK_W) 528865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->CondCodes[3] = generate_cc(value[3]); 529865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 530865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 531865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 532865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 533865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 534865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Initialize a new machine state instance from an existing one, adding 535865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * the partial derivatives onto the input registers. 536865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Used to implement DDX and DDY instructions in non-trivial cases. 537865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 538865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic void 539865f88afc0d59d886fb2ad50429e584ecf17fa81Brianinit_machine_deriv( GLcontext *ctx, 540865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct fp_machine *machine, 541865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_fragment_program *program, 542865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const SWspan *span, char xOrY, 543865f88afc0d59d886fb2ad50429e584ecf17fa81Brian struct fp_machine *dMachine ) 544865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 545865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint u, v; 546865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 547865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(xOrY == 'X' || xOrY == 'Y'); 548865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 549865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* copy existing machine */ 550865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine)); 551865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 552865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { 553865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Clear temporary registers (undefined for ARB_f_p) */ 554865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_bzero( (void*) machine->Temporaries, 555865f88afc0d59d886fb2ad50429e584ecf17fa81Brian MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); 556865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 557865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 558865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Add derivatives */ 559ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian if (program->Base.InputsRead & FRAG_BIT_WPOS) { 560f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat *wpos = machine->Attribs[FRAG_ATTRIB_WPOS][machine->CurFrag]; 561865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 562865f88afc0d59d886fb2ad50429e584ecf17fa81Brian wpos[0] += 1.0F; 563865f88afc0d59d886fb2ad50429e584ecf17fa81Brian wpos[1] += 0.0F; 564865f88afc0d59d886fb2ad50429e584ecf17fa81Brian wpos[2] += span->dzdx; 565865f88afc0d59d886fb2ad50429e584ecf17fa81Brian wpos[3] += span->dwdx; 566865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 567865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 568865f88afc0d59d886fb2ad50429e584ecf17fa81Brian wpos[0] += 0.0F; 569865f88afc0d59d886fb2ad50429e584ecf17fa81Brian wpos[1] += 1.0F; 570865f88afc0d59d886fb2ad50429e584ecf17fa81Brian wpos[2] += span->dzdy; 571865f88afc0d59d886fb2ad50429e584ecf17fa81Brian wpos[3] += span->dwdy; 572865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 573865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 574ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian if (program->Base.InputsRead & FRAG_BIT_COL0) { 575f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat *col0 = machine->Attribs[FRAG_ATTRIB_COL0][machine->CurFrag]; 576865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 577865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col0[0] += span->drdx * (1.0F / CHAN_MAXF); 578865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col0[1] += span->dgdx * (1.0F / CHAN_MAXF); 579865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col0[2] += span->dbdx * (1.0F / CHAN_MAXF); 580865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col0[3] += span->dadx * (1.0F / CHAN_MAXF); 581865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 582865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 583865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col0[0] += span->drdy * (1.0F / CHAN_MAXF); 584865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col0[1] += span->dgdy * (1.0F / CHAN_MAXF); 585865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col0[2] += span->dbdy * (1.0F / CHAN_MAXF); 586865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col0[3] += span->dady * (1.0F / CHAN_MAXF); 587865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 588865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 589ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian if (program->Base.InputsRead & FRAG_BIT_COL1) { 590f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat *col1 = machine->Attribs[FRAG_ATTRIB_COL1][machine->CurFrag]; 591865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 592865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col1[0] += span->dsrdx * (1.0F / CHAN_MAXF); 593865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col1[1] += span->dsgdx * (1.0F / CHAN_MAXF); 594865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col1[2] += span->dsbdx * (1.0F / CHAN_MAXF); 595865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col1[3] += 0.0; /*XXX fix */ 596865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 597865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 598865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col1[0] += span->dsrdy * (1.0F / CHAN_MAXF); 599865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col1[1] += span->dsgdy * (1.0F / CHAN_MAXF); 600865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col1[2] += span->dsbdy * (1.0F / CHAN_MAXF); 601865f88afc0d59d886fb2ad50429e584ecf17fa81Brian col1[3] += 0.0; /*XXX fix */ 602865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 603865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 604ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian if (program->Base.InputsRead & FRAG_BIT_FOGC) { 605f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat *fogc = machine->Attribs[FRAG_ATTRIB_FOGC][machine->CurFrag]; 606865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 607865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fogc[0] += span->dfogdx; 608865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 609865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 610865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fogc[0] += span->dfogdy; 611865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 612865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 613865f88afc0d59d886fb2ad50429e584ecf17fa81Brian for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { 614ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian if (program->Base.InputsRead & FRAG_BIT_TEX(u)) { 615f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat *tex = machine->Attribs[FRAG_ATTRIB_TEX0 + u][machine->CurFrag]; 616865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* XXX perspective-correct interpolation */ 617865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (xOrY == 'X') { 618865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tex[0] += span->texStepX[u][0]; 619865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tex[1] += span->texStepX[u][1]; 620865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tex[2] += span->texStepX[u][2]; 621865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tex[3] += span->texStepX[u][3]; 622865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 623865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 624865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tex[0] += span->texStepY[u][0]; 625865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tex[1] += span->texStepY[u][1]; 626865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tex[2] += span->texStepY[u][2]; 627865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tex[3] += span->texStepY[u][3]; 628865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 629865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 630865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 631865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 632865f88afc0d59d886fb2ad50429e584ecf17fa81Brian for (v = 0; v < ctx->Const.MaxVarying; v++) { 633ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian if (program->Base.InputsRead & FRAG_BIT_VAR(v)) { 634f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat *var = machine->Attribs[FRAG_ATTRIB_VAR0 + v][machine->CurFrag]; 635ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian if (xOrY == 'X') { 636ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian var[0] += span->varStepX[v][0]; 637ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian var[1] += span->varStepX[v][1]; 638ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian var[2] += span->varStepX[v][2]; 639ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian var[3] += span->varStepX[v][3]; 640ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian } 641ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian else { 642ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian var[0] += span->varStepY[v][0]; 643ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian var[1] += span->varStepY[v][1]; 644ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian var[2] += span->varStepY[v][2]; 645ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian var[3] += span->varStepY[v][3]; 646ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5Brian } 647865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 648865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 649865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 650865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* init condition codes */ 651865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dMachine->CondCodes[0] = COND_EQ; 652865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dMachine->CondCodes[1] = COND_EQ; 653865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dMachine->CondCodes[2] = COND_EQ; 654865f88afc0d59d886fb2ad50429e584ecf17fa81Brian dMachine->CondCodes[3] = COND_EQ; 655865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 656865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 657865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 658865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 659865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Execute the given vertex program. 660865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * NOTE: we do everything in single-precision floating point; we don't 661865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * currently observe the single/half/fixed-precision qualifiers. 662865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \param ctx - rendering context 663865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \param program - the fragment program to execute 664865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \param machine - machine state (register file) 665865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \param maxInst - max number of instructions to execute 666865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. 667865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 668865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic GLboolean 669865f88afc0d59d886fb2ad50429e584ecf17fa81Brianexecute_program( GLcontext *ctx, 670865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_fragment_program *program, GLuint maxInst, 671865f88afc0d59d886fb2ad50429e584ecf17fa81Brian struct fp_machine *machine, const SWspan *span, 672865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint column ) 673865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 674f673b24017b8b5e850a1be5c04bd28cefa811329Brian const GLuint MAX_EXEC = 10000; 675d22079217c5a1954a07afb1193d06eecb2decbb6Brian GLuint pc, total = 0; 676865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 677865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 678865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("execute fragment program --------------------\n"); 679865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 680865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 681865f88afc0d59d886fb2ad50429e584ecf17fa81Brian for (pc = 0; pc < maxInst; pc++) { 682865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct prog_instruction *inst = program->Base.Instructions + pc; 683865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 684865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (ctx->FragmentProgram.CallbackEnabled && 685865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ctx->FragmentProgram.Callback) { 686865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ctx->FragmentProgram.CurrentPosition = inst->StringPos; 687865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ctx->FragmentProgram.Callback(program->Base.Target, 688865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ctx->FragmentProgram.CallbackData); 689865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 690865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 691865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 692865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_print_instruction(inst); 693865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 694865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 695865f88afc0d59d886fb2ad50429e584ecf17fa81Brian switch (inst->Opcode) { 696865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_ABS: 697865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 698865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 699865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 700865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = FABSF(a[0]); 701865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = FABSF(a[1]); 702865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = FABSF(a[2]); 703865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = FABSF(a[3]); 704865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 705865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 706865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 707865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_ADD: 708865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 709865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 710865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 711865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 712865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = a[0] + b[0]; 713865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[1] + b[1]; 714865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[2] + b[2]; 715865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = a[3] + b[3]; 716865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 717865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 718865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", 719865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], result[1], result[2], result[3], 720865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0], a[1], a[2], a[3], 721865f88afc0d59d886fb2ad50429e584ecf17fa81Brian b[0], b[1], b[2], b[3]); 722865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 723865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 724865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 725865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_BRA: /* conditional branch */ 726865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 7270031ea7d85ae8990872c2181d038fb97b566dc2bBrian /* NOTE: The branch is conditional! */ 728865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint swizzle = inst->DstReg.CondSwizzle; 729865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint condMask = inst->DstReg.CondMask; 730865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || 731865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || 732865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || 733865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { 734865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* take branch */ 735865f88afc0d59d886fb2ad50429e584ecf17fa81Brian pc = inst->BranchTarget; 736d22079217c5a1954a07afb1193d06eecb2decbb6Brian /* 737d22079217c5a1954a07afb1193d06eecb2decbb6Brian printf("Take branch to %u\n", pc); 738d22079217c5a1954a07afb1193d06eecb2decbb6Brian */ 739865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 740865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 741865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 742865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_CAL: /* Call subroutine */ 743865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 744865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* NOTE: The call is conditional! */ 745865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint swizzle = inst->DstReg.CondSwizzle; 746865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint condMask = inst->DstReg.CondMask; 747865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || 748865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || 749865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || 750865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { 751865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { 752865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ 753865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 754865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->CallStack[machine->StackDepth++] = pc + 1; 755865f88afc0d59d886fb2ad50429e584ecf17fa81Brian pc = inst->BranchTarget; 756865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 757865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 758865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 759865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_CMP: 760865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 761865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], c[4], result[4]; 762865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 763865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 764865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); 765865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = a[0] < 0.0F ? b[0] : c[0]; 766865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[1] < 0.0F ? b[1] : c[1]; 767865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[2] < 0.0F ? b[2] : c[2]; 768865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = a[3] < 0.0F ? b[3] : c[3]; 769865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 770865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 771865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 772865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_COS: 773865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 774865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 775865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 776865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] 777865f88afc0d59d886fb2ad50429e584ecf17fa81Brian = (GLfloat) _mesa_cos(a[0]); 778865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 779865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 780865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 781865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_DDX: /* Partial derivative with respect to X */ 782865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 783865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], aNext[4], result[4]; 784865f88afc0d59d886fb2ad50429e584ecf17fa81Brian struct fp_machine dMachine; 785865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X', 786865f88afc0d59d886fb2ad50429e584ecf17fa81Brian column, result)) { 787865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* This is tricky. Make a copy of the current machine state, 788865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * increment the input registers by the dx or dy partial 789865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * derivatives, then re-execute the program up to the 790865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * preceeding instruction, then fetch the source register. 791865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Finally, find the difference in the register values for 792865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * the original and derivative runs. 793865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 794865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); 795865f88afc0d59d886fb2ad50429e584ecf17fa81Brian init_machine_deriv(ctx, machine, program, span, 796865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 'X', &dMachine); 797865f88afc0d59d886fb2ad50429e584ecf17fa81Brian execute_program(ctx, program, pc, &dMachine, span, column); 798865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); 799865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = aNext[0] - a[0]; 800865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = aNext[1] - a[1]; 801865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = aNext[2] - a[2]; 802865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = aNext[3] - a[3]; 803865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 804865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 805865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 806865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 807865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_DDY: /* Partial derivative with respect to Y */ 808865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 809865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], aNext[4], result[4]; 810865f88afc0d59d886fb2ad50429e584ecf17fa81Brian struct fp_machine dMachine; 811865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y', 812865f88afc0d59d886fb2ad50429e584ecf17fa81Brian column, result)) { 813865f88afc0d59d886fb2ad50429e584ecf17fa81Brian init_machine_deriv(ctx, machine, program, span, 814865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 'Y', &dMachine); 815865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); 816865f88afc0d59d886fb2ad50429e584ecf17fa81Brian execute_program(ctx, program, pc, &dMachine, span, column); 817865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); 818865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = aNext[0] - a[0]; 819865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = aNext[1] - a[1]; 820865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = aNext[2] - a[2]; 821865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = aNext[3] - a[3]; 822865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 823865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 824865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 825865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 826865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_DP3: 827865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 828865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 829865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 830865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 831865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] = DOT3(a, b); 832865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 833865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 834865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", 835865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], a[0], a[1], a[2], b[0], b[1], b[2]); 836865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 837865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 838865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 839865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_DP4: 840865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 841865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 842865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 843865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 844865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] = DOT4(a,b); 845865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 846865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 847865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", 848865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], a[0], a[1], a[2], a[3], 849865f88afc0d59d886fb2ad50429e584ecf17fa81Brian b[0], b[1], b[2], b[3]); 850865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 851865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 852865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 853865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_DPH: 854865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 855865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 856865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 857865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 858865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] = 859865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3]; 860865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 861865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 862865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 863865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_DST: /* Distance vector */ 864865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 865865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 866865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 867865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 868865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = 1.0F; 869865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[1] * b[1]; 870865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[2]; 871865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = b[3]; 872865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 873865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 874865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 875865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_EX2: /* Exponential base 2 */ 876865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 877865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 878865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 879865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] = 880865f88afc0d59d886fb2ad50429e584ecf17fa81Brian (GLfloat) _mesa_pow(2.0, a[0]); 881865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 882865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 883865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 884865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_FLR: 885865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 886865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 887865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 888865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = FLOORF(a[0]); 889865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = FLOORF(a[1]); 890865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = FLOORF(a[2]); 891865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = FLOORF(a[3]); 892865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 893865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 894865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 895865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_FRC: 896865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 897865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 898865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 899865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = a[0] - FLOORF(a[0]); 900865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[1] - FLOORF(a[1]); 901865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[2] - FLOORF(a[2]); 902865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = a[3] - FLOORF(a[3]); 903865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 904865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 905865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 9065ae49cf3ed53fda6a904d7e90feef78495ae6903Brian case OPCODE_IF: 9075ae49cf3ed53fda6a904d7e90feef78495ae6903Brian { 9085ae49cf3ed53fda6a904d7e90feef78495ae6903Brian const GLuint swizzle = inst->DstReg.CondSwizzle; 9095ae49cf3ed53fda6a904d7e90feef78495ae6903Brian const GLuint condMask = inst->DstReg.CondMask; 9105ae49cf3ed53fda6a904d7e90feef78495ae6903Brian if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || 9115ae49cf3ed53fda6a904d7e90feef78495ae6903Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || 9125ae49cf3ed53fda6a904d7e90feef78495ae6903Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || 9135ae49cf3ed53fda6a904d7e90feef78495ae6903Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { 9145ae49cf3ed53fda6a904d7e90feef78495ae6903Brian /* do if-clause (just continue execution) */ 9155ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9165ae49cf3ed53fda6a904d7e90feef78495ae6903Brian else { 9175ae49cf3ed53fda6a904d7e90feef78495ae6903Brian /* do else-clause, or go to endif */ 9185ae49cf3ed53fda6a904d7e90feef78495ae6903Brian GLint ifDepth = 1; 9195ae49cf3ed53fda6a904d7e90feef78495ae6903Brian do { 9205ae49cf3ed53fda6a904d7e90feef78495ae6903Brian pc++; 9215ae49cf3ed53fda6a904d7e90feef78495ae6903Brian inst = program->Base.Instructions + pc; 9225ae49cf3ed53fda6a904d7e90feef78495ae6903Brian if (inst->Opcode == OPCODE_END) { 9235ae49cf3ed53fda6a904d7e90feef78495ae6903Brian /* mal-formed program! */ 9245ae49cf3ed53fda6a904d7e90feef78495ae6903Brian abort(); 9255ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9265ae49cf3ed53fda6a904d7e90feef78495ae6903Brian else if (inst->Opcode == OPCODE_IF) { 9275ae49cf3ed53fda6a904d7e90feef78495ae6903Brian ifDepth++; 9285ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9295ae49cf3ed53fda6a904d7e90feef78495ae6903Brian else if (inst->Opcode == OPCODE_ELSE) { 9305ae49cf3ed53fda6a904d7e90feef78495ae6903Brian if (ifDepth == 0) { 9315ae49cf3ed53fda6a904d7e90feef78495ae6903Brian /* ok, continue normal execution */ 9325ae49cf3ed53fda6a904d7e90feef78495ae6903Brian break; 9335ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9345ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9355ae49cf3ed53fda6a904d7e90feef78495ae6903Brian else if (inst->Opcode == OPCODE_ENDIF) { 9365ae49cf3ed53fda6a904d7e90feef78495ae6903Brian ifDepth--; 9375ae49cf3ed53fda6a904d7e90feef78495ae6903Brian if (ifDepth == 0) { 9385ae49cf3ed53fda6a904d7e90feef78495ae6903Brian /* ok, continue normal execution */ 9395ae49cf3ed53fda6a904d7e90feef78495ae6903Brian break; 9405ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9415ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9425ae49cf3ed53fda6a904d7e90feef78495ae6903Brian assert(ifDepth >= 0); 9435ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } while (pc < maxInst); 9445ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9455ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9465ae49cf3ed53fda6a904d7e90feef78495ae6903Brian break; 9475ae49cf3ed53fda6a904d7e90feef78495ae6903Brian case OPCODE_ELSE: 9485ae49cf3ed53fda6a904d7e90feef78495ae6903Brian { 9495ae49cf3ed53fda6a904d7e90feef78495ae6903Brian /* find/goto ENDIF */ 9505ae49cf3ed53fda6a904d7e90feef78495ae6903Brian GLint ifDepth = 1; 9515ae49cf3ed53fda6a904d7e90feef78495ae6903Brian do { 9525ae49cf3ed53fda6a904d7e90feef78495ae6903Brian pc++; 9535ae49cf3ed53fda6a904d7e90feef78495ae6903Brian inst = program->Base.Instructions + pc; 9545ae49cf3ed53fda6a904d7e90feef78495ae6903Brian if (inst->Opcode == OPCODE_END) { 9555ae49cf3ed53fda6a904d7e90feef78495ae6903Brian /* mal-formed program! */ 9565ae49cf3ed53fda6a904d7e90feef78495ae6903Brian abort(); 9575ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9585ae49cf3ed53fda6a904d7e90feef78495ae6903Brian else if (inst->Opcode == OPCODE_IF) { 9595ae49cf3ed53fda6a904d7e90feef78495ae6903Brian ifDepth++; 9605ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9615ae49cf3ed53fda6a904d7e90feef78495ae6903Brian else if (inst->Opcode == OPCODE_ENDIF) { 9625ae49cf3ed53fda6a904d7e90feef78495ae6903Brian ifDepth--; 9635ae49cf3ed53fda6a904d7e90feef78495ae6903Brian if (ifDepth == 0) 9645ae49cf3ed53fda6a904d7e90feef78495ae6903Brian break; 9655ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9665ae49cf3ed53fda6a904d7e90feef78495ae6903Brian assert(ifDepth >= 0); 9675ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } while (pc < maxInst); 9685ae49cf3ed53fda6a904d7e90feef78495ae6903Brian } 9695ae49cf3ed53fda6a904d7e90feef78495ae6903Brian break; 9705ae49cf3ed53fda6a904d7e90feef78495ae6903Brian case OPCODE_ENDIF: 9715ae49cf3ed53fda6a904d7e90feef78495ae6903Brian /* nothing */ 9725ae49cf3ed53fda6a904d7e90feef78495ae6903Brian break; 9730bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian case OPCODE_INT: /* float to int */ 9740bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian { 9750bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian GLfloat a[4], result[4]; 9760bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 9770bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian result[0] = (GLfloat) (GLint) a[0]; 9780bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian result[1] = (GLfloat) (GLint) a[1]; 9790bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian result[2] = (GLfloat) (GLint) a[2]; 9800bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian result[3] = (GLfloat) (GLint) a[3]; 9810bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian store_vector4( inst, machine, result ); 9820bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian } 9830bad236cfbaabfc0ed4f20088e64fa89f81934ceBrian break; 984865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_KIL_NV: /* NV_f_p only */ 985865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 986865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint swizzle = inst->DstReg.CondSwizzle; 987865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint condMask = inst->DstReg.CondMask; 988865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || 989865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || 990865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || 991865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { 992865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return GL_FALSE; 993865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 994865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 995865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 996865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_KIL: /* ARB_f_p only */ 997865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 998865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4]; 999865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1000865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) { 1001865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return GL_FALSE; 1002865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1003865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1004865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1005865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_LG2: /* log base 2 */ 1006865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1007865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1008865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1009865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] = LOG2(a[0]); 1010865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1011865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1012865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1013865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_LIT: 1014865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1015865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */ 1016865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1017865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1018865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0] = MAX2(a[0], 0.0F); 1019865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[1] = MAX2(a[1], 0.0F); 1020865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* XXX ARB version clamps a[3], NV version doesn't */ 1021865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon)); 1022865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = 1.0F; 1023865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[0]; 1024865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* XXX we could probably just use pow() here */ 1025865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (a[0] > 0.0F) { 1026865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (a[1] == 0.0 && a[3] == 0.0) 1027865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = 1.0; 1028865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else 1029865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = EXPF(a[3] * LOGF(a[1])); 1030865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1031865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 1032865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = 0.0; 1033865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1034865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = 1.0F; 1035865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1036865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1037865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", 1038865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], result[1], result[2], result[3], 1039865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0], a[1], a[2], a[3]); 1040865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1041865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1042865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1043865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_LRP: 1044865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1045865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], c[4], result[4]; 1046865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1047865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1048865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); 1049865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0]; 1050865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1]; 1051865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; 1052865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; 1053865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1054865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1055865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("LRP (%g %g %g %g) = (%g %g %g %g), " 1056865f88afc0d59d886fb2ad50429e584ecf17fa81Brian "(%g %g %g %g), (%g %g %g %g)\n", 1057865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], result[1], result[2], result[3], 1058865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0], a[1], a[2], a[3], 1059865f88afc0d59d886fb2ad50429e584ecf17fa81Brian b[0], b[1], b[2], b[3], 1060865f88afc0d59d886fb2ad50429e584ecf17fa81Brian c[0], c[1], c[2], c[3]); 1061865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1062865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1063865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1064865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_MAD: 1065865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1066865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], c[4], result[4]; 1067865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1068865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1069865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); 1070865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = a[0] * b[0] + c[0]; 1071865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[1] * b[1] + c[1]; 1072865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[2] * b[2] + c[2]; 1073865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = a[3] * b[3] + c[3]; 1074865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1075865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1076865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("MAD (%g %g %g %g) = (%g %g %g %g) * " 1077865f88afc0d59d886fb2ad50429e584ecf17fa81Brian "(%g %g %g %g) + (%g %g %g %g)\n", 1078865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], result[1], result[2], result[3], 1079865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0], a[1], a[2], a[3], 1080865f88afc0d59d886fb2ad50429e584ecf17fa81Brian b[0], b[1], b[2], b[3], 1081865f88afc0d59d886fb2ad50429e584ecf17fa81Brian c[0], c[1], c[2], c[3]); 1082865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1083865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1084865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1085865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_MAX: 1086865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1087865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1088865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1089865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1090865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = MAX2(a[0], b[0]); 1091865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = MAX2(a[1], b[1]); 1092865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = MAX2(a[2], b[2]); 1093865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = MAX2(a[3], b[3]); 1094865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1095865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1096865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", 1097865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], result[1], result[2], result[3], 1098865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0], a[1], a[2], a[3], 1099865f88afc0d59d886fb2ad50429e584ecf17fa81Brian b[0], b[1], b[2], b[3]); 1100865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1101865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1102865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1103865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_MIN: 1104865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1105865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1106865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1107865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1108865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = MIN2(a[0], b[0]); 1109865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = MIN2(a[1], b[1]); 1110865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = MIN2(a[2], b[2]); 1111865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = MIN2(a[3], b[3]); 1112865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1113865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1114865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1115865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_MOV: 1116865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1117865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat result[4]; 1118865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result ); 1119865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1120865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1121865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("MOV (%g %g %g %g)\n", 1122865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], result[1], result[2], result[3]); 1123865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1124865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1125865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1126865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_MUL: 1127865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1128865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1129865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1130865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1131865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = a[0] * b[0]; 1132865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[1] * b[1]; 1133865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[2] * b[2]; 1134865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = a[3] * b[3]; 1135865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1136865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1137865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", 1138865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], result[1], result[2], result[3], 1139865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0], a[1], a[2], a[3], 1140865f88afc0d59d886fb2ad50429e584ecf17fa81Brian b[0], b[1], b[2], b[3]); 1141865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1142865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1143865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 11447aece10039ad4786d7f85d61ec8614b9f287ea23Brian case OPCODE_NOISE1: 11457aece10039ad4786d7f85d61ec8614b9f287ea23Brian { 11467aece10039ad4786d7f85d61ec8614b9f287ea23Brian GLfloat a[4], result[4]; 11477aece10039ad4786d7f85d61ec8614b9f287ea23Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 11487aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[0] = 11497aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[1] = 11507aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[2] = 11517aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[3] = _slang_library_noise1(a[0]); 11527aece10039ad4786d7f85d61ec8614b9f287ea23Brian store_vector4( inst, machine, result ); 11537aece10039ad4786d7f85d61ec8614b9f287ea23Brian } 11547aece10039ad4786d7f85d61ec8614b9f287ea23Brian break; 11557aece10039ad4786d7f85d61ec8614b9f287ea23Brian case OPCODE_NOISE2: 11567aece10039ad4786d7f85d61ec8614b9f287ea23Brian { 11577aece10039ad4786d7f85d61ec8614b9f287ea23Brian GLfloat a[4], result[4]; 11587aece10039ad4786d7f85d61ec8614b9f287ea23Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 11597aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[0] = 11607aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[1] = 11617aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[2] = 11627aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[3] = _slang_library_noise2(a[0], a[1]); 11637aece10039ad4786d7f85d61ec8614b9f287ea23Brian store_vector4( inst, machine, result ); 11647aece10039ad4786d7f85d61ec8614b9f287ea23Brian } 11657aece10039ad4786d7f85d61ec8614b9f287ea23Brian break; 11667aece10039ad4786d7f85d61ec8614b9f287ea23Brian case OPCODE_NOISE3: 11677aece10039ad4786d7f85d61ec8614b9f287ea23Brian { 11687aece10039ad4786d7f85d61ec8614b9f287ea23Brian GLfloat a[4], result[4]; 11697aece10039ad4786d7f85d61ec8614b9f287ea23Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 11707aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[0] = 11717aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[1] = 11727aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[2] = 11737aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[3] = _slang_library_noise3(a[0], a[1], a[2]); 11747aece10039ad4786d7f85d61ec8614b9f287ea23Brian store_vector4( inst, machine, result ); 11757aece10039ad4786d7f85d61ec8614b9f287ea23Brian } 11767aece10039ad4786d7f85d61ec8614b9f287ea23Brian break; 11777aece10039ad4786d7f85d61ec8614b9f287ea23Brian case OPCODE_NOISE4: 11787aece10039ad4786d7f85d61ec8614b9f287ea23Brian { 11797aece10039ad4786d7f85d61ec8614b9f287ea23Brian GLfloat a[4], result[4]; 11807aece10039ad4786d7f85d61ec8614b9f287ea23Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 11817aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[0] = 11827aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[1] = 11837aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[2] = 11847aece10039ad4786d7f85d61ec8614b9f287ea23Brian result[3] = _slang_library_noise4(a[0], a[1], a[2], a[3]); 11857aece10039ad4786d7f85d61ec8614b9f287ea23Brian store_vector4( inst, machine, result ); 11867aece10039ad4786d7f85d61ec8614b9f287ea23Brian } 11877aece10039ad4786d7f85d61ec8614b9f287ea23Brian break; 11880031ea7d85ae8990872c2181d038fb97b566dc2bBrian case OPCODE_NOP: 11890031ea7d85ae8990872c2181d038fb97b566dc2bBrian break; 1190865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ 1191865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1192865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1193865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLhalfNV hx, hy; 1194865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint *rawResult = (GLuint *) result; 1195865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint twoHalves; 1196865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1197865f88afc0d59d886fb2ad50429e584ecf17fa81Brian hx = _mesa_float_to_half(a[0]); 1198865f88afc0d59d886fb2ad50429e584ecf17fa81Brian hy = _mesa_float_to_half(a[1]); 1199865f88afc0d59d886fb2ad50429e584ecf17fa81Brian twoHalves = hx | (hy << 16); 1200865f88afc0d59d886fb2ad50429e584ecf17fa81Brian rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] 1201865f88afc0d59d886fb2ad50429e584ecf17fa81Brian = twoHalves; 1202865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1203865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1204865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1205865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ 1206865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1207865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1208865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint usx, usy, *rawResult = (GLuint *) result; 1209865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1210865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0] = CLAMP(a[0], 0.0F, 1.0F); 1211865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[1] = CLAMP(a[1], 0.0F, 1.0F); 1212865f88afc0d59d886fb2ad50429e584ecf17fa81Brian usx = IROUND(a[0] * 65535.0F); 1213865f88afc0d59d886fb2ad50429e584ecf17fa81Brian usy = IROUND(a[1] * 65535.0F); 1214865f88afc0d59d886fb2ad50429e584ecf17fa81Brian rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] 1215865f88afc0d59d886fb2ad50429e584ecf17fa81Brian = usx | (usy << 16); 1216865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1217865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1218865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1219865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ 1220865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1221865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1222865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; 1223865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1224865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F); 1225865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); 1226865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); 1227865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); 1228865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ubx = IROUND(127.0F * a[0] + 128.0F); 1229865f88afc0d59d886fb2ad50429e584ecf17fa81Brian uby = IROUND(127.0F * a[1] + 128.0F); 1230865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ubz = IROUND(127.0F * a[2] + 128.0F); 1231865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ubw = IROUND(127.0F * a[3] + 128.0F); 1232865f88afc0d59d886fb2ad50429e584ecf17fa81Brian rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] 1233865f88afc0d59d886fb2ad50429e584ecf17fa81Brian = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); 1234865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1235865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1236865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1237865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ 1238865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1239865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1240865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; 1241865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1242865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0] = CLAMP(a[0], 0.0F, 1.0F); 1243865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[1] = CLAMP(a[1], 0.0F, 1.0F); 1244865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[2] = CLAMP(a[2], 0.0F, 1.0F); 1245865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[3] = CLAMP(a[3], 0.0F, 1.0F); 1246865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ubx = IROUND(255.0F * a[0]); 1247865f88afc0d59d886fb2ad50429e584ecf17fa81Brian uby = IROUND(255.0F * a[1]); 1248865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ubz = IROUND(255.0F * a[2]); 1249865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ubw = IROUND(255.0F * a[3]); 1250865f88afc0d59d886fb2ad50429e584ecf17fa81Brian rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] 1251865f88afc0d59d886fb2ad50429e584ecf17fa81Brian = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); 1252865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1253865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1254865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1255865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_POW: 1256865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1257865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1258865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1259865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[1], machine, program, b ); 1260865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] 1261865f88afc0d59d886fb2ad50429e584ecf17fa81Brian = (GLfloat)_mesa_pow(a[0], b[0]); 1262865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1263865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1264865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1265865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_RCP: 1266865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1267865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1268865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1269865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1270865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (a[0] == 0) 1271865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("RCP(0)\n"); 1272865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else if (IS_INF_OR_NAN(a[0])) 1273865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("RCP(inf)\n"); 1274865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1275865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; 1276865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1277865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1278865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1279865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_RET: /* return from subroutine */ 1280865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1281865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* NOTE: The return is conditional! */ 1282865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint swizzle = inst->DstReg.CondSwizzle; 1283865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint condMask = inst->DstReg.CondMask; 1284865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || 1285865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || 1286865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || 1287865f88afc0d59d886fb2ad50429e584ecf17fa81Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { 1288865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (machine->StackDepth == 0) { 1289865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ 1290865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1291865f88afc0d59d886fb2ad50429e584ecf17fa81Brian pc = machine->CallStack[--machine->StackDepth]; 1292865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1293865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1294865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1295865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_RFL: /* reflection vector */ 1296865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1297865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat axis[4], dir[4], result[4], tmpX, tmpW; 1298865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, axis ); 1299865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dir ); 1300865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tmpW = DOT3(axis, axis); 1301865f88afc0d59d886fb2ad50429e584ecf17fa81Brian tmpX = (2.0F * DOT3(axis, dir)) / tmpW; 1302865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = tmpX * axis[0] - dir[0]; 1303865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = tmpX * axis[1] - dir[1]; 1304865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = tmpX * axis[2] - dir[2]; 1305865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* result[3] is never written! XXX enforce in parser! */ 1306865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1307865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1308865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1309865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_RSQ: /* 1 / sqrt() */ 1310865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1311865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1312865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1313865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0] = FABSF(a[0]); 1314865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); 1315865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1316865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1317865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); 1318865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1319865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1320865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1321865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SCS: /* sine and cos */ 1322865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1323865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1324865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1325223d7cb3c785ad58c869a3ee0fbf2f1d42c3310dBrian result[0] = (GLfloat) _mesa_cos(a[0]); 1326223d7cb3c785ad58c869a3ee0fbf2f1d42c3310dBrian result[1] = (GLfloat) _mesa_sin(a[0]); 1327865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = 0.0; /* undefined! */ 1328865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = 0.0; /* undefined! */ 1329865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1330865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1331865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1332865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SEQ: /* set on equal */ 1333865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1334865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1335865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1336865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1337865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = (a[0] == b[0]) ? 1.0F : 0.0F; 1338865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = (a[1] == b[1]) ? 1.0F : 0.0F; 1339865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = (a[2] == b[2]) ? 1.0F : 0.0F; 1340865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = (a[3] == b[3]) ? 1.0F : 0.0F; 1341865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1342865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1343865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1344865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SFL: /* set false, operands ignored */ 1345865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1346865f88afc0d59d886fb2ad50429e584ecf17fa81Brian static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; 1347865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1348865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1349865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1350865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SGE: /* set on greater or equal */ 1351865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1352865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1353865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1354865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1355865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F; 1356865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F; 1357865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F; 1358865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F; 1359865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1360865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1361865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1362865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SGT: /* set on greater */ 1363865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1364865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1365865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1366865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1367865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = (a[0] > b[0]) ? 1.0F : 0.0F; 1368865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = (a[1] > b[1]) ? 1.0F : 0.0F; 1369865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = (a[2] > b[2]) ? 1.0F : 0.0F; 1370865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = (a[3] > b[3]) ? 1.0F : 0.0F; 1371865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1372865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1373865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1374865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SIN: 1375865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1376865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1377865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1378865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[1] = result[2] = result[3] 1379865f88afc0d59d886fb2ad50429e584ecf17fa81Brian = (GLfloat) _mesa_sin(a[0]); 1380865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1381865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1382865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1383865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SLE: /* set on less or equal */ 1384865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1385865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1386865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1387865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1388865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F; 1389865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F; 1390865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F; 1391865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F; 1392865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1393865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1394865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1395865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SLT: /* set on less */ 1396865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1397865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1398865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1399865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1400865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = (a[0] < b[0]) ? 1.0F : 0.0F; 1401865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = (a[1] < b[1]) ? 1.0F : 0.0F; 1402865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = (a[2] < b[2]) ? 1.0F : 0.0F; 1403865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = (a[3] < b[3]) ? 1.0F : 0.0F; 1404865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1405865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1406865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1407865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SNE: /* set on not equal */ 1408865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1409865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1410865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1411865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1412865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = (a[0] != b[0]) ? 1.0F : 0.0F; 1413865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = (a[1] != b[1]) ? 1.0F : 0.0F; 1414865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = (a[2] != b[2]) ? 1.0F : 0.0F; 1415865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = (a[3] != b[3]) ? 1.0F : 0.0F; 1416865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1417865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1418865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1419865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_STR: /* set true, operands ignored */ 1420865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1421865f88afc0d59d886fb2ad50429e584ecf17fa81Brian static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F }; 1422865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1423865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1424865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1425865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SUB: 1426865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1427865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1428865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1429865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1430865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = a[0] - b[0]; 1431865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[1] - b[1]; 1432865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[2] - b[2]; 1433865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = a[3] - b[3]; 1434865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1435865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1436865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", 1437865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0], result[1], result[2], result[3], 1438865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); 1439865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1440865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1441865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1442865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_SWZ: /* extended swizzle */ 1443865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1444865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct prog_src_register *source = &inst->SrcReg[0]; 1445865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat *src = get_register_pointer(ctx, source, 1446865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine, program); 1447865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat result[4]; 1448865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint i; 1449865f88afc0d59d886fb2ad50429e584ecf17fa81Brian for (i = 0; i < 4; i++) { 1450865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint swz = GET_SWZ(source->Swizzle, i); 1451865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (swz == SWIZZLE_ZERO) 1452865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[i] = 0.0; 1453865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else if (swz == SWIZZLE_ONE) 1454865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[i] = 1.0; 1455865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 1456865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(swz >= 0); 1457865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(swz <= 3); 1458865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[i] = src[swz]; 1459865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1460865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (source->NegateBase & (1 << i)) 1461865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[i] = -result[i]; 1462865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1463865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1464865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1465865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1466865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_TEX: /* Both ARB and NV frag prog */ 1467865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Texel lookup */ 1468865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1469865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Note: only use the precomputed lambda value when we're 1470865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * sampling texture unit [K] with texcoord[K]. 1471865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Otherwise, the lambda value may have no relation to the 1472865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * instruction's texcoord or texture image. Using the wrong 1473865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * lambda is usually bad news. 1474865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * The rest of the time, just use zero (until we get a more 1475865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * sophisticated way of computing lambda). 1476865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 1477865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat coord[4], color[4], lambda; 1478865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (inst->SrcReg[0].File == PROGRAM_INPUT && 1479865f88afc0d59d886fb2ad50429e584ecf17fa81Brian inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) 1480865f88afc0d59d886fb2ad50429e584ecf17fa81Brian lambda = span->array->lambda[inst->TexSrcUnit][column]; 1481865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else 1482865f88afc0d59d886fb2ad50429e584ecf17fa81Brian lambda = 0.0; 1483865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); 1484865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_texel( ctx, coord, lambda, inst->TexSrcUnit, color ); 1485865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (DEBUG_FRAG) { 1486865f88afc0d59d886fb2ad50429e584ecf17fa81Brian printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], " 1487865f88afc0d59d886fb2ad50429e584ecf17fa81Brian "lod %f\n", 1488865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color[0], color[1], color[2], color[3], 1489865f88afc0d59d886fb2ad50429e584ecf17fa81Brian inst->TexSrcUnit, 1490865f88afc0d59d886fb2ad50429e584ecf17fa81Brian coord[0], coord[1], coord[2], coord[3], lambda); 1491865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1492865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, color ); 1493865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1494865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1495865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_TXB: /* GL_ARB_fragment_program only */ 1496865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Texel lookup with LOD bias */ 1497865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 149841a4e828d9e06e42bba78166975cb283674c0d9fBrian const struct gl_texture_unit *texUnit 149941a4e828d9e06e42bba78166975cb283674c0d9fBrian = &ctx->Texture.Unit[inst->TexSrcUnit]; 1500865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat coord[4], color[4], lambda, bias; 1501865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (inst->SrcReg[0].File == PROGRAM_INPUT && 1502865f88afc0d59d886fb2ad50429e584ecf17fa81Brian inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) 1503865f88afc0d59d886fb2ad50429e584ecf17fa81Brian lambda = span->array->lambda[inst->TexSrcUnit][column]; 1504865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else 1505865f88afc0d59d886fb2ad50429e584ecf17fa81Brian lambda = 0.0; 1506865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); 1507865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* coord[3] is the bias to add to lambda */ 150841a4e828d9e06e42bba78166975cb283674c0d9fBrian bias = texUnit->LodBias + coord[3]; 150941a4e828d9e06e42bba78166975cb283674c0d9fBrian if (texUnit->_Current) 151041a4e828d9e06e42bba78166975cb283674c0d9fBrian bias += texUnit->_Current->LodBias; 1511865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_texel(ctx, coord, lambda + bias, inst->TexSrcUnit, color); 1512865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, color ); 1513865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1514865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1515865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_TXD: /* GL_NV_fragment_program only */ 1516865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Texture lookup w/ partial derivatives for LOD */ 1517865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1518865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat texcoord[4], dtdx[4], dtdy[4], color[4]; 1519865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); 1520865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dtdx ); 1521865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[2], machine, program, dtdy ); 1522865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit, 1523865f88afc0d59d886fb2ad50429e584ecf17fa81Brian color ); 1524865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, color ); 1525865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1526865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1527865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_TXP: /* GL_ARB_fragment_program only */ 1528865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Texture lookup w/ projective divide */ 1529865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1530865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat texcoord[4], color[4], lambda; 1531865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (inst->SrcReg[0].File == PROGRAM_INPUT && 1532865f88afc0d59d886fb2ad50429e584ecf17fa81Brian inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) 1533865f88afc0d59d886fb2ad50429e584ecf17fa81Brian lambda = span->array->lambda[inst->TexSrcUnit][column]; 1534865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else 1535865f88afc0d59d886fb2ad50429e584ecf17fa81Brian lambda = 0.0; 1536865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); 1537865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Not so sure about this test - if texcoord[3] is 1538865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * zero, we'd probably be fine except for an ASSERT in 1539865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * IROUND_POS() which gets triggered by the inf values created. 1540865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 1541865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (texcoord[3] != 0.0) { 1542865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texcoord[0] /= texcoord[3]; 1543865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texcoord[1] /= texcoord[3]; 1544865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texcoord[2] /= texcoord[3]; 1545865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1546865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); 1547865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, color ); 1548865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1549865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1550865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ 1551865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Texture lookup w/ projective divide */ 1552865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1553865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat texcoord[4], color[4], lambda; 1554865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (inst->SrcReg[0].File == PROGRAM_INPUT && 1555865f88afc0d59d886fb2ad50429e584ecf17fa81Brian inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) 1556865f88afc0d59d886fb2ad50429e584ecf17fa81Brian lambda = span->array->lambda[inst->TexSrcUnit][column]; 1557865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else 1558865f88afc0d59d886fb2ad50429e584ecf17fa81Brian lambda = 0.0; 1559865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); 1560865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && 1561865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texcoord[3] != 0.0) { 1562865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texcoord[0] /= texcoord[3]; 1563865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texcoord[1] /= texcoord[3]; 1564865f88afc0d59d886fb2ad50429e584ecf17fa81Brian texcoord[2] /= texcoord[3]; 1565865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1566865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); 1567865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, color ); 1568865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1569865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1570865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_UP2H: /* unpack two 16-bit floats */ 1571865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1572865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1573865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint *rawBits = (const GLuint *) a; 1574865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLhalfNV hx, hy; 1575865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1576865f88afc0d59d886fb2ad50429e584ecf17fa81Brian hx = rawBits[0] & 0xffff; 1577865f88afc0d59d886fb2ad50429e584ecf17fa81Brian hy = rawBits[0] >> 16; 1578865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[2] = _mesa_half_to_float(hx); 1579865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = result[3] = _mesa_half_to_float(hy); 1580865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1581865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1582865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1583865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_UP2US: /* unpack two GLushorts */ 1584865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1585865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1586865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint *rawBits = (const GLuint *) a; 1587865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLushort usx, usy; 1588865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1589865f88afc0d59d886fb2ad50429e584ecf17fa81Brian usx = rawBits[0] & 0xffff; 1590865f88afc0d59d886fb2ad50429e584ecf17fa81Brian usy = rawBits[0] >> 16; 1591865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = result[2] = usx * (1.0f / 65535.0f); 1592865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = result[3] = usy * (1.0f / 65535.0f); 1593865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1594865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1595865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1596865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_UP4B: /* unpack four GLbytes */ 1597865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1598865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1599865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint *rawBits = (const GLuint *) a; 1600865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1601865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F; 1602865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F; 1603865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F; 1604865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F; 1605865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1606865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1607865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1608865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_UP4UB: /* unpack four GLubytes */ 1609865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1610865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], result[4]; 1611865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLuint *rawBits = (const GLuint *) a; 1612865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); 1613865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F; 1614865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F; 1615865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F; 1616865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F; 1617865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1618865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1619865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1620865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_XPD: /* cross product */ 1621865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1622865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], result[4]; 1623865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1624865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1625865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = a[1] * b[2] - a[2] * b[1]; 1626865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[2] * b[0] - a[0] * b[2]; 1627865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[0] * b[1] - a[1] * b[0]; 1628865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = 1.0; 1629865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1630865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1631865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1632865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_X2D: /* 2-D matrix transform */ 1633865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1634865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4], b[4], c[4], result[4]; 1635865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); 1636865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); 1637865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); 1638865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[0] = a[0] + b[0] * c[0] + b[1] * c[1]; 1639865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[1] = a[1] + b[0] * c[2] + b[1] * c[3]; 1640865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[2] = a[2] + b[0] * c[0] + b[1] * c[1]; 1641865f88afc0d59d886fb2ad50429e584ecf17fa81Brian result[3] = a[3] + b[0] * c[2] + b[1] * c[3]; 1642865f88afc0d59d886fb2ad50429e584ecf17fa81Brian store_vector4( inst, machine, result ); 1643865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1644865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1645865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_PRINT: 1646865f88afc0d59d886fb2ad50429e584ecf17fa81Brian { 1647865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (inst->SrcReg[0].File != -1) { 1648865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLfloat a[4]; 1649865f88afc0d59d886fb2ad50429e584ecf17fa81Brian fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); 1650865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, 1651865f88afc0d59d886fb2ad50429e584ecf17fa81Brian a[0], a[1], a[2], a[3]); 1652865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1653865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 1654865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_printf("%s\n", (const char *) inst->Data); 1655865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1656865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1657865f88afc0d59d886fb2ad50429e584ecf17fa81Brian break; 1658865f88afc0d59d886fb2ad50429e584ecf17fa81Brian case OPCODE_END: 1659865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return GL_TRUE; 1660865f88afc0d59d886fb2ad50429e584ecf17fa81Brian default: 1661865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program", 1662865f88afc0d59d886fb2ad50429e584ecf17fa81Brian inst->Opcode); 1663865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return GL_TRUE; /* return value doesn't matter */ 1664d22079217c5a1954a07afb1193d06eecb2decbb6Brian 1665d22079217c5a1954a07afb1193d06eecb2decbb6Brian } 1666d22079217c5a1954a07afb1193d06eecb2decbb6Brian total++; 1667d22079217c5a1954a07afb1193d06eecb2decbb6Brian if (total > MAX_EXEC) { 1668d22079217c5a1954a07afb1193d06eecb2decbb6Brian _mesa_problem(ctx, "Infinite loop detected in fragment program"); 1669f673b24017b8b5e850a1be5c04bd28cefa811329Brian return GL_TRUE; 1670d22079217c5a1954a07afb1193d06eecb2decbb6Brian abort(); 1671865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1672865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1673865f88afc0d59d886fb2ad50429e584ecf17fa81Brian return GL_TRUE; 1674865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 1675865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1676865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1677865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 1678865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Initialize the virtual fragment program machine state prior to running 1679865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * fragment program on a fragment. This involves initializing the input 1680865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * registers, condition codes, etc. 1681865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \param machine the virtual machine state to init 1682865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \param program the fragment program we're about to run 1683865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \param span the span of pixels we'll operate on 1684865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * \param col which element (column) of the span we'll operate on 1685865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 1686865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic void 1687865f88afc0d59d886fb2ad50429e584ecf17fa81Brianinit_machine( GLcontext *ctx, struct fp_machine *machine, 1688865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_fragment_program *program, 1689865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const SWspan *span, GLuint col ) 1690865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 1691865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint inputsRead = program->Base.InputsRead; 1692865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1693865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (ctx->FragmentProgram.CallbackEnabled) 1694865f88afc0d59d886fb2ad50429e584ecf17fa81Brian inputsRead = ~0; 1695865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1696865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { 1697865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Clear temporary registers (undefined for ARB_f_p) */ 1698865f88afc0d59d886fb2ad50429e584ecf17fa81Brian _mesa_bzero(machine->Temporaries, 1699865f88afc0d59d886fb2ad50429e584ecf17fa81Brian MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); 1700865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1701865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1702f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian /* Setup pointer to input attributes */ 1703f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian machine->Attribs = span->array->attribs; 1704f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian machine->CurFrag = col; 1705865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1706865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* init condition codes */ 1707865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->CondCodes[0] = COND_EQ; 1708865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->CondCodes[1] = COND_EQ; 1709865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->CondCodes[2] = COND_EQ; 1710865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->CondCodes[3] = COND_EQ; 1711865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1712865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* init call stack */ 1713865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine->StackDepth = 0; 1714865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 1715865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1716865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1717865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 1718865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Run fragment program on the pixels in span from 'start' to 'end' - 1. 1719865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 1720865f88afc0d59d886fb2ad50429e584ecf17fa81Brianstatic void 1721865f88afc0d59d886fb2ad50429e584ecf17fa81Brianrun_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) 1722865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 1723865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_fragment_program *program = ctx->FragmentProgram._Current; 1724865f88afc0d59d886fb2ad50429e584ecf17fa81Brian struct fp_machine machine; 1725865f88afc0d59d886fb2ad50429e584ecf17fa81Brian GLuint i; 1726865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1727865f88afc0d59d886fb2ad50429e584ecf17fa81Brian CurrentMachine = &machine; 1728865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1729865f88afc0d59d886fb2ad50429e584ecf17fa81Brian for (i = start; i < end; i++) { 1730865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (span->array->mask[i]) { 1731865f88afc0d59d886fb2ad50429e584ecf17fa81Brian init_machine(ctx, &machine, program, span, i); 1732865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1733865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (execute_program(ctx, program, ~0, &machine, span, i)) { 1734865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Store result color */ 1735f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], 1736865f88afc0d59d886fb2ad50429e584ecf17fa81Brian machine.Outputs[FRAG_RESULT_COLR]); 1737865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1738865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* Store result depth/z */ 1739865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { 1740865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2]; 1741865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (depth <= 0.0) 1742865f88afc0d59d886fb2ad50429e584ecf17fa81Brian span->array->z[i] = 0; 1743865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else if (depth >= 1.0) 1744865f88afc0d59d886fb2ad50429e584ecf17fa81Brian span->array->z[i] = ctx->DrawBuffer->_DepthMax; 1745865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else 1746865f88afc0d59d886fb2ad50429e584ecf17fa81Brian span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF); 1747865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1748865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1749865f88afc0d59d886fb2ad50429e584ecf17fa81Brian else { 1750865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* killed fragment */ 1751865f88afc0d59d886fb2ad50429e584ecf17fa81Brian span->array->mask[i] = GL_FALSE; 1752865f88afc0d59d886fb2ad50429e584ecf17fa81Brian span->writeAll = GL_FALSE; 1753865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1754865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1755865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1756865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1757865f88afc0d59d886fb2ad50429e584ecf17fa81Brian CurrentMachine = NULL; 1758865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 1759865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1760865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1761865f88afc0d59d886fb2ad50429e584ecf17fa81Brian/** 1762865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * Execute the current fragment program for all the fragments 1763865f88afc0d59d886fb2ad50429e584ecf17fa81Brian * in the given span. 1764865f88afc0d59d886fb2ad50429e584ecf17fa81Brian */ 1765865f88afc0d59d886fb2ad50429e584ecf17fa81Brianvoid 1766865f88afc0d59d886fb2ad50429e584ecf17fa81Brian_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) 1767865f88afc0d59d886fb2ad50429e584ecf17fa81Brian{ 1768865f88afc0d59d886fb2ad50429e584ecf17fa81Brian const struct gl_fragment_program *program = ctx->FragmentProgram._Current; 1769865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1770865f88afc0d59d886fb2ad50429e584ecf17fa81Brian /* incoming colors should be floats */ 1771865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ASSERT(span->array->ChanType == GL_FLOAT); 1772865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1773865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ 1774865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1775865f88afc0d59d886fb2ad50429e584ecf17fa81Brian run_program(ctx, span, 0, span->end); 1776865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1777865f88afc0d59d886fb2ad50429e584ecf17fa81Brian if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { 1778865f88afc0d59d886fb2ad50429e584ecf17fa81Brian span->interpMask &= ~SPAN_Z; 1779865f88afc0d59d886fb2ad50429e584ecf17fa81Brian span->arrayMask |= SPAN_Z; 1780865f88afc0d59d886fb2ad50429e584ecf17fa81Brian } 1781865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1782865f88afc0d59d886fb2ad50429e584ecf17fa81Brian ctx->_CurrentProgram = 0; 1783865f88afc0d59d886fb2ad50429e584ecf17fa81Brian} 1784865f88afc0d59d886fb2ad50429e584ecf17fa81Brian 1785