1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version: 7.3 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software. 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file prog_execute.c 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software interpreter for vertex/fragment programs. 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \author Brian Paul 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOTE: we do everything in single-precision floating point; we don't 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * currently observe the single/half/fixed-precision qualifiers. 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/colormac.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_execute.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_instruction.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_parameter.h" 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_print.h" 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_noise.h" 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* debug predicate */ 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUG_PROG 0 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set x to positive or negative infinity. 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(USE_IEEE) || defined(_WIN32) 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_POS_INFINITY(x) \ 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do { \ 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fi_type fi; \ 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fi.i = 0x7F800000; \ 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x = fi.f; \ 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } while (0) 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_NEG_INFINITY(x) \ 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do { \ 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fi_type fi; \ 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fi.i = 0xFF800000; \ 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x = fi.f; \ 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } while (0) 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(VMS) 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_POS_INFINITY(x) x = __MAXFLOAT 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_NEG_INFINITY(x) x = -__MAXFLOAT 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_POS_INFINITY(x) x = (GLfloat) HUGE_VAL 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return TRUE for +0 and other positive values, FALSE otherwise. 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used for RCC opcode. 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLboolean 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpositive(float x) 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fi_type fi; 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fi.f = x; 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fi.i & 0x80000000) 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return a pointer to the 4-element float vector specified by the given 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * source register. 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline const GLfloat * 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_src_register_pointer(const struct prog_src_register *source, 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program_machine *machine) 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program *prog = machine->CurProgram; 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint reg = source->Index; 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->RelAddr) { 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* add address register value to src index/offset */ 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg += machine->AddressReg[0][0]; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg < 0) { 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ZeroVec; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (source->File) { 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_TEMPORARY: 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg >= MAX_PROGRAM_TEMPS) 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ZeroVec; 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return machine->Temporaries[reg]; 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_INPUT: 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (prog->Target == GL_VERTEX_PROGRAM_ARB) { 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg >= VERT_ATTRIB_MAX) 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ZeroVec; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return machine->VertAttribs[reg]; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg >= FRAG_ATTRIB_MAX) 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ZeroVec; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return machine->Attribs[reg][machine->CurElement]; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_OUTPUT: 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg >= MAX_PROGRAM_OUTPUTS) 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ZeroVec; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return machine->Outputs[reg]; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_LOCAL_PARAM: 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg >= MAX_PROGRAM_LOCAL_PARAMS) 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ZeroVec; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return machine->CurProgram->LocalParams[reg]; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_ENV_PARAM: 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg >= MAX_PROGRAM_ENV_PARAMS) 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ZeroVec; 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return machine->EnvParams[reg]; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_STATE_VAR: 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fallthrough */ 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_CONSTANT: 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fallthrough */ 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_UNIFORM: 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fallthrough */ 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_NAMED_PARAM: 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg >= (GLint) prog->Parameters->NumParameters) 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ZeroVec; 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (GLfloat *) prog->Parameters->ParameterValues[reg]; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_SYSTEM_VALUE: 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(reg < Elements(machine->SystemValues)); 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return machine->SystemValues[reg]; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_problem(NULL, 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Invalid src register file %d in get_src_register_pointer()", 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org source->File); 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return a pointer to the 4-element float vector specified by the given 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * destination register. 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat * 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_dst_register_pointer(const struct prog_dst_register *dest, 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program_machine *machine) 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static GLfloat dummyReg[4]; 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint reg = dest->Index; 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dest->RelAddr) { 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* add address register value to src index/offset */ 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg += machine->AddressReg[0][0]; 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg < 0) { 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return dummyReg; 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (dest->File) { 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_TEMPORARY: 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg >= MAX_PROGRAM_TEMPS) 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return dummyReg; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return machine->Temporaries[reg]; 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_OUTPUT: 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg >= MAX_PROGRAM_OUTPUTS) 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return dummyReg; 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return machine->Outputs[reg]; 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_WRITE_ONLY: 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return dummyReg; 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_problem(NULL, 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Invalid dest register file %d in get_dst_register_pointer()", 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dest->File); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch a 4-element float vector from the given source register. 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Apply swizzling and negating as needed. 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector4(const struct prog_src_register *source, 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program_machine *machine, GLfloat result[4]) 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat *src = get_src_register_pointer(source, machine); 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(src); 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->Swizzle == SWIZZLE_NOOP) { 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no swizzling */ 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org COPY_4V(result, src); 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(GET_SWZ(source->Swizzle, 0) <= 3); 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(GET_SWZ(source->Swizzle, 1) <= 3); 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(GET_SWZ(source->Swizzle, 2) <= 3); 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(GET_SWZ(source->Swizzle, 3) <= 3); 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = src[GET_SWZ(source->Swizzle, 0)]; 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = src[GET_SWZ(source->Swizzle, 1)]; 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = src[GET_SWZ(source->Swizzle, 2)]; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = src[GET_SWZ(source->Swizzle, 3)]; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->Abs) { 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = FABSF(result[0]); 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = FABSF(result[1]); 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = FABSF(result[2]); 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = FABSF(result[3]); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->Negate) { 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(source->Negate == NEGATE_XYZW); 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = -result[0]; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = -result[1]; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = -result[2]; 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = -result[3]; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef NAN_CHECK 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!IS_INF_OR_NAN(result[0])); 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!IS_INF_OR_NAN(result[0])); 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!IS_INF_OR_NAN(result[0])); 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!IS_INF_OR_NAN(result[0])); 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch a 4-element uint vector from the given source register. 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Apply swizzling but not negation/abs. 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector4ui(const struct prog_src_register *source, 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program_machine *machine, GLuint result[4]) 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint *src = (GLuint *) get_src_register_pointer(source, machine); 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(src); 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->Swizzle == SWIZZLE_NOOP) { 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no swizzling */ 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org COPY_4V(result, src); 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(GET_SWZ(source->Swizzle, 0) <= 3); 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(GET_SWZ(source->Swizzle, 1) <= 3); 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(GET_SWZ(source->Swizzle, 2) <= 3); 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(GET_SWZ(source->Swizzle, 3) <= 3); 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = src[GET_SWZ(source->Swizzle, 0)]; 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = src[GET_SWZ(source->Swizzle, 1)]; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = src[GET_SWZ(source->Swizzle, 2)]; 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = src[GET_SWZ(source->Swizzle, 3)]; 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note: no Negate or Abs here */ 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch the derivative with respect to X or Y for the given register. 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX this currently only works for fragment program input attribs. 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector4_deriv(struct gl_context * ctx, 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct prog_src_register *source, 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program_machine *machine, 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char xOrY, GLfloat result[4]) 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->File == PROGRAM_INPUT && 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org source->Index < (GLint) machine->NumDeriv) { 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint col = machine->CurElement; 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat w = machine->Attribs[FRAG_ATTRIB_WPOS][col][3]; 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat invQ = 1.0f / w; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat deriv[4]; 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (xOrY == 'X') { 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deriv[0] = machine->DerivX[source->Index][0] * invQ; 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deriv[1] = machine->DerivX[source->Index][1] * invQ; 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deriv[2] = machine->DerivX[source->Index][2] * invQ; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deriv[3] = machine->DerivX[source->Index][3] * invQ; 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deriv[0] = machine->DerivY[source->Index][0] * invQ; 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deriv[1] = machine->DerivY[source->Index][1] * invQ; 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deriv[2] = machine->DerivY[source->Index][2] * invQ; 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deriv[3] = machine->DerivY[source->Index][3] * invQ; 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = deriv[GET_SWZ(source->Swizzle, 0)]; 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = deriv[GET_SWZ(source->Swizzle, 1)]; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = deriv[GET_SWZ(source->Swizzle, 2)]; 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = deriv[GET_SWZ(source->Swizzle, 3)]; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->Abs) { 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = FABSF(result[0]); 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = FABSF(result[1]); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = FABSF(result[2]); 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = FABSF(result[3]); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->Negate) { 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(source->Negate == NEGATE_XYZW); 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = -result[0]; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = -result[1]; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = -result[2]; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = -result[3]; 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSIGN_4V(result, 0.0, 0.0, 0.0, 0.0); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As above, but only return result[0] element. 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector1(const struct prog_src_register *source, 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program_machine *machine, GLfloat result[4]) 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat *src = get_src_register_pointer(source, machine); 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(src); 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = src[GET_SWZ(source->Swizzle, 0)]; 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->Abs) { 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = FABSF(result[0]); 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->Negate) { 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = -result[0]; 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLuint 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector1ui(const struct prog_src_register *source, 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program_machine *machine) 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint *src = (GLuint *) get_src_register_pointer(source, machine); 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return src[GET_SWZ(source->Swizzle, 0)]; 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch texel from texture. Use partial derivatives when possible. 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_texel(struct gl_context *ctx, 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program_machine *machine, 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct prog_instruction *inst, 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat texcoord[4], GLfloat lodBias, 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat color[4]) 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint unit = machine->Samplers[inst->TexSrcUnit]; 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note: we only have the right derivatives for fragment input attribs. 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (machine->NumDeriv > 0 && 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->SrcReg[0].File == PROGRAM_INPUT && 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) { 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* simple texture fetch for which we should have derivatives */ 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint attr = inst->SrcReg[0].Index; 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->FetchTexelDeriv(ctx, texcoord, 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->DerivX[attr], 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->DerivY[attr], 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lodBias, unit, color); 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->FetchTexelLod(ctx, texcoord, lodBias, unit, color); 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Test value against zero and return GT, LT, EQ or UN if NaN. 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLuint 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggenerate_cc(float value) 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (value != value) 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return COND_UN; /* NaN */ 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (value > 0.0F) 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return COND_GT; 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (value < 0.0F) 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return COND_LT; 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return COND_EQ; 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Test if the ccMaskRule is satisfied by the given condition code. 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used to mask destination writes according to the current condition code. 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLboolean 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtest_cc(GLuint condCode, GLuint ccMaskRule) 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (ccMaskRule) { 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case COND_EQ: return (condCode == COND_EQ); 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case COND_NE: return (condCode != COND_EQ); 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case COND_LT: return (condCode == COND_LT); 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case COND_GE: return (condCode == COND_GT || condCode == COND_EQ); 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case COND_LE: return (condCode == COND_LT || condCode == COND_EQ); 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case COND_GT: return (condCode == COND_GT); 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case COND_TR: return GL_TRUE; 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case COND_FL: return GL_FALSE; 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: return GL_TRUE; 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Evaluate the 4 condition codes against a predicate and return GL_TRUE 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or GL_FALSE to indicate result. 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLboolean 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgeval_condition(const struct gl_program_machine *machine, 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct prog_instruction *inst) 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint swizzle = inst->DstReg.CondSwizzle; 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint condMask = inst->DstReg.CondMask; 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Store 4 floats into a register. Observe the instructions saturate and 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * set-condition-code flags. 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstore_vector4(const struct prog_instruction *inst, 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program_machine *machine, const GLfloat value[4]) 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct prog_dst_register *dstReg = &(inst->DstReg); 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE; 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint writeMask = dstReg->WriteMask; 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat clampedValue[4]; 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat *dst = get_dst_register_pointer(dstReg, machine); 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (value[0] > 1.0e10 || 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IS_INF_OR_NAN(value[0]) || 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IS_INF_OR_NAN(value[1]) || 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IS_INF_OR_NAN(value[2]) || IS_INF_OR_NAN(value[3])) 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]); 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clamp) { 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F); 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F); 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F); 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F); 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org value = clampedValue; 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dstReg->CondMask != COND_TR) { 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* condition codes may turn off some writes */ 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_X) { 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)], 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstReg->CondMask)) 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writeMask &= ~WRITEMASK_X; 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Y) { 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)], 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstReg->CondMask)) 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writeMask &= ~WRITEMASK_Y; 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Z) { 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)], 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstReg->CondMask)) 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writeMask &= ~WRITEMASK_Z; 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_W) { 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)], 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstReg->CondMask)) 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writeMask &= ~WRITEMASK_W; 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef NAN_CHECK 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!IS_INF_OR_NAN(value[0])); 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!IS_INF_OR_NAN(value[0])); 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!IS_INF_OR_NAN(value[0])); 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!IS_INF_OR_NAN(value[0])); 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_X) 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[0] = value[0]; 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Y) 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[1] = value[1]; 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Z) 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[2] = value[2]; 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_W) 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[3] = value[3]; 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->CondUpdate) { 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_X) 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CondCodes[0] = generate_cc(value[0]); 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Y) 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CondCodes[1] = generate_cc(value[1]); 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Z) 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CondCodes[2] = generate_cc(value[2]); 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_W) 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CondCodes[3] = generate_cc(value[3]); 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_PROG 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("CondCodes=(%s,%s,%s,%s) for:\n", 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_condcode_string(machine->CondCodes[0]), 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_condcode_string(machine->CondCodes[1]), 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_condcode_string(machine->CondCodes[2]), 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_condcode_string(machine->CondCodes[3])); 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Store 4 uints into a register. Observe the set-condition-code flags. 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstore_vector4ui(const struct prog_instruction *inst, 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program_machine *machine, const GLuint value[4]) 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct prog_dst_register *dstReg = &(inst->DstReg); 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint writeMask = dstReg->WriteMask; 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint *dst = (GLuint *) get_dst_register_pointer(dstReg, machine); 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dstReg->CondMask != COND_TR) { 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* condition codes may turn off some writes */ 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_X) { 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)], 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstReg->CondMask)) 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writeMask &= ~WRITEMASK_X; 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Y) { 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)], 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstReg->CondMask)) 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writeMask &= ~WRITEMASK_Y; 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Z) { 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)], 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstReg->CondMask)) 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writeMask &= ~WRITEMASK_Z; 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_W) { 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)], 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstReg->CondMask)) 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writeMask &= ~WRITEMASK_W; 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_X) 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[0] = value[0]; 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Y) 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[1] = value[1]; 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Z) 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[2] = value[2]; 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_W) 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[3] = value[3]; 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->CondUpdate) { 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_X) 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CondCodes[0] = generate_cc((float)value[0]); 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Y) 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CondCodes[1] = generate_cc((float)value[1]); 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_Z) 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CondCodes[2] = generate_cc((float)value[2]); 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writeMask & WRITEMASK_W) 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CondCodes[3] = generate_cc((float)value[3]); 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_PROG 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("CondCodes=(%s,%s,%s,%s) for:\n", 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_condcode_string(machine->CondCodes[0]), 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_condcode_string(machine->CondCodes[1]), 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_condcode_string(machine->CondCodes[2]), 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_condcode_string(machine->CondCodes[3])); 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Execute the given vertex/fragment program. 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx rendering context 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param program the program to execute 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param machine machine state (must be initialized) 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLboolean 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_execute_program(struct gl_context * ctx, 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program *program, 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program_machine *machine) 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint numInst = program->NumInstructions; 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint maxExec = 65536; 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint pc, numExec = 0; 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CurProgram = program; 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("execute program %u --------------------\n", program->Id); 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (program->Target == GL_VERTEX_PROGRAM_ARB) { 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->EnvParams = ctx->VertexProgram.Parameters; 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->EnvParams = ctx->FragmentProgram.Parameters; 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (pc = 0; pc < numInst; pc++) { 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct prog_instruction *inst = program->Instructions + pc; 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_print_instruction(inst); 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (inst->Opcode) { 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_ABS: 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = FABSF(a[0]); 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = FABSF(a[1]); 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = FABSF(a[2]); 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = FABSF(a[3]); 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_ADD: 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] + b[0]; 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] + b[1]; 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] + b[2]; 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] + b[3]; 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_AND: /* bitwise AND */ 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint a[4], b[4], result[4]; 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4ui(&inst->SrcReg[0], machine, a); 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4ui(&inst->SrcReg[1], machine, b); 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] & b[0]; 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] & b[1]; 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] & b[2]; 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] & b[3]; 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4ui(inst, machine, result); 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_ARL: 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat t[4]; 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, t); 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->AddressReg[0][0] = IFLOOR(t[0]); 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("ARL %d\n", machine->AddressReg[0][0]); 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_BGNLOOP: 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no-op */ 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(program->Instructions[inst->BranchTarget].Opcode 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org == OPCODE_ENDLOOP); 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_ENDLOOP: 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* subtract 1 here since pc is incremented by for(pc) loop */ 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(program->Instructions[inst->BranchTarget].Opcode 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org == OPCODE_BGNLOOP); 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_BGNSUB: /* begin subroutine */ 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_ENDSUB: /* end subroutine */ 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_BRA: /* branch (conditional) */ 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (eval_condition(machine, inst)) { 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* take branch */ 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Subtract 1 here since we'll do pc++ below */ 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pc = inst->BranchTarget - 1; 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_BRK: /* break out of loop (conditional) */ 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(program->Instructions[inst->BranchTarget].Opcode 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org == OPCODE_ENDLOOP); 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (eval_condition(machine, inst)) { 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* break out of loop */ 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* pc++ at end of for-loop will put us after the ENDLOOP inst */ 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pc = inst->BranchTarget; 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_CONT: /* continue loop (conditional) */ 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(program->Instructions[inst->BranchTarget].Opcode 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org == OPCODE_ENDLOOP); 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (eval_condition(machine, inst)) { 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* continue at ENDLOOP */ 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Subtract 1 here since we'll do pc++ at end of for-loop */ 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pc = inst->BranchTarget - 1; 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_CAL: /* Call subroutine (conditional) */ 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (eval_condition(machine, inst)) { 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* call the subroutine */ 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->CallStack[machine->StackDepth++] = pc + 1; /* next inst */ 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Subtract 1 here since we'll do pc++ at end of for-loop */ 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pc = inst->BranchTarget - 1; 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_CMP: 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], c[4], result[4]; 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[2], machine, c); 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] < 0.0F ? b[0] : c[0]; 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] < 0.0F ? b[1] : c[1]; 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] < 0.0F ? b[2] : c[2]; 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] < 0.0F ? b[3] : c[3]; 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("CMP (%g %g %g %g) = (%g %g %g %g) < 0 ? (%g %g %g %g) : (%g %g %g %g)\n", 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3], 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c[0], c[1], c[2], c[3]); 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_COS: 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org = (GLfloat) cos(a[0]); 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_DDX: /* Partial derivative with respect to X */ 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat result[4]; 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine, 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 'X', result); 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_DDY: /* Partial derivative with respect to Y */ 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat result[4]; 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine, 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 'Y', result); 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_DP2: 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = DOT2(a, b); 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("DP2 %g = (%g %g) . (%g %g)\n", 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], a[0], a[1], b[0], b[1]); 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_DP2A: 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], c, result[4]; 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[1], machine, &c); 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = DOT2(a, b) + c; 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("DP2A %g = (%g %g) . (%g %g) + %g\n", 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], a[0], a[1], b[0], b[1], c); 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_DP3: 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = DOT3(a, b); 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], a[0], a[1], a[2], b[0], b[1], b[2]); 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_DP4: 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = DOT4(a, b); 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], a[0], a[1], a[2], a[3], 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3]); 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_DPH: 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = DOT3(a, b) + b[3]; 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_DST: /* Distance vector */ 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1.0F; 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] * b[1]; 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2]; 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = b[3]; 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_EXP: 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat t[4], q[4], floor_t0; 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, t); 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floor_t0 = FLOORF(t[0]); 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floor_t0 > FLT_MAX_EXP) { 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_POS_INFINITY(q[0]); 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_POS_INFINITY(q[2]); 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (floor_t0 < FLT_MIN_EXP) { 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[0] = 0.0F; 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[2] = 0.0F; 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[0] = LDEXPF(1.0, (int) floor_t0); 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note: GL_NV_vertex_program expects 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * result.z = result.x * APPX(result.y) 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We do what the ARB extension says. 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[2] = (GLfloat) pow(2.0, t[0]); 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[1] = t[0] - floor_t0; 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[3] = 1.0F; 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4( inst, machine, q ); 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_EX2: /* Exponential base 2 */ 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4], val; 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = (GLfloat) pow(2.0, a[0]); 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (IS_INF_OR_NAN(val)) 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = 1.0e10; 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = val; 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_FLR: 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = FLOORF(a[0]); 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = FLOORF(a[1]); 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = FLOORF(a[2]); 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = FLOORF(a[3]); 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_FRC: 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] - FLOORF(a[0]); 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] - FLOORF(a[1]); 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] - FLOORF(a[2]); 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] - FLOORF(a[3]); 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_IF: 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLboolean cond; 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(program->Instructions[inst->BranchTarget].Opcode 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org == OPCODE_ELSE || 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org program->Instructions[inst->BranchTarget].Opcode 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org == OPCODE_ENDIF); 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* eval condition */ 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4]; 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cond = (a[0] != 0.0); 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cond = eval_condition(machine, inst); 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("IF: %d\n", cond); 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* do if/else */ 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cond) { 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* do if-clause (just continue execution) */ 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* go to the instruction after ELSE or ENDIF */ 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(inst->BranchTarget >= 0); 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pc = inst->BranchTarget; 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_ELSE: 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* goto ENDIF */ 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(program->Instructions[inst->BranchTarget].Opcode 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org == OPCODE_ENDIF); 982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(inst->BranchTarget >= 0); 983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pc = inst->BranchTarget; 984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_ENDIF: 986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* nothing */ 987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_KIL_NV: /* NV_f_p only (conditional) */ 989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (eval_condition(machine, inst)) { 990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_KIL: /* ARB_f_p only */ 994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4]; 996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("KIL if (%g %g %g %g) <= 0.0\n", 999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3]); 1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) { 1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_LG2: /* log base 2 */ 1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4], val; 1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The fast LOG2 macro doesn't meet the precision requirements. 1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a[0] == 0.0F) { 1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = -FLT_MAX; 1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = (float)(log(a[0]) * 1.442695F); 1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = val; 1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_LIT: 1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */ 1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0] = MAX2(a[0], 0.0F); 1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[1] = MAX2(a[1], 0.0F); 1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX ARB version clamps a[3], NV version doesn't */ 1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon)); 1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1.0F; 1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[0]; 1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX we could probably just use pow() here */ 1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a[0] > 0.0F) { 1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a[1] == 0.0 && a[3] == 0.0) 1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 1.0F; 1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (GLfloat) pow(a[1], a[3]); 1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 0.0F; 1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = 1.0F; 1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", 1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3]); 1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_LOG: 1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat t[4], q[4], abs_t0; 1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, t); 1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org abs_t0 = FABSF(t[0]); 1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (abs_t0 != 0.0F) { 1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Since we really can't handle infinite values on VMS 1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * like other OSes we'll use __MAXFLOAT to represent 1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * infinity. This may need some tweaking. 1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef VMS 1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (abs_t0 == __MAXFLOAT) 1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (IS_INF_OR_NAN(abs_t0)) 1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_POS_INFINITY(q[0]); 1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[1] = 1.0F; 1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_POS_INFINITY(q[2]); 1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int exponent; 1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat mantissa = FREXPF(t[0], &exponent); 1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[0] = (GLfloat) (exponent - 1); 1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */ 1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The fast LOG2 macro doesn't meet the precision 1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * requirements. 1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[2] = (float)(log(t[0]) * 1.442695F); 1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_NEG_INFINITY(q[0]); 1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[1] = 1.0F; 1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_NEG_INFINITY(q[2]); 1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org q[3] = 1.0; 1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, q); 1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_LRP: 1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], c[4], result[4]; 1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[2], machine, c); 1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0]; 1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1]; 1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; 1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; 1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("LRP (%g %g %g %g) = (%g %g %g %g), " 1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "(%g %g %g %g), (%g %g %g %g)\n", 1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], 1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]); 1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_MAD: 1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], c[4], result[4]; 1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[2], machine, c); 1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] * b[0] + c[0]; 1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] * b[1] + c[1]; 1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] * b[2] + c[2]; 1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] * b[3] + c[3]; 1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("MAD (%g %g %g %g) = (%g %g %g %g) * " 1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "(%g %g %g %g) + (%g %g %g %g)\n", 1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], 1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]); 1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_MAX: 1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = MAX2(a[0], b[0]); 1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = MAX2(a[1], b[1]); 1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = MAX2(a[2], b[2]); 1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = MAX2(a[3], b[3]); 1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", 1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); 1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_MIN: 1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = MIN2(a[0], b[0]); 1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = MIN2(a[1], b[1]); 1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = MIN2(a[2], b[2]); 1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = MIN2(a[3], b[3]); 1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_MOV: 1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat result[4]; 1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, result); 1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("MOV (%g %g %g %g)\n", 1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3]); 1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_MUL: 1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] * b[0]; 1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] * b[1]; 1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] * b[2]; 1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] * b[3]; 1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", 1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); 1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_NOISE1: 1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = 1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = _mesa_noise1(a[0]); 1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_NOISE2: 1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = 1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = result[3] = _mesa_noise2(a[0], a[1]); 1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_NOISE3: 1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = 1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = _mesa_noise3(a[0], a[1], a[2]); 1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_NOISE4: 1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = 1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = _mesa_noise4(a[0], a[1], a[2], a[3]); 1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_NOP: 1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_NOT: /* bitwise NOT */ 1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint a[4], result[4]; 1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4ui(&inst->SrcReg[0], machine, a); 1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = ~a[0]; 1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = ~a[1]; 1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = ~a[2]; 1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = ~a[3]; 1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4ui(inst, machine, result); 1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_NRM3: /* 3-component normalization */ 1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat tmp; 1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2]; 1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp != 0.0F) 1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp = INV_SQRTF(tmp); 1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = tmp * a[0]; 1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = tmp * a[1]; 1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = tmp * a[2]; 1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = 0.0; /* undefined, but prevent valgrind warnings */ 1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_NRM4: /* 4-component normalization */ 1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat tmp; 1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]; 1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp != 0.0F) 1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp = INV_SQRTF(tmp); 1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = tmp * a[0]; 1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = tmp * a[1]; 1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = tmp * a[2]; 1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = tmp * a[3]; 1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_OR: /* bitwise OR */ 1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint a[4], b[4], result[4]; 1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4ui(&inst->SrcReg[0], machine, a); 1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4ui(&inst->SrcReg[1], machine, b); 1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] | b[0]; 1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] | b[1]; 1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] | b[2]; 1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] | b[3]; 1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4ui(inst, machine, result); 1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ 1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4]; 1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint result[4]; 1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLhalfNV hx, hy; 1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hx = _mesa_float_to_half(a[0]); 1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hy = _mesa_float_to_half(a[1]); 1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = 1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = hx | (hy << 16); 1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4ui(inst, machine, result); 1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ 1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4]; 1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint result[4], usx, usy; 1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0] = CLAMP(a[0], 0.0F, 1.0F); 1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[1] = CLAMP(a[1], 0.0F, 1.0F); 1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usx = F_TO_I(a[0] * 65535.0F); 1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usy = F_TO_I(a[1] * 65535.0F); 1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = 1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = usx | (usy << 16); 1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4ui(inst, machine, result); 1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ 1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4]; 1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint result[4], ubx, uby, ubz, ubw; 1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F); 1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); 1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); 1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); 1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubx = F_TO_I(127.0F * a[0] + 128.0F); 1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uby = F_TO_I(127.0F * a[1] + 128.0F); 1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubz = F_TO_I(127.0F * a[2] + 128.0F); 1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubw = F_TO_I(127.0F * a[3] + 128.0F); 1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = 1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); 1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4ui(inst, machine, result); 1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ 1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4]; 1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint result[4], ubx, uby, ubz, ubw; 1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0] = CLAMP(a[0], 0.0F, 1.0F); 1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[1] = CLAMP(a[1], 0.0F, 1.0F); 1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[2] = CLAMP(a[2], 0.0F, 1.0F); 1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[3] = CLAMP(a[3], 0.0F, 1.0F); 1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubx = F_TO_I(255.0F * a[0]); 1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uby = F_TO_I(255.0F * a[1]); 1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubz = F_TO_I(255.0F * a[2]); 1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubw = F_TO_I(255.0F * a[3]); 1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = 1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = 1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); 1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4ui(inst, machine, result); 1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_POW: 1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[1], machine, b); 1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] 1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org = (GLfloat) pow(a[0], b[0]); 1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_RCC: /* clamped riciprocal */ 1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float largest = 1.884467e+19, smallest = 5.42101e-20; 1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], r, result[4]; 1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a[0] == 0) 1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("RCC(0)\n"); 1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (IS_INF_OR_NAN(a[0])) 1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("RCC(inf)\n"); 1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a[0] == 1.0F) { 1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r = 1.0F; 1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r = 1.0F / a[0]; 1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (positive(r)) { 1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (r > largest) { 1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r = largest; 1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (r < smallest) { 1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r = smallest; 1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (r < -largest) { 1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r = -largest; 1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (r > -smallest) { 1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r = -smallest; 1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = r; 1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_RCP: 1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (a[0] == 0) 1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("RCP(0)\n"); 1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (IS_INF_OR_NAN(a[0])) 1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("RCP(inf)\n"); 1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; 1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_RET: /* return from subroutine (conditional) */ 1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (eval_condition(machine, inst)) { 1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (machine->StackDepth == 0) { 1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ 1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* subtract one because of pc++ in the for loop */ 1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pc = machine->CallStack[--machine->StackDepth] - 1; 1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_RFL: /* reflection vector */ 1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat axis[4], dir[4], result[4], tmpX, tmpW; 1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, axis); 1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, dir); 1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpW = DOT3(axis, axis); 1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpX = (2.0F * DOT3(axis, dir)) / tmpW; 1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = tmpX * axis[0] - dir[0]; 1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = tmpX * axis[1] - dir[1]; 1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = tmpX * axis[2] - dir[2]; 1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* result[3] is never written! XXX enforce in parser! */ 1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_RSQ: /* 1 / sqrt() */ 1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0] = FABSF(a[0]); 1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); 1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); 1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SCS: /* sine and cos */ 1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (GLfloat) cos(a[0]); 1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (GLfloat) sin(a[0]); 1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = 0.0; /* undefined! */ 1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = 0.0; /* undefined! */ 1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SEQ: /* set on equal */ 1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (a[0] == b[0]) ? 1.0F : 0.0F; 1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (a[1] == b[1]) ? 1.0F : 0.0F; 1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (a[2] == b[2]) ? 1.0F : 0.0F; 1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = (a[3] == b[3]) ? 1.0F : 0.0F; 1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("SEQ (%g %g %g %g) = (%g %g %g %g) == (%g %g %g %g)\n", 1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], 1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3]); 1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SFL: /* set false, operands ignored */ 1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; 1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SGE: /* set on greater or equal */ 1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F; 1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F; 1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F; 1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F; 1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("SGE (%g %g %g %g) = (%g %g %g %g) >= (%g %g %g %g)\n", 1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], 1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3]); 1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SGT: /* set on greater */ 1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (a[0] > b[0]) ? 1.0F : 0.0F; 1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (a[1] > b[1]) ? 1.0F : 0.0F; 1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (a[2] > b[2]) ? 1.0F : 0.0F; 1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = (a[3] > b[3]) ? 1.0F : 0.0F; 1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("SGT (%g %g %g %g) = (%g %g %g %g) > (%g %g %g %g)\n", 1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], 1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3]); 1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SIN: 1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector1(&inst->SrcReg[0], machine, a); 1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[1] = result[2] = result[3] 1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org = (GLfloat) sin(a[0]); 1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SLE: /* set on less or equal */ 1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F; 1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F; 1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F; 1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F; 1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("SLE (%g %g %g %g) = (%g %g %g %g) <= (%g %g %g %g)\n", 1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], 1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3]); 1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SLT: /* set on less */ 1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (a[0] < b[0]) ? 1.0F : 0.0F; 1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (a[1] < b[1]) ? 1.0F : 0.0F; 1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (a[2] < b[2]) ? 1.0F : 0.0F; 1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = (a[3] < b[3]) ? 1.0F : 0.0F; 1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("SLT (%g %g %g %g) = (%g %g %g %g) < (%g %g %g %g)\n", 1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], 1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3]); 1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SNE: /* set on not equal */ 1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (a[0] != b[0]) ? 1.0F : 0.0F; 1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (a[1] != b[1]) ? 1.0F : 0.0F; 1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (a[2] != b[2]) ? 1.0F : 0.0F; 1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = (a[3] != b[3]) ? 1.0F : 0.0F; 1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("SNE (%g %g %g %g) = (%g %g %g %g) != (%g %g %g %g)\n", 1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], 1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b[0], b[1], b[2], b[3]); 1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SSG: /* set sign (-1, 0 or +1) */ 1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (GLfloat) ((a[0] > 0.0F) - (a[0] < 0.0F)); 1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (GLfloat) ((a[1] > 0.0F) - (a[1] < 0.0F)); 1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (GLfloat) ((a[2] > 0.0F) - (a[2] < 0.0F)); 1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = (GLfloat) ((a[3] > 0.0F) - (a[3] < 0.0F)); 1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_STR: /* set true, operands ignored */ 1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F }; 1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SUB: 1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] - b[0]; 1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] - b[1]; 1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] - b[2]; 1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] - b[3]; 1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", 1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); 1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_SWZ: /* extended swizzle */ 1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct prog_src_register *source = &inst->SrcReg[0]; 1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat *src = get_src_register_pointer(source, machine); 1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat result[4]; 1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i; 1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < 4; i++) { 1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint swz = GET_SWZ(source->Swizzle, i); 1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (swz == SWIZZLE_ZERO) 1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[i] = 0.0; 1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (swz == SWIZZLE_ONE) 1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[i] = 1.0; 1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(swz >= 0); 1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(swz <= 3); 1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[i] = src[swz]; 1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (source->Negate & (1 << i)) 1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[i] = -result[i]; 1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_TEX: /* Both ARB and NV frag prog */ 1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Simple texel lookup */ 1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat texcoord[4], color[4]; 1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For TEX, texcoord.Q should not be used and its value should not 1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * matter (at most, we pass coord.xyz to texture3D() in GLSL). 1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set Q=1 so that FetchTexelDeriv() doesn't get a garbage value 1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * which is effectively what happens when the texcoord swizzle 1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is .xyzz 1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[3] = 1.0f; 1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_texel(ctx, machine, inst, texcoord, 0.0, color); 1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g]\n", 1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org color[0], color[1], color[2], color[3], 1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->TexSrcUnit, 1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[0], texcoord[1], texcoord[2], texcoord[3]); 1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, color); 1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_TXB: /* GL_ARB_fragment_program only */ 1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Texel lookup with LOD bias */ 1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat texcoord[4], color[4], lodBias; 1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* texcoord[3] is the bias to add to lambda */ 1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lodBias = texcoord[3]; 1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_texel(ctx, machine, inst, texcoord, lodBias, color); 1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("TXB (%g, %g, %g, %g) = texture[%d][%g %g %g %g]" 1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org " bias %g\n", 1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org color[0], color[1], color[2], color[3], 1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->TexSrcUnit, 1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[0], 1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[1], 1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[2], 1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[3], 1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lodBias); 1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, color); 1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_TXD: /* GL_NV_fragment_program only */ 1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Texture lookup w/ partial derivatives for LOD */ 1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat texcoord[4], dtdx[4], dtdy[4], color[4]; 1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, dtdx); 1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[2], machine, dtdy); 1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy, 1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0.0, /* lodBias */ 1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->TexSrcUnit, color); 1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, color); 1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_TXL: 1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Texel lookup with explicit LOD */ 1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat texcoord[4], color[4], lod; 1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* texcoord[3] is the LOD */ 1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lod = texcoord[3]; 1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->FetchTexelLod(ctx, texcoord, lod, 1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org machine->Samplers[inst->TexSrcUnit], color); 1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, color); 1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_TXP: /* GL_ARB_fragment_program only */ 1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Texture lookup w/ projective divide */ 1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat texcoord[4], color[4]; 1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Not so sure about this test - if texcoord[3] is 1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * zero, we'd probably be fine except for an ASSERT in 1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IROUND_POS() which gets triggered by the inf values created. 1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (texcoord[3] != 0.0) { 1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[0] /= texcoord[3]; 1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[1] /= texcoord[3]; 1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[2] /= texcoord[3]; 1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_texel(ctx, machine, inst, texcoord, 0.0, color); 1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, color); 1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ 1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Texture lookup w/ projective divide, as above, but do not 1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * do the divide by w if sampling from a cube map. 1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat texcoord[4], color[4]; 1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, texcoord); 1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && 1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[3] != 0.0) { 1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[0] /= texcoord[3]; 1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[1] /= texcoord[3]; 1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texcoord[2] /= texcoord[3]; 1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_texel(ctx, machine, inst, texcoord, 0.0, color); 1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, color); 1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_TRUNC: /* truncate toward zero */ 1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], result[4]; 1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (GLfloat) (GLint) a[0]; 1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (GLfloat) (GLint) a[1]; 1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (GLfloat) (GLint) a[2]; 1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = (GLfloat) (GLint) a[3]; 1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_UP2H: /* unpack two 16-bit floats */ 1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); 1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat result[4]; 1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLushort hx, hy; 1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hx = raw & 0xffff; 1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hy = raw >> 16; 1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[2] = _mesa_half_to_float(hx); 1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = result[3] = _mesa_half_to_float(hy); 1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_UP2US: /* unpack two GLushorts */ 1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); 1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat result[4]; 1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLushort usx, usy; 1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usx = raw & 0xffff; 1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usy = raw >> 16; 1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = result[2] = usx * (1.0f / 65535.0f); 1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = result[3] = usy * (1.0f / 65535.0f); 1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_UP4B: /* unpack four GLbytes */ 1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); 1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat result[4]; 1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = (((raw >> 0) & 0xff) - 128) / 127.0F; 1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = (((raw >> 8) & 0xff) - 128) / 127.0F; 1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = (((raw >> 16) & 0xff) - 128) / 127.0F; 1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = (((raw >> 24) & 0xff) - 128) / 127.0F; 1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_UP4UB: /* unpack four GLubytes */ 1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); 1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat result[4]; 1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = ((raw >> 0) & 0xff) / 255.0F; 1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = ((raw >> 8) & 0xff) / 255.0F; 1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = ((raw >> 16) & 0xff) / 255.0F; 1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = ((raw >> 24) & 0xff) / 255.0F; 1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_XOR: /* bitwise XOR */ 1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint a[4], b[4], result[4]; 1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4ui(&inst->SrcReg[0], machine, a); 1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4ui(&inst->SrcReg[1], machine, b); 1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] ^ b[0]; 1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] ^ b[1]; 1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] ^ b[2]; 1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] ^ b[3]; 1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4ui(inst, machine, result); 1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_XPD: /* cross product */ 1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], result[4]; 1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[1] * b[2] - a[2] * b[1]; 1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[2] * b[0] - a[0] * b[2]; 1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[0] * b[1] - a[1] * b[0]; 1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = 1.0; 1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUG_PROG) { 1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("XPD (%g %g %g %g) = (%g %g %g) X (%g %g %g)\n", 1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0], result[1], result[2], result[3], 1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], b[0], b[1], b[2]); 1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_X2D: /* 2-D matrix transform */ 1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4], b[4], c[4], result[4]; 1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[1], machine, b); 1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[2], machine, c); 1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[0] = a[0] + b[0] * c[0] + b[1] * c[1]; 1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[1] = a[1] + b[0] * c[2] + b[1] * c[3]; 1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[2] = a[2] + b[0] * c[0] + b[1] * c[1]; 1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[3] = a[3] + b[0] * c[2] + b[1] * c[3]; 1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store_vector4(inst, machine, result); 1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_PRINT: 1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { 1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat a[4]; 1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fetch_vector4(&inst->SrcReg[0], machine, a); 1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, 1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[0], a[1], a[2], a[3]); 1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("%s\n", (const char *) inst->Data); 1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_END: 1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_problem(ctx, "Bad opcode %d in _mesa_execute_program", 1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Opcode); 1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; /* return value doesn't matter */ 1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numExec++; 1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (numExec > maxExec) { 1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static GLboolean reported = GL_FALSE; 1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!reported) { 1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_problem(ctx, "Infinite loop detected in fragment program"); 1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reported = GL_TRUE; 1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } /* for pc */ 1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1904