113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/* 213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Mesa 3-D graphics library 3f4361540f8dd3016571523863b33481cba7a0c07Brian Paul * Version: 7.3 413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * 5f4361540f8dd3016571523863b33481cba7a0c07Brian Paul * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * 713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Permission is hereby granted, free of charge, to any person obtaining a 813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * copy of this software and associated documentation files (the "Software"), 913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * to deal in the Software without restriction, including without limitation 1013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * and/or sell copies of the Software, and to permit persons to whom the 1213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Software is furnished to do so, subject to the following conditions: 1313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * 1413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * The above copyright notice and this permission notice shall be included 1513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * in all copies or substantial portions of the Software. 1613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * 1713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 2413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 2513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 2613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * \file prog_execute.c 2713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Software interpreter for vertex/fragment programs. 2813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * \author Brian Paul 2913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 3013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 3113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/* 3213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * NOTE: we do everything in single-precision floating point; we don't 3313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * currently observe the single/half/fixed-precision qualifiers. 3413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * 3513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 3613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 3713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 38bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 39bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h" 403fdd9fa556e9ba48244cb2b3966d3bfb0b84731bVinson Lee#include "main/macros.h" 4113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian#include "prog_execute.h" 4213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian#include "prog_instruction.h" 4313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian#include "prog_parameter.h" 4413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian#include "prog_print.h" 45702b5b076b7591560e7e701e0c9ff2eeb30fa966Brian Paul#include "prog_noise.h" 4613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 4713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 4813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/* debug predicate */ 4913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian#define DEBUG_PROG 0 5013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 5113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 52f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian/** 53f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian * Set x to positive or negative infinity. 54f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian */ 55f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#if defined(USE_IEEE) || defined(_WIN32) 5672362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger#define SET_POS_INFINITY(x) \ 5772362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger do { \ 5872362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger fi_type fi; \ 5972362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger fi.i = 0x7F800000; \ 6072362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger x = fi.f; \ 6172362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger } while (0) 6272362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger#define SET_NEG_INFINITY(x) \ 6372362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger do { \ 6472362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger fi_type fi; \ 6572362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger fi.i = 0xFF800000; \ 6672362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger x = fi.f; \ 6772362a5cd41d97b770980c28fe6719c556f12ab7Roland Scheidegger } while (0) 68f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#elif defined(VMS) 69f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#define SET_POS_INFINITY(x) x = __MAXFLOAT 70f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#define SET_NEG_INFINITY(x) x = -__MAXFLOAT 71f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#else 72f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#define SET_POS_INFINITY(x) x = (GLfloat) HUGE_VAL 73f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL 74f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#endif 75f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian 76f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits 77f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian 78f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian 79f183a2d7ea31a4fea89af834dc19c5b232eb1970Brianstatic const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; 80f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian 81f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian 82f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian 8313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 84b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul * Return TRUE for +0 and other positive values, FALSE otherwise. 85b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul * Used for RCC opcode. 86b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul */ 879520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLboolean 88b4ad7c28430e4084d843cd99cf68209e95363963Brian Paulpositive(float x) 89b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul{ 90b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul fi_type fi; 91b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul fi.f = x; 92b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul if (fi.i & 0x80000000) 93b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul return GL_FALSE; 94b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul return GL_TRUE; 95b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul} 96b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul 97b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul 98b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul 99b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul/** 10013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Return a pointer to the 4-element float vector specified by the given 10113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * source register. 10213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 1039520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline const GLfloat * 104f4361540f8dd3016571523863b33481cba7a0c07Brian Paulget_src_register_pointer(const struct prog_src_register *source, 105f4361540f8dd3016571523863b33481cba7a0c07Brian Paul const struct gl_program_machine *machine) 10613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian{ 107f4361540f8dd3016571523863b33481cba7a0c07Brian Paul const struct gl_program *prog = machine->CurProgram; 108f4361540f8dd3016571523863b33481cba7a0c07Brian Paul GLint reg = source->Index; 109f4361540f8dd3016571523863b33481cba7a0c07Brian Paul 110f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian if (source->RelAddr) { 111f4361540f8dd3016571523863b33481cba7a0c07Brian Paul /* add address register value to src index/offset */ 112f4361540f8dd3016571523863b33481cba7a0c07Brian Paul reg += machine->AddressReg[0][0]; 113f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg < 0) { 114f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return ZeroVec; 115f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 116f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 117f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian 11813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian switch (source->File) { 11913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case PROGRAM_TEMPORARY: 120f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg >= MAX_PROGRAM_TEMPS) 121f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return ZeroVec; 122f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return machine->Temporaries[reg]; 12313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 12413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case PROGRAM_INPUT: 125f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (prog->Target == GL_VERTEX_PROGRAM_ARB) { 126f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg >= VERT_ATTRIB_MAX) 127f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return ZeroVec; 128f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return machine->VertAttribs[reg]; 12913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 13013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian else { 131f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg >= FRAG_ATTRIB_MAX) 132f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return ZeroVec; 133f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return machine->Attribs[reg][machine->CurElement]; 13413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 13513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 13613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case PROGRAM_OUTPUT: 137f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg >= MAX_PROGRAM_OUTPUTS) 138f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return ZeroVec; 139f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return machine->Outputs[reg]; 14013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 14113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case PROGRAM_LOCAL_PARAM: 142f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg >= MAX_PROGRAM_LOCAL_PARAMS) 143f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return ZeroVec; 144f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return machine->CurProgram->LocalParams[reg]; 14513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 14613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case PROGRAM_ENV_PARAM: 147f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg >= MAX_PROGRAM_ENV_PARAMS) 148f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return ZeroVec; 149f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return machine->EnvParams[reg]; 15013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 15113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case PROGRAM_STATE_VAR: 15213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian /* Fallthrough */ 15313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case PROGRAM_CONSTANT: 15413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian /* Fallthrough */ 15513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case PROGRAM_UNIFORM: 15613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian /* Fallthrough */ 15713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case PROGRAM_NAMED_PARAM: 158f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg >= (GLint) prog->Parameters->NumParameters) 159f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return ZeroVec; 1606d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain return (GLfloat *) prog->Parameters->ParameterValues[reg]; 161f4361540f8dd3016571523863b33481cba7a0c07Brian Paul 1626a0d3b7696260f449a1d0c5222814568764e8110Brian Paul case PROGRAM_SYSTEM_VALUE: 1636a0d3b7696260f449a1d0c5222814568764e8110Brian Paul assert(reg < Elements(machine->SystemValues)); 1646a0d3b7696260f449a1d0c5222814568764e8110Brian Paul return machine->SystemValues[reg]; 1656a0d3b7696260f449a1d0c5222814568764e8110Brian Paul 166f4361540f8dd3016571523863b33481cba7a0c07Brian Paul default: 167f4361540f8dd3016571523863b33481cba7a0c07Brian Paul _mesa_problem(NULL, 168f4361540f8dd3016571523863b33481cba7a0c07Brian Paul "Invalid src register file %d in get_src_register_pointer()", 169f4361540f8dd3016571523863b33481cba7a0c07Brian Paul source->File); 170f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return NULL; 171f4361540f8dd3016571523863b33481cba7a0c07Brian Paul } 172f4361540f8dd3016571523863b33481cba7a0c07Brian Paul} 173f4361540f8dd3016571523863b33481cba7a0c07Brian Paul 174f4361540f8dd3016571523863b33481cba7a0c07Brian Paul 175f4361540f8dd3016571523863b33481cba7a0c07Brian Paul/** 176f4361540f8dd3016571523863b33481cba7a0c07Brian Paul * Return a pointer to the 4-element float vector specified by the given 177f4361540f8dd3016571523863b33481cba7a0c07Brian Paul * destination register. 178f4361540f8dd3016571523863b33481cba7a0c07Brian Paul */ 1799520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat * 180f4361540f8dd3016571523863b33481cba7a0c07Brian Paulget_dst_register_pointer(const struct prog_dst_register *dest, 181f4361540f8dd3016571523863b33481cba7a0c07Brian Paul struct gl_program_machine *machine) 182f4361540f8dd3016571523863b33481cba7a0c07Brian Paul{ 183f4361540f8dd3016571523863b33481cba7a0c07Brian Paul static GLfloat dummyReg[4]; 184f4361540f8dd3016571523863b33481cba7a0c07Brian Paul GLint reg = dest->Index; 185f4361540f8dd3016571523863b33481cba7a0c07Brian Paul 186f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (dest->RelAddr) { 187f4361540f8dd3016571523863b33481cba7a0c07Brian Paul /* add address register value to src index/offset */ 188f4361540f8dd3016571523863b33481cba7a0c07Brian Paul reg += machine->AddressReg[0][0]; 189f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg < 0) { 190f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return dummyReg; 191f4361540f8dd3016571523863b33481cba7a0c07Brian Paul } 192f4361540f8dd3016571523863b33481cba7a0c07Brian Paul } 193f4361540f8dd3016571523863b33481cba7a0c07Brian Paul 194f4361540f8dd3016571523863b33481cba7a0c07Brian Paul switch (dest->File) { 195f4361540f8dd3016571523863b33481cba7a0c07Brian Paul case PROGRAM_TEMPORARY: 196f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg >= MAX_PROGRAM_TEMPS) 197f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return dummyReg; 198f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return machine->Temporaries[reg]; 199f4361540f8dd3016571523863b33481cba7a0c07Brian Paul 200f4361540f8dd3016571523863b33481cba7a0c07Brian Paul case PROGRAM_OUTPUT: 201f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (reg >= MAX_PROGRAM_OUTPUTS) 202f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return dummyReg; 203f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return machine->Outputs[reg]; 204f4361540f8dd3016571523863b33481cba7a0c07Brian Paul 205f4361540f8dd3016571523863b33481cba7a0c07Brian Paul case PROGRAM_WRITE_ONLY: 206f4361540f8dd3016571523863b33481cba7a0c07Brian Paul return dummyReg; 20713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 20813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian default: 20933eac56e4a48143aa8acd5757feb68570e860de5Brian _mesa_problem(NULL, 210f4361540f8dd3016571523863b33481cba7a0c07Brian Paul "Invalid dest register file %d in get_dst_register_pointer()", 211f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dest->File); 21213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian return NULL; 21313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 21413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian} 21513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 21613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 217f4361540f8dd3016571523863b33481cba7a0c07Brian Paul 21813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 21913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Fetch a 4-element float vector from the given source register. 22013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Apply swizzling and negating as needed. 22113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 22213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brianstatic void 22333eac56e4a48143aa8acd5757feb68570e860de5Brianfetch_vector4(const struct prog_src_register *source, 224e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian const struct gl_program_machine *machine, GLfloat result[4]) 22513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian{ 226f4361540f8dd3016571523863b33481cba7a0c07Brian Paul const GLfloat *src = get_src_register_pointer(source, machine); 22713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian ASSERT(src); 22813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 22913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (source->Swizzle == SWIZZLE_NOOP) { 23013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian /* no swizzling */ 23113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian COPY_4V(result, src); 23213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 23313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian else { 23413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian ASSERT(GET_SWZ(source->Swizzle, 0) <= 3); 23513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian ASSERT(GET_SWZ(source->Swizzle, 1) <= 3); 23613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian ASSERT(GET_SWZ(source->Swizzle, 2) <= 3); 23713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian ASSERT(GET_SWZ(source->Swizzle, 3) <= 3); 23813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[0] = src[GET_SWZ(source->Swizzle, 0)]; 23913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[1] = src[GET_SWZ(source->Swizzle, 1)]; 24013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[2] = src[GET_SWZ(source->Swizzle, 2)]; 24113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[3] = src[GET_SWZ(source->Swizzle, 3)]; 24213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 24313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 24413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (source->Abs) { 24513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[0] = FABSF(result[0]); 24613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[1] = FABSF(result[1]); 24713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[2] = FABSF(result[2]); 24813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[3] = FABSF(result[3]); 24913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 2507db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul if (source->Negate) { 2517db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul ASSERT(source->Negate == NEGATE_XYZW); 25213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[0] = -result[0]; 25313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[1] = -result[1]; 25413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[2] = -result[2]; 25513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[3] = -result[3]; 25613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 25792009543705918760df92abb0cbb8cad68875e72Brian Paul 25892009543705918760df92abb0cbb8cad68875e72Brian Paul#ifdef NAN_CHECK 25992009543705918760df92abb0cbb8cad68875e72Brian Paul assert(!IS_INF_OR_NAN(result[0])); 26092009543705918760df92abb0cbb8cad68875e72Brian Paul assert(!IS_INF_OR_NAN(result[0])); 26192009543705918760df92abb0cbb8cad68875e72Brian Paul assert(!IS_INF_OR_NAN(result[0])); 26292009543705918760df92abb0cbb8cad68875e72Brian Paul assert(!IS_INF_OR_NAN(result[0])); 26392009543705918760df92abb0cbb8cad68875e72Brian Paul#endif 26413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian} 26513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 26662da6a1b3e341e53981e2817595e0eea107fe6cbBrian 26713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 26837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul * Fetch a 4-element uint vector from the given source register. 26937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul * Apply swizzling but not negation/abs. 27037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul */ 27137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paulstatic void 27237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paulfetch_vector4ui(const struct prog_src_register *source, 27337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul const struct gl_program_machine *machine, GLuint result[4]) 27437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul{ 275f4361540f8dd3016571523863b33481cba7a0c07Brian Paul const GLuint *src = (GLuint *) get_src_register_pointer(source, machine); 27637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul ASSERT(src); 27737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 27837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (source->Swizzle == SWIZZLE_NOOP) { 27937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul /* no swizzling */ 28037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul COPY_4V(result, src); 28137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 28237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul else { 28337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul ASSERT(GET_SWZ(source->Swizzle, 0) <= 3); 28437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul ASSERT(GET_SWZ(source->Swizzle, 1) <= 3); 28537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul ASSERT(GET_SWZ(source->Swizzle, 2) <= 3); 28637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul ASSERT(GET_SWZ(source->Swizzle, 3) <= 3); 28737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[0] = src[GET_SWZ(source->Swizzle, 0)]; 28837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[1] = src[GET_SWZ(source->Swizzle, 1)]; 28937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[2] = src[GET_SWZ(source->Swizzle, 2)]; 29037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[3] = src[GET_SWZ(source->Swizzle, 3)]; 29137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 29237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 2937db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul /* Note: no Negate or Abs here */ 29437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul} 29537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 29637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 29737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 29837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul/** 29962da6a1b3e341e53981e2817595e0eea107fe6cbBrian * Fetch the derivative with respect to X or Y for the given register. 30062da6a1b3e341e53981e2817595e0eea107fe6cbBrian * XXX this currently only works for fragment program input attribs. 30113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 30262da6a1b3e341e53981e2817595e0eea107fe6cbBrianstatic void 303f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergfetch_vector4_deriv(struct gl_context * ctx, 304e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian const struct prog_src_register *source, 30562da6a1b3e341e53981e2817595e0eea107fe6cbBrian const struct gl_program_machine *machine, 30662da6a1b3e341e53981e2817595e0eea107fe6cbBrian char xOrY, GLfloat result[4]) 30713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian{ 30837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (source->File == PROGRAM_INPUT && 30937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul source->Index < (GLint) machine->NumDeriv) { 31062da6a1b3e341e53981e2817595e0eea107fe6cbBrian const GLint col = machine->CurElement; 31162da6a1b3e341e53981e2817595e0eea107fe6cbBrian const GLfloat w = machine->Attribs[FRAG_ATTRIB_WPOS][col][3]; 31262da6a1b3e341e53981e2817595e0eea107fe6cbBrian const GLfloat invQ = 1.0f / w; 31362da6a1b3e341e53981e2817595e0eea107fe6cbBrian GLfloat deriv[4]; 31413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 31513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (xOrY == 'X') { 31662da6a1b3e341e53981e2817595e0eea107fe6cbBrian deriv[0] = machine->DerivX[source->Index][0] * invQ; 31762da6a1b3e341e53981e2817595e0eea107fe6cbBrian deriv[1] = machine->DerivX[source->Index][1] * invQ; 31862da6a1b3e341e53981e2817595e0eea107fe6cbBrian deriv[2] = machine->DerivX[source->Index][2] * invQ; 31962da6a1b3e341e53981e2817595e0eea107fe6cbBrian deriv[3] = machine->DerivX[source->Index][3] * invQ; 32013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 32113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian else { 32262da6a1b3e341e53981e2817595e0eea107fe6cbBrian deriv[0] = machine->DerivY[source->Index][0] * invQ; 32362da6a1b3e341e53981e2817595e0eea107fe6cbBrian deriv[1] = machine->DerivY[source->Index][1] * invQ; 32462da6a1b3e341e53981e2817595e0eea107fe6cbBrian deriv[2] = machine->DerivY[source->Index][2] * invQ; 32562da6a1b3e341e53981e2817595e0eea107fe6cbBrian deriv[3] = machine->DerivY[source->Index][3] * invQ; 32613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 32762da6a1b3e341e53981e2817595e0eea107fe6cbBrian 32862da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[0] = deriv[GET_SWZ(source->Swizzle, 0)]; 32962da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[1] = deriv[GET_SWZ(source->Swizzle, 1)]; 33062da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[2] = deriv[GET_SWZ(source->Swizzle, 2)]; 33162da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[3] = deriv[GET_SWZ(source->Swizzle, 3)]; 33262da6a1b3e341e53981e2817595e0eea107fe6cbBrian 33362da6a1b3e341e53981e2817595e0eea107fe6cbBrian if (source->Abs) { 33462da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[0] = FABSF(result[0]); 33562da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[1] = FABSF(result[1]); 33662da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[2] = FABSF(result[2]); 33762da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[3] = FABSF(result[3]); 33813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 3397db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul if (source->Negate) { 3407db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul ASSERT(source->Negate == NEGATE_XYZW); 34162da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[0] = -result[0]; 34262da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[1] = -result[1]; 34362da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[2] = -result[2]; 34462da6a1b3e341e53981e2817595e0eea107fe6cbBrian result[3] = -result[3]; 34513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 34613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 34762da6a1b3e341e53981e2817595e0eea107fe6cbBrian else { 34862da6a1b3e341e53981e2817595e0eea107fe6cbBrian ASSIGN_4V(result, 0.0, 0.0, 0.0, 0.0); 34913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 35013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian} 35113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 35213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 35313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 35413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * As above, but only return result[0] element. 35513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 35613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brianstatic void 35733eac56e4a48143aa8acd5757feb68570e860de5Brianfetch_vector1(const struct prog_src_register *source, 358e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian const struct gl_program_machine *machine, GLfloat result[4]) 35913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian{ 360f4361540f8dd3016571523863b33481cba7a0c07Brian Paul const GLfloat *src = get_src_register_pointer(source, machine); 36113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian ASSERT(src); 36213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 36313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[0] = src[GET_SWZ(source->Swizzle, 0)]; 36413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 36513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (source->Abs) { 36613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[0] = FABSF(result[0]); 36713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 3687db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul if (source->Negate) { 36913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[0] = -result[0]; 37013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 37113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian} 37213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 37313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 3748d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paulstatic GLuint 3758d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paulfetch_vector1ui(const struct prog_src_register *source, 3768d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul const struct gl_program_machine *machine) 3778d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul{ 3788d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul const GLuint *src = (GLuint *) get_src_register_pointer(source, machine); 379984b72ad5f47cda8e141dc38524f6a0598dcc541Brian Paul return src[GET_SWZ(source->Swizzle, 0)]; 3808d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul} 3818d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul 3828d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul 38313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 384999b55663a09d9669a9d14c5aadfa84e6dcba288Brian * Fetch texel from texture. Use partial derivatives when possible. 385999b55663a09d9669a9d14c5aadfa84e6dcba288Brian */ 3869520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 387f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergfetch_texel(struct gl_context *ctx, 388999b55663a09d9669a9d14c5aadfa84e6dcba288Brian const struct gl_program_machine *machine, 389999b55663a09d9669a9d14c5aadfa84e6dcba288Brian const struct prog_instruction *inst, 390999b55663a09d9669a9d14c5aadfa84e6dcba288Brian const GLfloat texcoord[4], GLfloat lodBias, 391999b55663a09d9669a9d14c5aadfa84e6dcba288Brian GLfloat color[4]) 392999b55663a09d9669a9d14c5aadfa84e6dcba288Brian{ 393ade508312c701ce89d3c2cd717994dbbabb4f207Brian Paul const GLuint unit = machine->Samplers[inst->TexSrcUnit]; 394ade508312c701ce89d3c2cd717994dbbabb4f207Brian Paul 395999b55663a09d9669a9d14c5aadfa84e6dcba288Brian /* Note: we only have the right derivatives for fragment input attribs. 396999b55663a09d9669a9d14c5aadfa84e6dcba288Brian */ 397999b55663a09d9669a9d14c5aadfa84e6dcba288Brian if (machine->NumDeriv > 0 && 398999b55663a09d9669a9d14c5aadfa84e6dcba288Brian inst->SrcReg[0].File == PROGRAM_INPUT && 399999b55663a09d9669a9d14c5aadfa84e6dcba288Brian inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) { 400999b55663a09d9669a9d14c5aadfa84e6dcba288Brian /* simple texture fetch for which we should have derivatives */ 401999b55663a09d9669a9d14c5aadfa84e6dcba288Brian GLuint attr = inst->SrcReg[0].Index; 402999b55663a09d9669a9d14c5aadfa84e6dcba288Brian machine->FetchTexelDeriv(ctx, texcoord, 403999b55663a09d9669a9d14c5aadfa84e6dcba288Brian machine->DerivX[attr], 404999b55663a09d9669a9d14c5aadfa84e6dcba288Brian machine->DerivY[attr], 405ade508312c701ce89d3c2cd717994dbbabb4f207Brian Paul lodBias, unit, color); 406999b55663a09d9669a9d14c5aadfa84e6dcba288Brian } 407999b55663a09d9669a9d14c5aadfa84e6dcba288Brian else { 408ade508312c701ce89d3c2cd717994dbbabb4f207Brian Paul machine->FetchTexelLod(ctx, texcoord, lodBias, unit, color); 409999b55663a09d9669a9d14c5aadfa84e6dcba288Brian } 410999b55663a09d9669a9d14c5aadfa84e6dcba288Brian} 411999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 412999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 413999b55663a09d9669a9d14c5aadfa84e6dcba288Brian/** 41413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Test value against zero and return GT, LT, EQ or UN if NaN. 41513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 4169520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLuint 417e80d901d9854b7c24a71fcd5a3377c33f408c8c0Briangenerate_cc(float value) 41813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian{ 41913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (value != value) 420e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian return COND_UN; /* NaN */ 42113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (value > 0.0F) 42213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian return COND_GT; 42313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (value < 0.0F) 42413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian return COND_LT; 42513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian return COND_EQ; 42613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian} 42713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 42813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 42913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 43013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Test if the ccMaskRule is satisfied by the given condition code. 43113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Used to mask destination writes according to the current condition code. 43213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 4339520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLboolean 43413e3b21b16b14112b416f3ee5742fc7bd1b2d823Briantest_cc(GLuint condCode, GLuint ccMaskRule) 43513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian{ 43613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian switch (ccMaskRule) { 43713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case COND_EQ: return (condCode == COND_EQ); 43813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case COND_NE: return (condCode != COND_EQ); 43913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case COND_LT: return (condCode == COND_LT); 44013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case COND_GE: return (condCode == COND_GT || condCode == COND_EQ); 44113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case COND_LE: return (condCode == COND_LT || condCode == COND_EQ); 44213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case COND_GT: return (condCode == COND_GT); 44313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case COND_TR: return GL_TRUE; 44413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian case COND_FL: return GL_FALSE; 44513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian default: return GL_TRUE; 44613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 44713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian} 44813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 44913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 45013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 45113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Evaluate the 4 condition codes against a predicate and return GL_TRUE 45213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * or GL_FALSE to indicate result. 45313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 4549520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLboolean 45513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brianeval_condition(const struct gl_program_machine *machine, 45613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian const struct prog_instruction *inst) 45713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian{ 45813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian const GLuint swizzle = inst->DstReg.CondSwizzle; 45913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian const GLuint condMask = inst->DstReg.CondMask; 46013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || 46113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || 46213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || 46313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { 46413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian return GL_TRUE; 46513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 46613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian else { 46713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian return GL_FALSE; 46813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 46913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian} 47013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 47113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 47213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 47313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 47413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Store 4 floats into a register. Observe the instructions saturate and 47513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * set-condition-code flags. 47613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 47713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brianstatic void 478e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brianstore_vector4(const struct prog_instruction *inst, 479e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian struct gl_program_machine *machine, const GLfloat value[4]) 48013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian{ 481f4361540f8dd3016571523863b33481cba7a0c07Brian Paul const struct prog_dst_register *dstReg = &(inst->DstReg); 48213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE; 483f4361540f8dd3016571523863b33481cba7a0c07Brian Paul GLuint writeMask = dstReg->WriteMask; 48413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian GLfloat clampedValue[4]; 485f4361540f8dd3016571523863b33481cba7a0c07Brian Paul GLfloat *dst = get_dst_register_pointer(dstReg, machine); 48613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 48713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian#if 0 48813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (value[0] > 1.0e10 || 48913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian IS_INF_OR_NAN(value[0]) || 49013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian IS_INF_OR_NAN(value[1]) || 491e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian IS_INF_OR_NAN(value[2]) || IS_INF_OR_NAN(value[3])) 49213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]); 49313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian#endif 49413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 49513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (clamp) { 49613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F); 49713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F); 49813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F); 49913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F); 50013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian value = clampedValue; 50113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 50213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 503f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (dstReg->CondMask != COND_TR) { 50413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian /* condition codes may turn off some writes */ 50513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_X) { 506f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)], 507f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dstReg->CondMask)) 50813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian writeMask &= ~WRITEMASK_X; 50913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 51013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_Y) { 511f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)], 512f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dstReg->CondMask)) 51313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian writeMask &= ~WRITEMASK_Y; 51413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 51513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_Z) { 516f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)], 517f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dstReg->CondMask)) 51813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian writeMask &= ~WRITEMASK_Z; 51913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 52013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_W) { 521f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)], 522f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dstReg->CondMask)) 52313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian writeMask &= ~WRITEMASK_W; 52413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 52513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 52613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 52792009543705918760df92abb0cbb8cad68875e72Brian Paul#ifdef NAN_CHECK 52892009543705918760df92abb0cbb8cad68875e72Brian Paul assert(!IS_INF_OR_NAN(value[0])); 52992009543705918760df92abb0cbb8cad68875e72Brian Paul assert(!IS_INF_OR_NAN(value[0])); 53092009543705918760df92abb0cbb8cad68875e72Brian Paul assert(!IS_INF_OR_NAN(value[0])); 53192009543705918760df92abb0cbb8cad68875e72Brian Paul assert(!IS_INF_OR_NAN(value[0])); 53292009543705918760df92abb0cbb8cad68875e72Brian Paul#endif 53392009543705918760df92abb0cbb8cad68875e72Brian Paul 53413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_X) 535f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dst[0] = value[0]; 53613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_Y) 537f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dst[1] = value[1]; 53813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_Z) 539f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dst[2] = value[2]; 54013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_W) 541f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dst[3] = value[3]; 54213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 54313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (inst->CondUpdate) { 54413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_X) 54513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian machine->CondCodes[0] = generate_cc(value[0]); 54613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_Y) 54713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian machine->CondCodes[1] = generate_cc(value[1]); 54813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_Z) 54913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian machine->CondCodes[2] = generate_cc(value[2]); 55013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (writeMask & WRITEMASK_W) 55113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian machine->CondCodes[3] = generate_cc(value[3]); 552a01616eed52aa4dfe3b6850b76a4cd8de119a3f3Brian#if DEBUG_PROG 553a01616eed52aa4dfe3b6850b76a4cd8de119a3f3Brian printf("CondCodes=(%s,%s,%s,%s) for:\n", 554a01616eed52aa4dfe3b6850b76a4cd8de119a3f3Brian _mesa_condcode_string(machine->CondCodes[0]), 555a01616eed52aa4dfe3b6850b76a4cd8de119a3f3Brian _mesa_condcode_string(machine->CondCodes[1]), 556a01616eed52aa4dfe3b6850b76a4cd8de119a3f3Brian _mesa_condcode_string(machine->CondCodes[2]), 557a01616eed52aa4dfe3b6850b76a4cd8de119a3f3Brian _mesa_condcode_string(machine->CondCodes[3])); 558a01616eed52aa4dfe3b6850b76a4cd8de119a3f3Brian#endif 55913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 56013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian} 56113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 56213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 56313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian/** 56437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul * Store 4 uints into a register. Observe the set-condition-code flags. 56537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul */ 56637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paulstatic void 56737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paulstore_vector4ui(const struct prog_instruction *inst, 56837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul struct gl_program_machine *machine, const GLuint value[4]) 56937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul{ 570f4361540f8dd3016571523863b33481cba7a0c07Brian Paul const struct prog_dst_register *dstReg = &(inst->DstReg); 571f4361540f8dd3016571523863b33481cba7a0c07Brian Paul GLuint writeMask = dstReg->WriteMask; 572f4361540f8dd3016571523863b33481cba7a0c07Brian Paul GLuint *dst = (GLuint *) get_dst_register_pointer(dstReg, machine); 57337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 574f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (dstReg->CondMask != COND_TR) { 57537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul /* condition codes may turn off some writes */ 57637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_X) { 577f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)], 578f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dstReg->CondMask)) 57937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul writeMask &= ~WRITEMASK_X; 58037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 58137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_Y) { 582f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)], 583f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dstReg->CondMask)) 58437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul writeMask &= ~WRITEMASK_Y; 58537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 58637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_Z) { 587f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)], 588f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dstReg->CondMask)) 58937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul writeMask &= ~WRITEMASK_Z; 59037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 59137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_W) { 592f4361540f8dd3016571523863b33481cba7a0c07Brian Paul if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)], 593f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dstReg->CondMask)) 59437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul writeMask &= ~WRITEMASK_W; 59537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 59637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 59737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 59837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_X) 599f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dst[0] = value[0]; 60037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_Y) 601f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dst[1] = value[1]; 60237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_Z) 603f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dst[2] = value[2]; 60437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_W) 605f4361540f8dd3016571523863b33481cba7a0c07Brian Paul dst[3] = value[3]; 60637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 60737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (inst->CondUpdate) { 60837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_X) 609b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz machine->CondCodes[0] = generate_cc((float)value[0]); 61037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_Y) 611b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz machine->CondCodes[1] = generate_cc((float)value[1]); 61237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_Z) 613b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz machine->CondCodes[2] = generate_cc((float)value[2]); 61437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul if (writeMask & WRITEMASK_W) 615b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz machine->CondCodes[3] = generate_cc((float)value[3]); 61637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul#if DEBUG_PROG 61737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul printf("CondCodes=(%s,%s,%s,%s) for:\n", 61837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul _mesa_condcode_string(machine->CondCodes[0]), 61937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul _mesa_condcode_string(machine->CondCodes[1]), 62037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul _mesa_condcode_string(machine->CondCodes[2]), 62137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul _mesa_condcode_string(machine->CondCodes[3])); 62237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul#endif 62337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 62437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul} 62537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 62637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 62737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul 62837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul/** 62913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * Execute the given vertex/fragment program. 63013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * 6313c1c999226859216b8af35c4806413b4488f21b4Brian * \param ctx rendering context 6323c1c999226859216b8af35c4806413b4488f21b4Brian * \param program the program to execute 6333c1c999226859216b8af35c4806413b4488f21b4Brian * \param machine machine state (must be initialized) 63413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. 63513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian */ 63613e3b21b16b14112b416f3ee5742fc7bd1b2d823BrianGLboolean 637f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_execute_program(struct gl_context * ctx, 6388b34b7da4131d2b07037ce062c522fddd614f127Brian const struct gl_program *program, 639085d7d59f0e167bb546c4a1675e09631b14fc9f7Brian struct gl_program_machine *machine) 64013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian{ 6418b34b7da4131d2b07037ce062c522fddd614f127Brian const GLuint numInst = program->NumInstructions; 6427125f1e87df359be4aad1d801b633146eeac7292Ian Romanick const GLuint maxExec = 65536; 643452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca GLuint pc, numExec = 0; 64413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 64513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian machine->CurProgram = program; 64613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 64713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (DEBUG_PROG) { 64813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian printf("execute program %u --------------------\n", program->Id); 64913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 65013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 65133eac56e4a48143aa8acd5757feb68570e860de5Brian if (program->Target == GL_VERTEX_PROGRAM_ARB) { 65233eac56e4a48143aa8acd5757feb68570e860de5Brian machine->EnvParams = ctx->VertexProgram.Parameters; 65333eac56e4a48143aa8acd5757feb68570e860de5Brian } 65433eac56e4a48143aa8acd5757feb68570e860de5Brian else { 65533eac56e4a48143aa8acd5757feb68570e860de5Brian machine->EnvParams = ctx->FragmentProgram.Parameters; 65633eac56e4a48143aa8acd5757feb68570e860de5Brian } 65733eac56e4a48143aa8acd5757feb68570e860de5Brian 6588b34b7da4131d2b07037ce062c522fddd614f127Brian for (pc = 0; pc < numInst; pc++) { 65913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian const struct prog_instruction *inst = program->Instructions + pc; 66013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 66113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian if (DEBUG_PROG) { 66213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian _mesa_print_instruction(inst); 66313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 66413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 66513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian switch (inst->Opcode) { 666e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_ABS: 667e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 668e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 66933eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 670e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = FABSF(a[0]); 671e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = FABSF(a[1]); 672e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = FABSF(a[2]); 673e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = FABSF(a[3]); 674e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 675e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 676e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 677e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_ADD: 678e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 679e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 68033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 68133eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 682e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = a[0] + b[0]; 683e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[1] + b[1]; 684e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[2] + b[2]; 685e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = a[3] + b[3]; 686e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 687e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 688e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", 689e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], result[1], result[2], result[3], 690e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); 69113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 692e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 693e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 69437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul case OPCODE_AND: /* bitwise AND */ 69537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul { 69637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLuint a[4], b[4], result[4]; 69737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul fetch_vector4ui(&inst->SrcReg[0], machine, a); 69837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul fetch_vector4ui(&inst->SrcReg[1], machine, b); 69937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[0] = a[0] & b[0]; 70037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[1] = a[1] & b[1]; 70137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[2] = a[2] & b[2]; 70237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[3] = a[3] & b[3]; 70337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul store_vector4ui(inst, machine, result); 70437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 70537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul break; 706f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian case OPCODE_ARL: 707f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian { 708f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian GLfloat t[4]; 70933eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, t); 710a9475cc240984aab5d9cc5868aa3f6c1b206be94Brian Paul machine->AddressReg[0][0] = IFLOOR(t[0]); 711a636f5b4d064dccf658f00d152ae9aeaa3751e64Brian Paul if (DEBUG_PROG) { 712a636f5b4d064dccf658f00d152ae9aeaa3751e64Brian Paul printf("ARL %d\n", machine->AddressReg[0][0]); 713a636f5b4d064dccf658f00d152ae9aeaa3751e64Brian Paul } 714f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 715f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian break; 716e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_BGNLOOP: 717e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* no-op */ 718e8ea2d26cd9e90d45cdfb94c3a6b06e27d6c0083Brian Paul ASSERT(program->Instructions[inst->BranchTarget].Opcode 719e8ea2d26cd9e90d45cdfb94c3a6b06e27d6c0083Brian Paul == OPCODE_ENDLOOP); 720e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 721e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_ENDLOOP: 722e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* subtract 1 here since pc is incremented by for(pc) loop */ 723e8ea2d26cd9e90d45cdfb94c3a6b06e27d6c0083Brian Paul ASSERT(program->Instructions[inst->BranchTarget].Opcode 724e8ea2d26cd9e90d45cdfb94c3a6b06e27d6c0083Brian Paul == OPCODE_BGNLOOP); 725e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ 726e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 727e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_BGNSUB: /* begin subroutine */ 728e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 729e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_ENDSUB: /* end subroutine */ 730e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 731e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_BRA: /* branch (conditional) */ 732db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul if (eval_condition(machine, inst)) { 733db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul /* take branch */ 734db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul /* Subtract 1 here since we'll do pc++ below */ 735db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul pc = inst->BranchTarget - 1; 736db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul } 737db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul break; 738e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_BRK: /* break out of loop (conditional) */ 739db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul ASSERT(program->Instructions[inst->BranchTarget].Opcode 740db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul == OPCODE_ENDLOOP); 741db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul if (eval_condition(machine, inst)) { 742db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul /* break out of loop */ 743db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul /* pc++ at end of for-loop will put us after the ENDLOOP inst */ 744db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul pc = inst->BranchTarget; 745db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul } 746db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul break; 747e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_CONT: /* continue loop (conditional) */ 748db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul ASSERT(program->Instructions[inst->BranchTarget].Opcode 749db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul == OPCODE_ENDLOOP); 750e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (eval_condition(machine, inst)) { 751db721151b76611b75bcedfc90221ef5f92e8edebBrian Paul /* continue at ENDLOOP */ 752e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* Subtract 1 here since we'll do pc++ at end of for-loop */ 753e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian pc = inst->BranchTarget - 1; 754e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 755e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 756e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_CAL: /* Call subroutine (conditional) */ 757e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (eval_condition(machine, inst)) { 758e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* call the subroutine */ 759e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { 760e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ 761e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 762a0275b0d2c071ed8254c2af3a0c53eec9d3561a6Brian machine->CallStack[machine->StackDepth++] = pc + 1; /* next inst */ 76331dc7a3c890a831f9a0d20dc394ddbe854a05718Brian /* Subtract 1 here since we'll do pc++ at end of for-loop */ 76431dc7a3c890a831f9a0d20dc394ddbe854a05718Brian pc = inst->BranchTarget - 1; 765e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 766e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 767e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_CMP: 768e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 769e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], c[4], result[4]; 77033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 77133eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 77233eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[2], machine, c); 773e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = a[0] < 0.0F ? b[0] : c[0]; 774e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[1] < 0.0F ? b[1] : c[1]; 775e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[2] < 0.0F ? b[2] : c[2]; 776e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = a[3] < 0.0F ? b[3] : c[3]; 777e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 778fd7f2ae085ea55649089b29515e143eed43c177eBrian Paul if (DEBUG_PROG) { 779fd7f2ae085ea55649089b29515e143eed43c177eBrian Paul printf("CMP (%g %g %g %g) = (%g %g %g %g) < 0 ? (%g %g %g %g) : (%g %g %g %g)\n", 780fd7f2ae085ea55649089b29515e143eed43c177eBrian Paul result[0], result[1], result[2], result[3], 781fd7f2ae085ea55649089b29515e143eed43c177eBrian Paul a[0], a[1], a[2], a[3], 782fd7f2ae085ea55649089b29515e143eed43c177eBrian Paul b[0], b[1], b[2], b[3], 783fd7f2ae085ea55649089b29515e143eed43c177eBrian Paul c[0], c[1], c[2], c[3]); 784fd7f2ae085ea55649089b29515e143eed43c177eBrian Paul } 785e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 786e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 787e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_COS: 788e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 789e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 79033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, a); 791e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = result[1] = result[2] = result[3] 792165694ad65374ff4330bd80acb398fe0428ba2e6Eric Anholt = (GLfloat) cos(a[0]); 793e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 794e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 795e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 796e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_DDX: /* Partial derivative with respect to X */ 797e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 79862da6a1b3e341e53981e2817595e0eea107fe6cbBrian GLfloat result[4]; 79962da6a1b3e341e53981e2817595e0eea107fe6cbBrian fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine, 80062da6a1b3e341e53981e2817595e0eea107fe6cbBrian 'X', result); 801e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 802e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 803e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 804e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_DDY: /* Partial derivative with respect to Y */ 805e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 80662da6a1b3e341e53981e2817595e0eea107fe6cbBrian GLfloat result[4]; 80762da6a1b3e341e53981e2817595e0eea107fe6cbBrian fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine, 80862da6a1b3e341e53981e2817595e0eea107fe6cbBrian 'Y', result); 809e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 810e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 811e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 81265cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul case OPCODE_DP2: 81365cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul { 81465cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul GLfloat a[4], b[4], result[4]; 81565cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul fetch_vector4(&inst->SrcReg[0], machine, a); 81665cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul fetch_vector4(&inst->SrcReg[1], machine, b); 81765cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul result[0] = result[1] = result[2] = result[3] = DOT2(a, b); 81865cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul store_vector4(inst, machine, result); 81965cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul if (DEBUG_PROG) { 82065cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul printf("DP2 %g = (%g %g) . (%g %g)\n", 82165cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul result[0], a[0], a[1], b[0], b[1]); 82265cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul } 82365cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul } 82465cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul break; 82565cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul case OPCODE_DP2A: 82665cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul { 82765cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul GLfloat a[4], b[4], c, result[4]; 82865cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul fetch_vector4(&inst->SrcReg[0], machine, a); 82965cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul fetch_vector4(&inst->SrcReg[1], machine, b); 83065cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul fetch_vector1(&inst->SrcReg[1], machine, &c); 83165cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul result[0] = result[1] = result[2] = result[3] = DOT2(a, b) + c; 83265cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul store_vector4(inst, machine, result); 83365cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul if (DEBUG_PROG) { 83465cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul printf("DP2A %g = (%g %g) . (%g %g) + %g\n", 83565cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul result[0], a[0], a[1], b[0], b[1], c); 83665cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul } 83765cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul } 83865cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul break; 839e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_DP3: 840e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 841e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 84233eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 84333eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 844e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = result[1] = result[2] = result[3] = DOT3(a, b); 845e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 846e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 847e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", 848e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], a[0], a[1], a[2], b[0], b[1], b[2]); 84913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 850e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 851e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 852e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_DP4: 853e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 854e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 85533eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 85633eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 857e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = result[1] = result[2] = result[3] = DOT4(a, b); 858e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 859e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 860e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", 861e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], a[0], a[1], a[2], a[3], 862e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian b[0], b[1], b[2], b[3]); 86313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 864e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 865e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 866e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_DPH: 867e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 868e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 86933eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 87033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 87165cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul result[0] = result[1] = result[2] = result[3] = DOT3(a, b) + b[3]; 872e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 873e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 874e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 875e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_DST: /* Distance vector */ 876e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 877e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 87833eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 87933eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 880e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = 1.0F; 881e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[1] * b[1]; 882e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[2]; 883e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = b[3]; 884e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 885e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 886e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 887f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian case OPCODE_EXP: 888f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian { 889f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian GLfloat t[4], q[4], floor_t0; 89033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, t); 891f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian floor_t0 = FLOORF(t[0]); 892f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian if (floor_t0 > FLT_MAX_EXP) { 893f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian SET_POS_INFINITY(q[0]); 894f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian SET_POS_INFINITY(q[2]); 895f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 896f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian else if (floor_t0 < FLT_MIN_EXP) { 897f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian q[0] = 0.0F; 898f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian q[2] = 0.0F; 899f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 900f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian else { 901761728afe8b81fc0ff7928f99f8b5668a0a7824dBrian q[0] = LDEXPF(1.0, (int) floor_t0); 902761728afe8b81fc0ff7928f99f8b5668a0a7824dBrian /* Note: GL_NV_vertex_program expects 903761728afe8b81fc0ff7928f99f8b5668a0a7824dBrian * result.z = result.x * APPX(result.y) 904761728afe8b81fc0ff7928f99f8b5668a0a7824dBrian * We do what the ARB extension says. 905761728afe8b81fc0ff7928f99f8b5668a0a7824dBrian */ 906fef303bc94f2fb15a068563ac8abfb1765bde035Eric Anholt q[2] = (GLfloat) pow(2.0, t[0]); 907f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 908f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian q[1] = t[0] - floor_t0; 909f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian q[3] = 1.0F; 910f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian store_vector4( inst, machine, q ); 911f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 912f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian break; 913e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_EX2: /* Exponential base 2 */ 914e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 915035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul GLfloat a[4], result[4], val; 91633eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, a); 917fef303bc94f2fb15a068563ac8abfb1765bde035Eric Anholt val = (GLfloat) pow(2.0, a[0]); 918035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul /* 919035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul if (IS_INF_OR_NAN(val)) 920035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul val = 1.0e10; 921035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul */ 922035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul result[0] = result[1] = result[2] = result[3] = val; 923e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 924e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 925e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 926e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_FLR: 927e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 928e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 92933eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 930e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = FLOORF(a[0]); 931e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = FLOORF(a[1]); 932e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = FLOORF(a[2]); 933e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = FLOORF(a[3]); 934e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 935e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 936e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 937e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_FRC: 938e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 939e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 94033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 941e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = a[0] - FLOORF(a[0]); 942e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[1] - FLOORF(a[1]); 943e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[2] - FLOORF(a[2]); 944e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = a[3] - FLOORF(a[3]); 945e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 946e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 947e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 948e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_IF: 94963556fa9949f543a8134b6b5ff3d216acb71dd9fBrian { 95063556fa9949f543a8134b6b5ff3d216acb71dd9fBrian GLboolean cond; 951ddd9729bc37f4b1098ef940da6e723743db3ded8Brian Paul ASSERT(program->Instructions[inst->BranchTarget].Opcode 952ddd9729bc37f4b1098ef940da6e723743db3ded8Brian Paul == OPCODE_ELSE || 953ddd9729bc37f4b1098ef940da6e723743db3ded8Brian Paul program->Instructions[inst->BranchTarget].Opcode 954ddd9729bc37f4b1098ef940da6e723743db3ded8Brian Paul == OPCODE_ENDIF); 95563556fa9949f543a8134b6b5ff3d216acb71dd9fBrian /* eval condition */ 95663556fa9949f543a8134b6b5ff3d216acb71dd9fBrian if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { 95763556fa9949f543a8134b6b5ff3d216acb71dd9fBrian GLfloat a[4]; 95863556fa9949f543a8134b6b5ff3d216acb71dd9fBrian fetch_vector1(&inst->SrcReg[0], machine, a); 95963556fa9949f543a8134b6b5ff3d216acb71dd9fBrian cond = (a[0] != 0.0); 96063556fa9949f543a8134b6b5ff3d216acb71dd9fBrian } 96163556fa9949f543a8134b6b5ff3d216acb71dd9fBrian else { 96263556fa9949f543a8134b6b5ff3d216acb71dd9fBrian cond = eval_condition(machine, inst); 96363556fa9949f543a8134b6b5ff3d216acb71dd9fBrian } 964a7f7366d382b2fe124f1495baf0360bffa30f0c0Brian if (DEBUG_PROG) { 965a7f7366d382b2fe124f1495baf0360bffa30f0c0Brian printf("IF: %d\n", cond); 966a7f7366d382b2fe124f1495baf0360bffa30f0c0Brian } 96763556fa9949f543a8134b6b5ff3d216acb71dd9fBrian /* do if/else */ 96863556fa9949f543a8134b6b5ff3d216acb71dd9fBrian if (cond) { 96963556fa9949f543a8134b6b5ff3d216acb71dd9fBrian /* do if-clause (just continue execution) */ 97063556fa9949f543a8134b6b5ff3d216acb71dd9fBrian } 97163556fa9949f543a8134b6b5ff3d216acb71dd9fBrian else { 97263556fa9949f543a8134b6b5ff3d216acb71dd9fBrian /* go to the instruction after ELSE or ENDIF */ 97363556fa9949f543a8134b6b5ff3d216acb71dd9fBrian assert(inst->BranchTarget >= 0); 974ddd9729bc37f4b1098ef940da6e723743db3ded8Brian Paul pc = inst->BranchTarget; 97563556fa9949f543a8134b6b5ff3d216acb71dd9fBrian } 976e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 977e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 978e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_ELSE: 979e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* goto ENDIF */ 980ddd9729bc37f4b1098ef940da6e723743db3ded8Brian Paul ASSERT(program->Instructions[inst->BranchTarget].Opcode 981ddd9729bc37f4b1098ef940da6e723743db3ded8Brian Paul == OPCODE_ENDIF); 982e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian assert(inst->BranchTarget >= 0); 983ddd9729bc37f4b1098ef940da6e723743db3ded8Brian Paul pc = inst->BranchTarget; 984e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 985e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_ENDIF: 986e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* nothing */ 987e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 988e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_KIL_NV: /* NV_f_p only (conditional) */ 989e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (eval_condition(machine, inst)) { 990e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian return GL_FALSE; 991e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 992e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 993e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_KIL: /* ARB_f_p only */ 994e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 995e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4]; 99633eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 997c0633ddabbcc91dcf06fd4452eb7516c624752c0Brian Paul if (DEBUG_PROG) { 998c0633ddabbcc91dcf06fd4452eb7516c624752c0Brian Paul printf("KIL if (%g %g %g %g) <= 0.0\n", 999c0633ddabbcc91dcf06fd4452eb7516c624752c0Brian Paul a[0], a[1], a[2], a[3]); 1000c0633ddabbcc91dcf06fd4452eb7516c624752c0Brian Paul } 1001c0633ddabbcc91dcf06fd4452eb7516c624752c0Brian Paul 1002e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) { 100313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian return GL_FALSE; 100413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1005e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1006e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1007e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_LG2: /* log base 2 */ 1008e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1009035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul GLfloat a[4], result[4], val; 101033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, a); 1011962fa6bbc16abf2b9829bd0b761d9baa9d01fd1eIan Romanick /* The fast LOG2 macro doesn't meet the precision requirements. 1012962fa6bbc16abf2b9829bd0b761d9baa9d01fd1eIan Romanick */ 1013035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul if (a[0] == 0.0F) { 101418883cdf2334511005973155fc517eb678dc0043Vinson Lee val = -FLT_MAX; 1015035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul } 1016035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul else { 1017b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz val = (float)(log(a[0]) * 1.442695F); 1018035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul } 1019035de6a82b6c911a81ca9c678aac59772eaff8d3Brian Paul result[0] = result[1] = result[2] = result[3] = val; 1020e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1021e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1022e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1023e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_LIT: 1024e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1025e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */ 1026e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 102733eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 1028e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0] = MAX2(a[0], 0.0F); 1029e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[1] = MAX2(a[1], 0.0F); 1030e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* XXX ARB version clamps a[3], NV version doesn't */ 1031e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon)); 1032e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = 1.0F; 1033e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[0]; 1034e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* XXX we could probably just use pow() here */ 1035e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (a[0] > 0.0F) { 1036e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (a[1] == 0.0 && a[3] == 0.0) 103720fbb24b67dda0679774756e4b6d98c2c66c2c42Brian Paul result[2] = 1.0F; 1038e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian else 1039fef303bc94f2fb15a068563ac8abfb1765bde035Eric Anholt result[2] = (GLfloat) pow(a[1], a[3]); 104013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1041e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian else { 104220fbb24b67dda0679774756e4b6d98c2c66c2c42Brian Paul result[2] = 0.0F; 104313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1044e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = 1.0F; 1045e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1046e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1047e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", 1048e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], result[1], result[2], result[3], 1049e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0], a[1], a[2], a[3]); 105013e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1051e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1052e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1053f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian case OPCODE_LOG: 1054f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian { 1055f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian GLfloat t[4], q[4], abs_t0; 105633eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, t); 1057f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian abs_t0 = FABSF(t[0]); 1058f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian if (abs_t0 != 0.0F) { 1059f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian /* Since we really can't handle infinite values on VMS 1060f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian * like other OSes we'll use __MAXFLOAT to represent 1061f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian * infinity. This may need some tweaking. 1062f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian */ 1063f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#ifdef VMS 1064f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian if (abs_t0 == __MAXFLOAT) 1065f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#else 1066f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian if (IS_INF_OR_NAN(abs_t0)) 1067f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian#endif 1068f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian { 1069f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian SET_POS_INFINITY(q[0]); 1070f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian q[1] = 1.0F; 1071f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian SET_POS_INFINITY(q[2]); 1072f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 1073f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian else { 1074f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian int exponent; 1075f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian GLfloat mantissa = FREXPF(t[0], &exponent); 1076f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian q[0] = (GLfloat) (exponent - 1); 1077f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */ 1078962fa6bbc16abf2b9829bd0b761d9baa9d01fd1eIan Romanick 1079962fa6bbc16abf2b9829bd0b761d9baa9d01fd1eIan Romanick /* The fast LOG2 macro doesn't meet the precision 1080962fa6bbc16abf2b9829bd0b761d9baa9d01fd1eIan Romanick * requirements. 1081962fa6bbc16abf2b9829bd0b761d9baa9d01fd1eIan Romanick */ 1082b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz q[2] = (float)(log(t[0]) * 1.442695F); 1083f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 1084f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 1085f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian else { 1086f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian SET_NEG_INFINITY(q[0]); 1087f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian q[1] = 1.0F; 1088f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian SET_NEG_INFINITY(q[2]); 1089f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 1090f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian q[3] = 1.0; 1091f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian store_vector4(inst, machine, q); 1092f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian } 1093f183a2d7ea31a4fea89af834dc19c5b232eb1970Brian break; 1094e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_LRP: 1095e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1096e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], c[4], result[4]; 109733eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 109833eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 109933eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[2], machine, c); 1100e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0]; 1101e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1]; 1102e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; 1103e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; 1104e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1105e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1106e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("LRP (%g %g %g %g) = (%g %g %g %g), " 1107e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian "(%g %g %g %g), (%g %g %g %g)\n", 1108e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], result[1], result[2], result[3], 1109e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0], a[1], a[2], a[3], 1110e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]); 111113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1112e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1113e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1114e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_MAD: 1115e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1116e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], c[4], result[4]; 111733eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 111833eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 111933eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[2], machine, c); 1120e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = a[0] * b[0] + c[0]; 1121e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[1] * b[1] + c[1]; 1122e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[2] * b[2] + c[2]; 1123e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = a[3] * b[3] + c[3]; 1124e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1125e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1126e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("MAD (%g %g %g %g) = (%g %g %g %g) * " 1127e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian "(%g %g %g %g) + (%g %g %g %g)\n", 1128e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], result[1], result[2], result[3], 1129e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0], a[1], a[2], a[3], 1130e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]); 113113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1132e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1133e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1134e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_MAX: 1135e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1136e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 113733eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 113833eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1139e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = MAX2(a[0], b[0]); 1140e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = MAX2(a[1], b[1]); 1141e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = MAX2(a[2], b[2]); 1142e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = MAX2(a[3], b[3]); 1143e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1144e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1145e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", 1146e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], result[1], result[2], result[3], 1147e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); 114813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1149e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1150e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1151e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_MIN: 1152e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1153e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 115433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 115533eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1156e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = MIN2(a[0], b[0]); 1157e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = MIN2(a[1], b[1]); 1158e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = MIN2(a[2], b[2]); 1159e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = MIN2(a[3], b[3]); 1160e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1161e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1162e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1163e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_MOV: 1164e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1165e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat result[4]; 116633eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, result); 1167e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1168e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1169e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("MOV (%g %g %g %g)\n", 1170e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], result[1], result[2], result[3]); 117113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1172e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1173e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1174e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_MUL: 1175e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1176e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 117733eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 117833eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1179e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = a[0] * b[0]; 1180e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[1] * b[1]; 1181e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[2] * b[2]; 1182e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = a[3] * b[3]; 1183e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1184e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1185e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", 1186e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], result[1], result[2], result[3], 1187e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); 118813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1189e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1190e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1191e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_NOISE1: 1192e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1193e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 119433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, a); 1195e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = 119613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[1] = 1197702b5b076b7591560e7e701e0c9ff2eeb30fa966Brian Paul result[2] = 1198702b5b076b7591560e7e701e0c9ff2eeb30fa966Brian Paul result[3] = _mesa_noise1(a[0]); 1199e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1200e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1201e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1202e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_NOISE2: 1203e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1204e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 120533eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 1206e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = 120713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[1] = 1208702b5b076b7591560e7e701e0c9ff2eeb30fa966Brian Paul result[2] = result[3] = _mesa_noise2(a[0], a[1]); 1209e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1210e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1211e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1212e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_NOISE3: 1213e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1214e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 121533eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 1216e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = 121713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[1] = 121813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[2] = 1219702b5b076b7591560e7e701e0c9ff2eeb30fa966Brian Paul result[3] = _mesa_noise3(a[0], a[1], a[2]); 1220e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1221e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1222e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1223e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_NOISE4: 1224e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1225e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 122633eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 1227e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = 122813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[1] = 122913e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian result[2] = 1230702b5b076b7591560e7e701e0c9ff2eeb30fa966Brian Paul result[3] = _mesa_noise4(a[0], a[1], a[2], a[3]); 1231e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1232e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1233e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1234e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_NOP: 1235e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 123637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul case OPCODE_NOT: /* bitwise NOT */ 123737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul { 123837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLuint a[4], result[4]; 123937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul fetch_vector4ui(&inst->SrcReg[0], machine, a); 124037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[0] = ~a[0]; 124137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[1] = ~a[1]; 124237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[2] = ~a[2]; 124337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[3] = ~a[3]; 124437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul store_vector4ui(inst, machine, result); 124537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 124637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul break; 1247f6ead50827c03017e6b730313c361b39190da92fBrian Paul case OPCODE_NRM3: /* 3-component normalization */ 1248f6ead50827c03017e6b730313c361b39190da92fBrian Paul { 1249f6ead50827c03017e6b730313c361b39190da92fBrian Paul GLfloat a[4], result[4]; 1250f6ead50827c03017e6b730313c361b39190da92fBrian Paul GLfloat tmp; 1251f6ead50827c03017e6b730313c361b39190da92fBrian Paul fetch_vector4(&inst->SrcReg[0], machine, a); 1252f6ead50827c03017e6b730313c361b39190da92fBrian Paul tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2]; 1253f6ead50827c03017e6b730313c361b39190da92fBrian Paul if (tmp != 0.0F) 125422459e7a9ca01cc5af8d9baeb6354d2e825cdbc9Brian Paul tmp = INV_SQRTF(tmp); 1255f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[0] = tmp * a[0]; 1256f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[1] = tmp * a[1]; 1257f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[2] = tmp * a[2]; 1258f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[3] = 0.0; /* undefined, but prevent valgrind warnings */ 1259f6ead50827c03017e6b730313c361b39190da92fBrian Paul store_vector4(inst, machine, result); 1260f6ead50827c03017e6b730313c361b39190da92fBrian Paul } 1261f6ead50827c03017e6b730313c361b39190da92fBrian Paul break; 1262f6ead50827c03017e6b730313c361b39190da92fBrian Paul case OPCODE_NRM4: /* 4-component normalization */ 1263f6ead50827c03017e6b730313c361b39190da92fBrian Paul { 1264f6ead50827c03017e6b730313c361b39190da92fBrian Paul GLfloat a[4], result[4]; 1265f6ead50827c03017e6b730313c361b39190da92fBrian Paul GLfloat tmp; 1266f6ead50827c03017e6b730313c361b39190da92fBrian Paul fetch_vector4(&inst->SrcReg[0], machine, a); 1267f6ead50827c03017e6b730313c361b39190da92fBrian Paul tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]; 1268f6ead50827c03017e6b730313c361b39190da92fBrian Paul if (tmp != 0.0F) 126922459e7a9ca01cc5af8d9baeb6354d2e825cdbc9Brian Paul tmp = INV_SQRTF(tmp); 1270f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[0] = tmp * a[0]; 1271f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[1] = tmp * a[1]; 1272f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[2] = tmp * a[2]; 1273f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[3] = tmp * a[3]; 1274f6ead50827c03017e6b730313c361b39190da92fBrian Paul store_vector4(inst, machine, result); 1275f6ead50827c03017e6b730313c361b39190da92fBrian Paul } 1276f6ead50827c03017e6b730313c361b39190da92fBrian Paul break; 127737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul case OPCODE_OR: /* bitwise OR */ 127837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul { 127937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLuint a[4], b[4], result[4]; 128037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul fetch_vector4ui(&inst->SrcReg[0], machine, a); 128137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul fetch_vector4ui(&inst->SrcReg[1], machine, b); 128237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[0] = a[0] | b[0]; 128337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[1] = a[1] | b[1]; 128437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[2] = a[2] | b[2]; 128537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[3] = a[3] | b[3]; 128637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul store_vector4ui(inst, machine, result); 128737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 128837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul break; 1289e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ 1290e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 129137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLfloat a[4]; 129237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLuint result[4]; 1293e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLhalfNV hx, hy; 129433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 1295e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian hx = _mesa_float_to_half(a[0]); 1296e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian hy = _mesa_float_to_half(a[1]); 129737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[0] = 129837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[1] = 129937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[2] = 130037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[3] = hx | (hy << 16); 130137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul store_vector4ui(inst, machine, result); 1302e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1303e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1304e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ 1305e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 130637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLfloat a[4]; 130737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLuint result[4], usx, usy; 130833eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 1309e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0] = CLAMP(a[0], 0.0F, 1.0F); 1310e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[1] = CLAMP(a[1], 0.0F, 1.0F); 1311c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul usx = F_TO_I(a[0] * 65535.0F); 1312c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul usy = F_TO_I(a[1] * 65535.0F); 131337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[0] = 131437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[1] = 131537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[2] = 131637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[3] = usx | (usy << 16); 131737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul store_vector4ui(inst, machine, result); 1318e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1319e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1320e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ 1321e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 132237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLfloat a[4]; 132337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLuint result[4], ubx, uby, ubz, ubw; 132433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 1325e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F); 1326e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); 1327e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); 1328e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); 1329c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul ubx = F_TO_I(127.0F * a[0] + 128.0F); 1330c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul uby = F_TO_I(127.0F * a[1] + 128.0F); 1331c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul ubz = F_TO_I(127.0F * a[2] + 128.0F); 1332c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul ubw = F_TO_I(127.0F * a[3] + 128.0F); 133337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[0] = 133437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[1] = 133537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[2] = 133637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); 133737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul store_vector4ui(inst, machine, result); 1338e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1339e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1340e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ 1341e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 134237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLfloat a[4]; 134337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLuint result[4], ubx, uby, ubz, ubw; 134433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 1345e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0] = CLAMP(a[0], 0.0F, 1.0F); 1346e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[1] = CLAMP(a[1], 0.0F, 1.0F); 1347e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[2] = CLAMP(a[2], 0.0F, 1.0F); 1348e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[3] = CLAMP(a[3], 0.0F, 1.0F); 1349c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul ubx = F_TO_I(255.0F * a[0]); 1350c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul uby = F_TO_I(255.0F * a[1]); 1351c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul ubz = F_TO_I(255.0F * a[2]); 1352c9cb9cf0502f4ca179ed1b4dd763c94912843d38Brian Paul ubw = F_TO_I(255.0F * a[3]); 135337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[0] = 135437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[1] = 135537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[2] = 135637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); 135737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul store_vector4ui(inst, machine, result); 1358e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1359e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1360e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_POW: 1361e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1362e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 136333eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, a); 136433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[1], machine, b); 1365e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = result[1] = result[2] = result[3] 1366fef303bc94f2fb15a068563ac8abfb1765bde035Eric Anholt = (GLfloat) pow(a[0], b[0]); 1367e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1368e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1369e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1370b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul case OPCODE_RCC: /* clamped riciprocal */ 1371b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul { 1372b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul const float largest = 1.884467e+19, smallest = 5.42101e-20; 1373b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul GLfloat a[4], r, result[4]; 1374b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul fetch_vector1(&inst->SrcReg[0], machine, a); 1375b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul if (DEBUG_PROG) { 1376b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul if (a[0] == 0) 1377b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul printf("RCC(0)\n"); 1378b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul else if (IS_INF_OR_NAN(a[0])) 1379b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul printf("RCC(inf)\n"); 1380b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1381b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul if (a[0] == 1.0F) { 1382b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul r = 1.0F; 1383b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1384b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul else { 1385b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul r = 1.0F / a[0]; 1386b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1387b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul if (positive(r)) { 1388b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul if (r > largest) { 1389b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul r = largest; 1390b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1391b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul else if (r < smallest) { 1392b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul r = smallest; 1393b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1394b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1395b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul else { 1396b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul if (r < -largest) { 1397b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul r = -largest; 1398b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1399b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul else if (r > -smallest) { 1400b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul r = -smallest; 1401b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1402b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1403b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul result[0] = result[1] = result[2] = result[3] = r; 1404b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul store_vector4(inst, machine, result); 1405b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul } 1406b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul break; 1407b4ad7c28430e4084d843cd99cf68209e95363963Brian Paul 1408e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_RCP: 1409e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1410e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 141133eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, a); 1412e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1413e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (a[0] == 0) 1414e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("RCP(0)\n"); 1415e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian else if (IS_INF_OR_NAN(a[0])) 1416e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("RCP(inf)\n"); 1417e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1418e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; 1419e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1420e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1421e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1422e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_RET: /* return from subroutine (conditional) */ 1423e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (eval_condition(machine, inst)) { 1424e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (machine->StackDepth == 0) { 1425e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ 142613e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1427a0275b0d2c071ed8254c2af3a0c53eec9d3561a6Brian /* subtract one because of pc++ in the for loop */ 1428a0275b0d2c071ed8254c2af3a0c53eec9d3561a6Brian pc = machine->CallStack[--machine->StackDepth] - 1; 1429e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1430e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1431e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_RFL: /* reflection vector */ 1432e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1433e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat axis[4], dir[4], result[4], tmpX, tmpW; 143433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, axis); 143533eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, dir); 1436e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian tmpW = DOT3(axis, axis); 1437e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian tmpX = (2.0F * DOT3(axis, dir)) / tmpW; 1438e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = tmpX * axis[0] - dir[0]; 1439e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = tmpX * axis[1] - dir[1]; 1440e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = tmpX * axis[2] - dir[2]; 1441e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* result[3] is never written! XXX enforce in parser! */ 1442e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1443e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1444e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1445e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_RSQ: /* 1 / sqrt() */ 1446e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1447e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 144833eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, a); 1449e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0] = FABSF(a[0]); 1450e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); 1451e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1452e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1453e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); 145413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1455e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1456e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1457e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SCS: /* sine and cos */ 1458e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1459e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 146033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, a); 1461165694ad65374ff4330bd80acb398fe0428ba2e6Eric Anholt result[0] = (GLfloat) cos(a[0]); 1462165694ad65374ff4330bd80acb398fe0428ba2e6Eric Anholt result[1] = (GLfloat) sin(a[0]); 1463e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = 0.0; /* undefined! */ 1464e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = 0.0; /* undefined! */ 1465e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1466e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1467e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1468e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SEQ: /* set on equal */ 1469e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1470e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 147133eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 147233eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1473e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = (a[0] == b[0]) ? 1.0F : 0.0F; 1474e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = (a[1] == b[1]) ? 1.0F : 0.0F; 1475e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = (a[2] == b[2]) ? 1.0F : 0.0F; 1476e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = (a[3] == b[3]) ? 1.0F : 0.0F; 1477e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 147828ab1125c22bcb558e3b5e127d975120de76e103Brian if (DEBUG_PROG) { 147928ab1125c22bcb558e3b5e127d975120de76e103Brian printf("SEQ (%g %g %g %g) = (%g %g %g %g) == (%g %g %g %g)\n", 148028ab1125c22bcb558e3b5e127d975120de76e103Brian result[0], result[1], result[2], result[3], 148128ab1125c22bcb558e3b5e127d975120de76e103Brian a[0], a[1], a[2], a[3], 148228ab1125c22bcb558e3b5e127d975120de76e103Brian b[0], b[1], b[2], b[3]); 148328ab1125c22bcb558e3b5e127d975120de76e103Brian } 1484e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1485e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1486e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SFL: /* set false, operands ignored */ 1487e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1488e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; 1489e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1490e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1491e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1492e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SGE: /* set on greater or equal */ 1493e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1494e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 149533eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 149633eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1497e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F; 1498e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F; 1499e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F; 1500e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F; 1501e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 150228ab1125c22bcb558e3b5e127d975120de76e103Brian if (DEBUG_PROG) { 150328ab1125c22bcb558e3b5e127d975120de76e103Brian printf("SGE (%g %g %g %g) = (%g %g %g %g) >= (%g %g %g %g)\n", 150428ab1125c22bcb558e3b5e127d975120de76e103Brian result[0], result[1], result[2], result[3], 150528ab1125c22bcb558e3b5e127d975120de76e103Brian a[0], a[1], a[2], a[3], 150628ab1125c22bcb558e3b5e127d975120de76e103Brian b[0], b[1], b[2], b[3]); 150728ab1125c22bcb558e3b5e127d975120de76e103Brian } 1508e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1509e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1510e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SGT: /* set on greater */ 1511e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1512e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 151333eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 151433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1515e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = (a[0] > b[0]) ? 1.0F : 0.0F; 1516e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = (a[1] > b[1]) ? 1.0F : 0.0F; 1517e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = (a[2] > b[2]) ? 1.0F : 0.0F; 1518e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = (a[3] > b[3]) ? 1.0F : 0.0F; 1519e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1520e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 152128ab1125c22bcb558e3b5e127d975120de76e103Brian printf("SGT (%g %g %g %g) = (%g %g %g %g) > (%g %g %g %g)\n", 152228ab1125c22bcb558e3b5e127d975120de76e103Brian result[0], result[1], result[2], result[3], 152328ab1125c22bcb558e3b5e127d975120de76e103Brian a[0], a[1], a[2], a[3], 152428ab1125c22bcb558e3b5e127d975120de76e103Brian b[0], b[1], b[2], b[3]); 152513e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1526e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1527e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1528e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SIN: 1529e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1530e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], result[4]; 153133eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector1(&inst->SrcReg[0], machine, a); 1532e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = result[1] = result[2] = result[3] 1533165694ad65374ff4330bd80acb398fe0428ba2e6Eric Anholt = (GLfloat) sin(a[0]); 1534e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1535e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1536e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1537e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SLE: /* set on less or equal */ 1538e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1539e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 154033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 154133eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1542e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F; 1543e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F; 1544e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F; 1545e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F; 1546e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 154728ab1125c22bcb558e3b5e127d975120de76e103Brian if (DEBUG_PROG) { 154828ab1125c22bcb558e3b5e127d975120de76e103Brian printf("SLE (%g %g %g %g) = (%g %g %g %g) <= (%g %g %g %g)\n", 154928ab1125c22bcb558e3b5e127d975120de76e103Brian result[0], result[1], result[2], result[3], 155028ab1125c22bcb558e3b5e127d975120de76e103Brian a[0], a[1], a[2], a[3], 155128ab1125c22bcb558e3b5e127d975120de76e103Brian b[0], b[1], b[2], b[3]); 155228ab1125c22bcb558e3b5e127d975120de76e103Brian } 1553e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1554e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1555e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SLT: /* set on less */ 1556e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1557e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 155833eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 155933eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1560e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = (a[0] < b[0]) ? 1.0F : 0.0F; 1561e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = (a[1] < b[1]) ? 1.0F : 0.0F; 1562e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = (a[2] < b[2]) ? 1.0F : 0.0F; 1563e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = (a[3] < b[3]) ? 1.0F : 0.0F; 1564e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 156528ab1125c22bcb558e3b5e127d975120de76e103Brian if (DEBUG_PROG) { 156628ab1125c22bcb558e3b5e127d975120de76e103Brian printf("SLT (%g %g %g %g) = (%g %g %g %g) < (%g %g %g %g)\n", 156728ab1125c22bcb558e3b5e127d975120de76e103Brian result[0], result[1], result[2], result[3], 156828ab1125c22bcb558e3b5e127d975120de76e103Brian a[0], a[1], a[2], a[3], 156928ab1125c22bcb558e3b5e127d975120de76e103Brian b[0], b[1], b[2], b[3]); 157028ab1125c22bcb558e3b5e127d975120de76e103Brian } 1571e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1572e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1573e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SNE: /* set on not equal */ 1574e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1575e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 157633eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 157733eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1578e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = (a[0] != b[0]) ? 1.0F : 0.0F; 1579e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = (a[1] != b[1]) ? 1.0F : 0.0F; 1580e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = (a[2] != b[2]) ? 1.0F : 0.0F; 1581e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = (a[3] != b[3]) ? 1.0F : 0.0F; 1582e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 158328ab1125c22bcb558e3b5e127d975120de76e103Brian if (DEBUG_PROG) { 158428ab1125c22bcb558e3b5e127d975120de76e103Brian printf("SNE (%g %g %g %g) = (%g %g %g %g) != (%g %g %g %g)\n", 158528ab1125c22bcb558e3b5e127d975120de76e103Brian result[0], result[1], result[2], result[3], 158628ab1125c22bcb558e3b5e127d975120de76e103Brian a[0], a[1], a[2], a[3], 158728ab1125c22bcb558e3b5e127d975120de76e103Brian b[0], b[1], b[2], b[3]); 158828ab1125c22bcb558e3b5e127d975120de76e103Brian } 1589e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1590e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1591f6ead50827c03017e6b730313c361b39190da92fBrian Paul case OPCODE_SSG: /* set sign (-1, 0 or +1) */ 1592f6ead50827c03017e6b730313c361b39190da92fBrian Paul { 1593f6ead50827c03017e6b730313c361b39190da92fBrian Paul GLfloat a[4], result[4]; 1594f6ead50827c03017e6b730313c361b39190da92fBrian Paul fetch_vector4(&inst->SrcReg[0], machine, a); 1595f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[0] = (GLfloat) ((a[0] > 0.0F) - (a[0] < 0.0F)); 1596f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[1] = (GLfloat) ((a[1] > 0.0F) - (a[1] < 0.0F)); 1597f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[2] = (GLfloat) ((a[2] > 0.0F) - (a[2] < 0.0F)); 1598f6ead50827c03017e6b730313c361b39190da92fBrian Paul result[3] = (GLfloat) ((a[3] > 0.0F) - (a[3] < 0.0F)); 1599f6ead50827c03017e6b730313c361b39190da92fBrian Paul store_vector4(inst, machine, result); 1600f6ead50827c03017e6b730313c361b39190da92fBrian Paul } 1601f6ead50827c03017e6b730313c361b39190da92fBrian Paul break; 1602e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_STR: /* set true, operands ignored */ 1603e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1604e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F }; 1605e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1606e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1607e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1608e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SUB: 1609e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1610e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 161133eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 161233eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1613e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = a[0] - b[0]; 1614e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[1] - b[1]; 1615e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[2] - b[2]; 1616e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = a[3] - b[3]; 1617e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1618e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1619e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", 1620e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0], result[1], result[2], result[3], 1621e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); 162213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1623e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1624e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1625e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_SWZ: /* extended swizzle */ 1626e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1627e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian const struct prog_src_register *source = &inst->SrcReg[0]; 1628f4361540f8dd3016571523863b33481cba7a0c07Brian Paul const GLfloat *src = get_src_register_pointer(source, machine); 1629e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat result[4]; 1630e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLuint i; 1631e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian for (i = 0; i < 4; i++) { 1632e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian const GLuint swz = GET_SWZ(source->Swizzle, i); 1633e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (swz == SWIZZLE_ZERO) 1634e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[i] = 0.0; 1635e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian else if (swz == SWIZZLE_ONE) 1636e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[i] = 1.0; 1637e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian else { 1638e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian ASSERT(swz >= 0); 1639e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian ASSERT(swz <= 3); 1640e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[i] = src[swz]; 164113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 16427db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul if (source->Negate & (1 << i)) 1643e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[i] = -result[i]; 164413e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1645e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1646e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1647e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1648e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_TEX: /* Both ARB and NV frag prog */ 1649999b55663a09d9669a9d14c5aadfa84e6dcba288Brian /* Simple texel lookup */ 1650e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1651999b55663a09d9669a9d14c5aadfa84e6dcba288Brian GLfloat texcoord[4], color[4]; 1652999b55663a09d9669a9d14c5aadfa84e6dcba288Brian fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1653999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 16540eb18ee55719377ebd90456bde605384ce4ec14aBrian Paul /* For TEX, texcoord.Q should not be used and its value should not 16550eb18ee55719377ebd90456bde605384ce4ec14aBrian Paul * matter (at most, we pass coord.xyz to texture3D() in GLSL). 16560eb18ee55719377ebd90456bde605384ce4ec14aBrian Paul * Set Q=1 so that FetchTexelDeriv() doesn't get a garbage value 16570eb18ee55719377ebd90456bde605384ce4ec14aBrian Paul * which is effectively what happens when the texcoord swizzle 16580eb18ee55719377ebd90456bde605384ce4ec14aBrian Paul * is .xyzz 16590eb18ee55719377ebd90456bde605384ce4ec14aBrian Paul */ 16600eb18ee55719377ebd90456bde605384ce4ec14aBrian Paul texcoord[3] = 1.0f; 16610eb18ee55719377ebd90456bde605384ce4ec14aBrian Paul 1662999b55663a09d9669a9d14c5aadfa84e6dcba288Brian fetch_texel(ctx, machine, inst, texcoord, 0.0, color); 1663999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 1664e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (DEBUG_PROG) { 1665999b55663a09d9669a9d14c5aadfa84e6dcba288Brian printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g]\n", 1666e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian color[0], color[1], color[2], color[3], 1667e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian inst->TexSrcUnit, 1668999b55663a09d9669a9d14c5aadfa84e6dcba288Brian texcoord[0], texcoord[1], texcoord[2], texcoord[3]); 1669e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1670e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, color); 1671e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1672e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1673e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_TXB: /* GL_ARB_fragment_program only */ 1674e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* Texel lookup with LOD bias */ 1675e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1676999b55663a09d9669a9d14c5aadfa84e6dcba288Brian GLfloat texcoord[4], color[4], lodBias; 1677999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 1678999b55663a09d9669a9d14c5aadfa84e6dcba288Brian fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1679999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 1680999b55663a09d9669a9d14c5aadfa84e6dcba288Brian /* texcoord[3] is the bias to add to lambda */ 1681890f37d4d96471a5c3d8ae286dfc13ad18ff78e5Brian Paul lodBias = texcoord[3]; 1682999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 1683999b55663a09d9669a9d14c5aadfa84e6dcba288Brian fetch_texel(ctx, machine, inst, texcoord, lodBias, color); 1684999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 1685be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul if (DEBUG_PROG) { 1686be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul printf("TXB (%g, %g, %g, %g) = texture[%d][%g %g %g %g]" 1687be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul " bias %g\n", 1688be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul color[0], color[1], color[2], color[3], 1689be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul inst->TexSrcUnit, 1690be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul texcoord[0], 1691be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul texcoord[1], 1692be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul texcoord[2], 1693be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul texcoord[3], 1694be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul lodBias); 1695be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul } 1696be2aa81f5f8f44be8c9c8854098d29635352c4f8Brian Paul 1697e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, color); 1698e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1699e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1700e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_TXD: /* GL_NV_fragment_program only */ 1701e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* Texture lookup w/ partial derivatives for LOD */ 1702e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1703e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat texcoord[4], dtdx[4], dtdy[4], color[4]; 170433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, texcoord); 170533eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, dtdx); 170633eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[2], machine, dtdy); 1707e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy, 1708999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 0.0, /* lodBias */ 1709e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian inst->TexSrcUnit, color); 1710e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, color); 1711e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1712e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 17130eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick case OPCODE_TXL: 17140eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick /* Texel lookup with explicit LOD */ 17150eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick { 17160eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick GLfloat texcoord[4], color[4], lod; 17170eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick 17180eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick fetch_vector4(&inst->SrcReg[0], machine, texcoord); 17190eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick 17200eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick /* texcoord[3] is the LOD */ 17210eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick lod = texcoord[3]; 17220eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick 17230eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick machine->FetchTexelLod(ctx, texcoord, lod, 17240eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick machine->Samplers[inst->TexSrcUnit], color); 17250eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick 17260eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick store_vector4(inst, machine, color); 17270eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick } 17280eb2026c8767d6e1f68e6b07f35a9aca9ed757c7Ian Romanick break; 1729e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_TXP: /* GL_ARB_fragment_program only */ 1730e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* Texture lookup w/ projective divide */ 1731e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1732999b55663a09d9669a9d14c5aadfa84e6dcba288Brian GLfloat texcoord[4], color[4]; 1733999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 173433eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1735e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian /* Not so sure about this test - if texcoord[3] is 1736e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian * zero, we'd probably be fine except for an ASSERT in 1737e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian * IROUND_POS() which gets triggered by the inf values created. 1738e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian */ 1739e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (texcoord[3] != 0.0) { 1740e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian texcoord[0] /= texcoord[3]; 1741e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian texcoord[1] /= texcoord[3]; 1742e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian texcoord[2] /= texcoord[3]; 1743e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1744999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 1745999b55663a09d9669a9d14c5aadfa84e6dcba288Brian fetch_texel(ctx, machine, inst, texcoord, 0.0, color); 1746999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 1747e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, color); 1748e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1749e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1750e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ 1751999b55663a09d9669a9d14c5aadfa84e6dcba288Brian /* Texture lookup w/ projective divide, as above, but do not 1752999b55663a09d9669a9d14c5aadfa84e6dcba288Brian * do the divide by w if sampling from a cube map. 1753999b55663a09d9669a9d14c5aadfa84e6dcba288Brian */ 1754e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1755999b55663a09d9669a9d14c5aadfa84e6dcba288Brian GLfloat texcoord[4], color[4]; 1756999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 175733eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1758e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && 1759e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian texcoord[3] != 0.0) { 1760e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian texcoord[0] /= texcoord[3]; 1761e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian texcoord[1] /= texcoord[3]; 1762e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian texcoord[2] /= texcoord[3]; 1763e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1764999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 1765999b55663a09d9669a9d14c5aadfa84e6dcba288Brian fetch_texel(ctx, machine, inst, texcoord, 0.0, color); 1766999b55663a09d9669a9d14c5aadfa84e6dcba288Brian 1767e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, color); 1768e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1769e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1770035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul case OPCODE_TRUNC: /* truncate toward zero */ 1771035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul { 1772035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul GLfloat a[4], result[4]; 1773035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul fetch_vector4(&inst->SrcReg[0], machine, a); 1774035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul result[0] = (GLfloat) (GLint) a[0]; 1775035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul result[1] = (GLfloat) (GLint) a[1]; 1776035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul result[2] = (GLfloat) (GLint) a[2]; 1777035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul result[3] = (GLfloat) (GLint) a[3]; 1778035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul store_vector4(inst, machine, result); 1779035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul } 1780035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul break; 1781e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_UP2H: /* unpack two 16-bit floats */ 1782e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 17838d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); 17848d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul GLfloat result[4]; 17857b5ad23c7f7f9016f725cb1caa3cf8971aeedbc8Brian Paul GLushort hx, hy; 17868d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul hx = raw & 0xffff; 17878d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul hy = raw >> 16; 1788e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = result[2] = _mesa_half_to_float(hx); 1789e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = result[3] = _mesa_half_to_float(hy); 1790e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1791e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1792e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1793e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_UP2US: /* unpack two GLushorts */ 1794e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 17958d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); 17968d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul GLfloat result[4]; 1797e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLushort usx, usy; 17988d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul usx = raw & 0xffff; 17998d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul usy = raw >> 16; 1800e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = result[2] = usx * (1.0f / 65535.0f); 1801e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = result[3] = usy * (1.0f / 65535.0f); 1802e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1803e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1804e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1805e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_UP4B: /* unpack four GLbytes */ 1806e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 18078d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); 18088d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul GLfloat result[4]; 18098d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul result[0] = (((raw >> 0) & 0xff) - 128) / 127.0F; 18108d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul result[1] = (((raw >> 8) & 0xff) - 128) / 127.0F; 18118d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul result[2] = (((raw >> 16) & 0xff) - 128) / 127.0F; 18128d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul result[3] = (((raw >> 24) & 0xff) - 128) / 127.0F; 1813e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1814e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1815e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1816e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_UP4UB: /* unpack four GLubytes */ 1817e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 18188d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); 18198d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul GLfloat result[4]; 18208d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul result[0] = ((raw >> 0) & 0xff) / 255.0F; 18218d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul result[1] = ((raw >> 8) & 0xff) / 255.0F; 18228d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul result[2] = ((raw >> 16) & 0xff) / 255.0F; 18238d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfbBrian Paul result[3] = ((raw >> 24) & 0xff) / 255.0F; 1824e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1825e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1826e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 182737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul case OPCODE_XOR: /* bitwise XOR */ 182837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul { 182937eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul GLuint a[4], b[4], result[4]; 183037eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul fetch_vector4ui(&inst->SrcReg[0], machine, a); 183137eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul fetch_vector4ui(&inst->SrcReg[1], machine, b); 183237eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[0] = a[0] ^ b[0]; 183337eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[1] = a[1] ^ b[1]; 183437eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[2] = a[2] ^ b[2]; 183537eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul result[3] = a[3] ^ b[3]; 183637eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul store_vector4ui(inst, machine, result); 183737eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul } 183837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul break; 1839e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_XPD: /* cross product */ 1840e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1841e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], result[4]; 184233eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 184333eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 1844e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = a[1] * b[2] - a[2] * b[1]; 1845e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[2] * b[0] - a[0] * b[2]; 1846e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[0] * b[1] - a[1] * b[0]; 1847e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = 1.0; 1848e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 18499637c963f59192aaccf68e7690f5ffb1e17ba077Brian if (DEBUG_PROG) { 18509637c963f59192aaccf68e7690f5ffb1e17ba077Brian printf("XPD (%g %g %g %g) = (%g %g %g) X (%g %g %g)\n", 18519637c963f59192aaccf68e7690f5ffb1e17ba077Brian result[0], result[1], result[2], result[3], 18529637c963f59192aaccf68e7690f5ffb1e17ba077Brian a[0], a[1], a[2], b[0], b[1], b[2]); 18539637c963f59192aaccf68e7690f5ffb1e17ba077Brian } 1854e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1855e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1856e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_X2D: /* 2-D matrix transform */ 1857e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 1858e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian GLfloat a[4], b[4], c[4], result[4]; 185933eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[0], machine, a); 186033eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[1], machine, b); 186133eac56e4a48143aa8acd5757feb68570e860de5Brian fetch_vector4(&inst->SrcReg[2], machine, c); 1862e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[0] = a[0] + b[0] * c[0] + b[1] * c[1]; 1863e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[1] = a[1] + b[0] * c[2] + b[1] * c[3]; 1864e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[2] = a[2] + b[0] * c[0] + b[1] * c[1]; 1865e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian result[3] = a[3] + b[0] * c[2] + b[1] * c[3]; 1866e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian store_vector4(inst, machine, result); 1867e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1868e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1869e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_PRINT: 1870e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian { 18714e98116c234c25119c1a3a0c0a138ada2ab69906Vinson Lee if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { 187245df4bad9fc0379f05197bee10c03fd351f24094Vinson Lee GLfloat a[4]; 187345df4bad9fc0379f05197bee10c03fd351f24094Vinson Lee fetch_vector4(&inst->SrcReg[0], machine, a); 187445df4bad9fc0379f05197bee10c03fd351f24094Vinson Lee printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, 187545df4bad9fc0379f05197bee10c03fd351f24094Vinson Lee a[0], a[1], a[2], a[3]); 187645df4bad9fc0379f05197bee10c03fd351f24094Vinson Lee } 187745df4bad9fc0379f05197bee10c03fd351f24094Vinson Lee else { 187845df4bad9fc0379f05197bee10c03fd351f24094Vinson Lee printf("%s\n", (const char *) inst->Data); 187945df4bad9fc0379f05197bee10c03fd351f24094Vinson Lee } 1880e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } 1881e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian break; 1882e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian case OPCODE_END: 1883e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian return GL_TRUE; 1884e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian default: 1885936dba1de5ca0d4252061c4a93674fad2d66d202Alan Hourihane _mesa_problem(ctx, "Bad opcode %d in _mesa_execute_program", 1886e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian inst->Opcode); 1887e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian return GL_TRUE; /* return value doesn't matter */ 188813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1889e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian 1890cfd0011f2fe3aad2ea0f66c151b3fb12d05f644eBrian numExec++; 1891cfd0011f2fe3aad2ea0f66c151b3fb12d05f644eBrian if (numExec > maxExec) { 1892cc15ef07e03e465d93df7062a516f9b4bfbaeda0Eric Anholt static GLboolean reported = GL_FALSE; 1893cc15ef07e03e465d93df7062a516f9b4bfbaeda0Eric Anholt if (!reported) { 1894cc15ef07e03e465d93df7062a516f9b4bfbaeda0Eric Anholt _mesa_problem(ctx, "Infinite loop detected in fragment program"); 1895cc15ef07e03e465d93df7062a516f9b4bfbaeda0Eric Anholt reported = GL_TRUE; 1896cc15ef07e03e465d93df7062a516f9b4bfbaeda0Eric Anholt } 189713e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian return GL_TRUE; 189813e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian } 1899e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian 1900e80d901d9854b7c24a71fcd5a3377c33f408c8c0Brian } /* for pc */ 190113e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian 190213e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian return GL_TRUE; 190313e3b21b16b14112b416f3ee5742fc7bd1b2d823Brian} 1904