t_vp_build.c revision 9248882ca27b289180a76262aa3d9b26c0cb0e8b
128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/* 228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Mesa 3-D graphics library 34cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org * Version: 6.5 428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Copyright (C) 2006 Tungsten Graphics All Rights Reserved. 628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Permission is hereby granted, free of charge, to any person obtaining a 828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * copy of this software and associated documentation files (the "Software"), 928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * to deal in the Software without restriction, including without limitation 1028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * and/or sell copies of the Software, and to permit persons to whom the 1228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Software is furnished to do so, subject to the following conditions: 1328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 1428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * The above copyright notice and this permission notice shall be included 1528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * in all copies or substantial portions of the Software. 1628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 1728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * TUNGSTEN GRAPHICS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 2128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WHETHER IN 2228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 2528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/** 2728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * \file t_vp_build.c 2828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Create a vertex program to execute the current fixed function T&L pipeline. 2928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * \author Keith Whitwell 3028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 3128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org#include "glheader.h" 3440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org#include "macros.h" 3528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "enums.h" 364551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org#include "t_context.h" 374551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org#include "t_vp_build.h" 3828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "shader/program.h" 4028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "shader/program_instruction.h" 4128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstruct state_key { 434cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org unsigned light_global_enabled:1; 444cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org unsigned light_local_viewer:1; 4528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned light_twoside:1; 46b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org unsigned light_color_material:1; 4728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned light_color_material_mask:12; 4828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned light_material_mask:12; 49b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned normalize:1; 5128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned rescale_normals:1; 5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned fog_source_is_depth:1; 53b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org unsigned tnl_do_vertex_fog:1; 5440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org unsigned separate_specular:1; 5540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org unsigned fog_mode:2; 5628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned point_attenuated:1; 5728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned texture_enabled_global:1; 5828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned fragprog_inputs_read:12; 5928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct { 6128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned light_enabled:1; 6228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned light_eyepos3_is_zero:1; 6328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned light_spotcutoff_is_180:1; 6428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned light_attenuated:1; 6528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned texunit_really_enabled:1; 6628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned texmat_enabled:1; 6728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned texgen_enabled:4; 6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned texgen_mode0:4; 6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org unsigned texgen_mode1:4; 7097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org unsigned texgen_mode2:4; 714cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org unsigned texgen_mode3:4; 724cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } unit[8]; 7397077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org}; 7497077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define FOG_NONE 0 7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define FOG_LINEAR 1 794551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org#define FOG_EXP 2 8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define FOG_EXP2 3 8140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic GLuint translate_fog_mode( GLenum mode ) 834cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 844cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org switch (mode) { 854cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org case GL_LINEAR: return FOG_LINEAR; 864cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org case GL_EXP: return FOG_EXP; 8728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case GL_EXP2: return FOG_EXP2; 884551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org default: return FOG_NONE; 8928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 9028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 9128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define TXG_NONE 0 9328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define TXG_OBJ_LINEAR 1 9428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define TXG_EYE_LINEAR 2 9528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define TXG_SPHERE_MAP 3 9628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define TXG_REFLECTION_MAP 4 97b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org#define TXG_NORMAL_MAP 5 9828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic GLuint translate_texgen( GLboolean enabled, GLenum mode ) 10040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 10140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (!enabled) 10240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org return TXG_NONE; 10340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 10440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org switch (mode) { 10540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org case GL_OBJECT_LINEAR: return TXG_OBJ_LINEAR; 10640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org case GL_EYE_LINEAR: return TXG_EYE_LINEAR; 10740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org case GL_SPHERE_MAP: return TXG_SPHERE_MAP; 10840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org case GL_REFLECTION_MAP_NV: return TXG_REFLECTION_MAP; 10940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org case GL_NORMAL_MAP_NV: return TXG_NORMAL_MAP; 11040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org default: return TXG_NONE; 11140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 11240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 11340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 11440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic struct state_key *make_state_key( GLcontext *ctx ) 11540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 11640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org TNLcontext *tnl = TNL_CONTEXT(ctx); 11740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct vertex_buffer *VB = &tnl->vb; 11840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org const struct fragment_program *fp = ctx->FragmentProgram._Current; 11940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct state_key *key = CALLOC_STRUCT(state_key); 12040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLuint i; 12140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 12240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* This now relies on texenvprogram.c being active: 12340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org */ 1244cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org assert(fp); 12540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 12640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->fragprog_inputs_read = fp->Base.InputsRead; 1274cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 12840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->separate_specular = (ctx->Light.Model.ColorControl == 12940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GL_SEPARATE_SPECULAR_COLOR); 13040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 13140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (ctx->Light.Enabled) { 13240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->light_global_enabled = 1; 13340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 13440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (ctx->Light.Model.LocalViewer) 13540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->light_local_viewer = 1; 13640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 13740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (ctx->Light.Model.TwoSide) 13840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->light_twoside = 1; 13940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 14040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (ctx->Light.ColorMaterialEnabled) { 14140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->light_color_material = 1; 142b90991dade9139e5c14c3b616a9eff07b9d6fddahenrike@webrtc.org key->light_color_material_mask = ctx->Light.ColorMaterialBitmask; 143b90991dade9139e5c14c3b616a9eff07b9d6fddahenrike@webrtc.org } 144b90991dade9139e5c14c3b616a9eff07b9d6fddahenrike@webrtc.org 14540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) 14640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (VB->AttribPtr[i]->stride) 14740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->light_material_mask |= 1<<(i-_TNL_ATTRIB_MAT_FRONT_AMBIENT); 14840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 14940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org for (i = 0; i < MAX_LIGHTS; i++) { 15040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct gl_light *light = &ctx->Light.Light[i]; 15140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 1524551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (light->Enabled) { 1534551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org key->unit[i].light_enabled = 1; 15440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 1554551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (light->EyePosition[3] == 0.0) 1564551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org key->unit[i].light_eyepos3_is_zero = 1; 1574551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 1584551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (light->SpotCutoff == 180.0) 1594551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org key->unit[i].light_spotcutoff_is_180 = 1; 1604551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 1614551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (light->ConstantAttenuation != 1.0 || 1624551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org light->LinearAttenuation != 0.0 || 1634551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org light->QuadraticAttenuation != 0.0) 16428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key->unit[i].light_attenuated = 1; 16540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 16628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 16728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 16828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 16928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (ctx->Transform.Normalize) 17028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key->normalize = 1; 17128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 17228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (ctx->Transform.RescaleNormals) 1734551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org key->rescale_normals = 1; 1744551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 1754551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org key->fog_mode = translate_fog_mode(fp->FogOption); 17628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 17728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) 17828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key->fog_source_is_depth = 1; 17928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 18028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (tnl->_DoVertexFog) 18128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key->tnl_do_vertex_fog = 1; 18228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 18328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (ctx->Point._Attenuated) 18440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->point_attenuated = 1; 18540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 18628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (ctx->Texture._TexGenEnabled || 18728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ctx->Texture._TexMatEnabled || 18828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ctx->Texture._EnabledUnits) 18928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key->texture_enabled_global = 1; 19028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 19128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 19228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 19328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 19428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (texUnit->_ReallyEnabled) 19528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key->unit[i].texunit_really_enabled = 1; 19640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 19740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) 19828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key->unit[i].texmat_enabled = 1; 19928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 20028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (texUnit->TexGenEnabled) { 20128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key->unit[i].texgen_enabled = 1; 20228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 20328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key->unit[i].texgen_mode0 = 20428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org translate_texgen( texUnit->TexGenEnabled & (1<<0), 20528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org texUnit->GenModeS ); 20640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->unit[i].texgen_mode1 = 20728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org translate_texgen( texUnit->TexGenEnabled & (1<<1), 20828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org texUnit->GenModeT ); 20940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->unit[i].texgen_mode2 = 21028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org translate_texgen( texUnit->TexGenEnabled & (1<<2), 21128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org texUnit->GenModeR ); 21240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org key->unit[i].texgen_mode3 = 21328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org translate_texgen( texUnit->TexGenEnabled & (1<<3), 21428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org texUnit->GenModeQ ); 21540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 21628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 21728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2184551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org return key; 2194551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org} 2204551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 2214551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 2224551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 2234551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org/* Very useful debugging tool - produces annotated listing of 2244551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * generated program with line/function references for each 2254551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * instruction back into this file: 2264551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org */ 2274551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org#define DISASSEM (MESA_VERBOSE&VERBOSE_DISASSEM) 2284551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 2294551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org/* Should be tunable by the driver - do we want to do matrix 2304551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * multiplications with DP4's or with MUL/MAD's? SSE works better 2314551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * with the latter, drivers may differ. 23240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org */ 2334551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org#define PREFER_DP4 0 2344551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 2354551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org#define MAX_INSN 256 2364551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 2374551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org/* Use uregs to represent registers internally, translate to Mesa's 23840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org * expected formats on emit. 2394551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * 24019f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org * NOTE: These are passed by value extensively in this file rather 2414551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * than as usual by pointer reference. If this disturbs you, try 2424551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * remembering they are just 32bits in size. 24340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org * 2444551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * GCC is smart enough to deal with these dword-sized structures in 2454551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * much the same way as if I had defined them as dwords and was using 2464551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * macros to access and set the fields. This is much nicer and easier 24719f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org * to evolve. 24819f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org */ 24919f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.orgstruct ureg { 25019f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org GLuint file:4; 25140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLint idx:8; /* relative addressing may be negative */ 25219f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org GLuint negate:1; 25319f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org GLuint swz:12; 25419f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org GLuint pad:7; 25519f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org}; 25619f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org 25719f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org 25819f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.orgstruct tnl_program { 25919f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org const struct state_key *state; 26040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct vertex_program *program; 26119f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org 26219f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org GLuint temp_in_use; 2634551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org GLuint temp_reserved; 2644551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 26540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg eye_position; 2664551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg eye_position_normalized; 2674551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg eye_normal; 2684551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg identity; 2694551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 2704551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org GLuint materials; 2714cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint color_materials; 2724cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org}; 2734cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 2743e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 2753e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.orgstatic const struct ureg undef = { 2763e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org ~0, 2774cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org ~0, 2783e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 0, 2793e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 0, 2804cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 0 2813e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org}; 2823e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 2834cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org/* Local shorthand: 2843e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org */ 2853e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org#define X SWIZZLE_X 2864cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org#define Y SWIZZLE_Y 2873e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org#define Z SWIZZLE_Z 2883e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org#define W SWIZZLE_W 2893e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 2904cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 2913e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org/* Construct a ureg: 2923e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org */ 2933e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.orgstatic struct ureg make_ureg(GLuint file, GLint idx) 2944cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 2953e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org struct ureg reg; 2963e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org reg.file = file; 2974cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org reg.idx = idx; 2983e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org reg.negate = 0; 2993e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org reg.swz = SWIZZLE_NOOP; 3004cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org reg.pad = 0; 3013e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org return reg; 3023e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org} 3034cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 3043e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 3053e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 3063e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.orgstatic struct ureg negate( struct ureg reg ) 3074cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 3083e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org reg.negate ^= 1; 3093e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org return reg; 3103e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org} 3114cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 3123e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 3133e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.orgstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 3144cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 3153e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 3163e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org GET_SWZ(reg.swz, y), 3174cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GET_SWZ(reg.swz, z), 3183e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org GET_SWZ(reg.swz, w)); 3193e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 3204cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org return reg; 3217e71b77f8aab5b7a6f2b669c16f90ec9a4b4609cbuildbot@webrtc.org} 3227e71b77f8aab5b7a6f2b669c16f90ec9a4b4609cbuildbot@webrtc.org 3233e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.orgstatic struct ureg swizzle1( struct ureg reg, int x ) 3243e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org{ 3253e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org return swizzle(reg, x, x, x, x); 32640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 32740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 32840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic struct ureg get_temp( struct tnl_program *p ) 32940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 33040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org int bit = _mesa_ffs( ~p->temp_in_use ); 33140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (!bit) { 33240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 33340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org _mesa_exit(1); 33440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 33540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 33640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if ((GLuint) bit > p->program->Base.NumTemporaries) 33740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org p->program->Base.NumTemporaries = bit; 33840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 339ffe2620c97c2b7bfe42b04453b5a981dbf1e5f06henrike@webrtc.org p->temp_in_use |= 1<<(bit-1); 340ffe2620c97c2b7bfe42b04453b5a981dbf1e5f06henrike@webrtc.org return make_ureg(PROGRAM_TEMPORARY, bit-1); 341ffe2620c97c2b7bfe42b04453b5a981dbf1e5f06henrike@webrtc.org} 34240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 34340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic struct ureg reserve_temp( struct tnl_program *p ) 34440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 34540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg temp = get_temp( p ); 34640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org p->temp_reserved |= 1<<temp.idx; 34740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org return temp; 34840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 34940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 35040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic void release_temp( struct tnl_program *p, struct ureg reg ) 35140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 35240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (reg.file == PROGRAM_TEMPORARY) { 35340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org p->temp_in_use &= ~(1<<reg.idx); 35440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org p->temp_in_use |= p->temp_reserved; /* can't release reserved temps */ 35540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 35640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 35740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 35840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic void release_temps( struct tnl_program *p ) 35940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 36040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org p->temp_in_use = p->temp_reserved; 36140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 36240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 36340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 36440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 36540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic struct ureg register_input( struct tnl_program *p, GLuint input ) 36640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 36740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org p->program->Base.InputsRead |= (1<<input); 36840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org return make_ureg(PROGRAM_INPUT, input); 36940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 37040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 37140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic struct ureg register_output( struct tnl_program *p, GLuint output ) 37240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 37340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org p->program->Base.OutputsWritten |= (1<<output); 37440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org return make_ureg(PROGRAM_OUTPUT, output); 37540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 37640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 37740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic struct ureg register_const4f( struct tnl_program *p, 37840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLfloat s0, 37940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLfloat s1, 3804cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLfloat s2, 3814cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLfloat s3) 3824cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 3834cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLfloat values[4]; 3844cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint idx; 3854cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org values[0] = s0; 3864cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org values[1] = s1; 3874cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org values[2] = s2; 3884cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org values[3] = s3; 3894cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values ); 3904cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org return make_ureg(PROGRAM_STATE_VAR, idx); 3914cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org} 3924cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 3934cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 3944cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) 3954cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 3964cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 3974cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 3984cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic GLboolean is_undef( struct ureg reg ) 3994cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 4004cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org return reg.file == 0xf; 4014cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org} 4024cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4034cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic struct ureg get_identity_param( struct tnl_program *p ) 4044cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 4054cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (is_undef(p->identity)) 4064cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p->identity = register_const4f(p, 0,0,0,1); 4074cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4084cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org return p->identity; 4094cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org} 4104cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4114cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic struct ureg register_param6( struct tnl_program *p, 4124cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint s0, 4134cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint s1, 4144cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint s2, 4154cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint s3, 4164cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint s4, 4174cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint s5) 4184cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 4194cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint tokens[6]; 4204cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint idx; 4214cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org tokens[0] = s0; 4224cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org tokens[1] = s1; 4234cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org tokens[2] = s2; 4244cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org tokens[3] = s3; 4254cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org tokens[4] = s4; 4264cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org tokens[5] = s5; 4274cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); 4284cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org return make_ureg(PROGRAM_STATE_VAR, idx); 4294cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org} 4304cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4314cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4324cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0) 43328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0) 43428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0) 43528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0) 43628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 43728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 43828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic void register_matrix_param6( struct tnl_program *p, 43928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLint s0, 44028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLint s1, 4414cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLint s2, 44228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLint s3, 44328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLint s4, 44428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLint s5, 44528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg *matrix ) 44697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org{ 44797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org GLint i; 44897077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 44997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org /* This is a bit sad as the support is there to pull the whole 45097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org * matrix out in one go: 45197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org */ 45297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org for (i = 0; i <= s4 - s3; i++) 45397077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org matrix[i] = register_param6( p, s0, s1, s2, i, i, s5 ); 45497077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org} 45597077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 45697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 45797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.orgstatic void emit_arg( struct prog_src_register *src, 45897077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org struct ureg reg ) 45997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org{ 46097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org src->File = reg.file; 4614cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org src->Index = reg.idx; 4624cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org src->Swizzle = reg.swz; 46397077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org src->NegateBase = reg.negate; 4644cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org src->Abs = 0; 46597077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org src->NegateAbs = 0; 4664cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org src->RelAddr = 0; 4674cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org} 4684cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4694cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic void emit_dst( struct prog_dst_register *dst, 47097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org struct ureg reg, GLuint mask ) 47197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org{ 4724cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org dst->File = reg.file; 4734cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org dst->Index = reg.idx; 4744cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org /* allow zero as a shorthand for xyzw */ 4754cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org dst->WriteMask = mask ? mask : WRITEMASK_XYZW; 4764cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org dst->CondMask = COND_TR; 4774cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org dst->CondSwizzle = 0; 4784cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org dst->CondSrc = 0; 4794cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org dst->pad = 0; 4804cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org} 4814cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4824cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic void debug_insn( struct prog_instruction *inst, const char *fn, 4834cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint line ) 4844cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 4854cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (DISASSEM) { 48640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org static const char *last_fn; 48740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 48840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (fn != last_fn) { 4894cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org last_fn = fn; 4904cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org _mesa_printf("%s:\n", fn); 49140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 4924cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4934cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org _mesa_printf("%d:\t", line); 49440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org _mesa_print_instruction(inst); 4954cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 4964cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org} 4974cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4984cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 4994cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic void emit_op3fn(struct tnl_program *p, 5004cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint op, 5014cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg dest, 5024cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint mask, 5034cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg src0, 5044cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg src1, 5054cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg src2, 5064cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org const char *fn, 5074cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint line) 5084cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 5094cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint nr = p->program->Base.NumInstructions++; 5104cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct prog_instruction *inst = &p->program->Base.Instructions[nr]; 51140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 51240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (p->program->Base.NumInstructions > MAX_INSN) { 5134551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org _mesa_problem(0, "Out of instructions in emit_op3fn\n"); 5144551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org return; 5154551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 5164551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5174551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org inst->Opcode = (enum prog_opcode) op; 51840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org inst->StringPos = 0; 5194551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org inst->Data = 0; 5204551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5214551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_arg( &inst->SrcReg[0], src0 ); 5224551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_arg( &inst->SrcReg[1], src1 ); 5234551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_arg( &inst->SrcReg[2], src2 ); 5244551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5254551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_dst( &inst->DstReg, dest, mask ); 5264551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5274551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org debug_insn(inst, fn, line); 5284551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org} 5294551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5304551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5314551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org#define emit_op3(p, op, dst, mask, src0, src1, src2) \ 5324551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__) 5334551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5344551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org#define emit_op2(p, op, dst, mask, src0, src1) \ 5354551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__) 5364551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5374551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org#define emit_op1(p, op, dst, mask, src0) \ 5384551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__) 5394551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5404551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5414551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.orgstatic struct ureg make_temp( struct tnl_program *p, struct ureg reg ) 5424551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org{ 5434551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (reg.file == PROGRAM_TEMPORARY && 5444551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org !(p->temp_reserved & (1<<reg.idx))) 5454551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org return reg; 5464551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org else { 5474551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg temp = get_temp(p); 5484551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op1(p, OPCODE_MOV, temp, 0, reg); 5494551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org return temp; 5504551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 5514551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org} 5524551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5534551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5544551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org/* Currently no tracking performed of input/output/register size or 5554551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * active elements. Could be used to reduce these operations, as 5564551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * could the matrix type. 55740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org */ 55840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic void emit_matrix_transform_vec4( struct tnl_program *p, 5594551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg dest, 560b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org const struct ureg *mat, 5614551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg src) 5624551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org{ 5634551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op2(p, OPCODE_DP4, dest, WRITEMASK_X, src, mat[0]); 56440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Y, src, mat[1]); 56540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Z, src, mat[2]); 5664551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op2(p, OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]); 5674551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org} 5684551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5694551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org/* This version is much easier to implement if writemasks are not 57040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org * supported natively on the target or (like SSE), the target doesn't 5714551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org * have a clean/obvious dotproduct implementation. 57240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org */ 573b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.orgstatic void emit_transpose_matrix_transform_vec4( struct tnl_program *p, 574b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg dest, 575b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org const struct ureg *mat, 576b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg src) 577b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org{ 578b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg tmp; 5794551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 5804551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (dest.file != PROGRAM_TEMPORARY) 5814551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org tmp = get_temp(p); 58240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org else 5834551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org tmp = dest; 58440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 585b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); 586b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); 587b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); 588b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); 589b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 590b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org if (dest.file != PROGRAM_TEMPORARY) 5914551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org release_temp(p, tmp); 59297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org} 59328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 59428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic void emit_matrix_transform_vec3( struct tnl_program *p, 59528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg dest, 59697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org const struct ureg *mat, 59797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org struct ureg src) 59897077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org{ 5994cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_op2(p, OPCODE_DP3, dest, WRITEMASK_X, src, mat[0]); 60028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Y, src, mat[1]); 60128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Z, src, mat[2]); 60228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 60328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 60428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6054cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic void emit_normalize_vec3( struct tnl_program *p, 60628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg dest, 60728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg src ) 60840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 60928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg tmp = get_temp(p); 61028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_DP3, tmp, 0, src, src); 61128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op1(p, OPCODE_RSQ, tmp, 0, tmp); 61228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_MUL, dest, 0, src, tmp); 61328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org release_temp(p, tmp); 61428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 61528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6164cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic void emit_passthrough( struct tnl_program *p, 61797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org GLuint input, 61828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLuint output ) 61928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org{ 6205bc25c41fc7880545052770dbcfe67f233c9b0c0sergeyu@chromium.org struct ureg out = register_output(p, output); 62128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op1(p, OPCODE_MOV, out, 0, register_input(p, input)); 62228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 62328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 62440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic struct ureg get_eye_position( struct tnl_program *p ) 62540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 626b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org if (is_undef(p->eye_position)) { 627b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 62828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg modelview[4]; 629b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 63028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org p->eye_position = reserve_temp(p); 63128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 63228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (PREFER_DP4) { 63328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, 63428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org STATE_MATRIX, modelview ); 63528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 63628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); 63728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 6384cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org else { 63928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, 64028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org STATE_MATRIX_TRANSPOSE, modelview ); 64140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 64228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos); 64328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 64428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 64528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 64628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return p->eye_position; 64728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 64828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 64928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6504cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic struct ureg get_eye_position_normalized( struct tnl_program *p ) 65197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org{ 65228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (is_undef(p->eye_position_normalized)) { 65328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg eye = get_eye_position(p); 6545bc25c41fc7880545052770dbcfe67f233c9b0c0sergeyu@chromium.org p->eye_position_normalized = reserve_temp(p); 65528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_normalize_vec3(p, p->eye_position_normalized, eye); 65628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 65728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 65828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return p->eye_position_normalized; 65928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 66028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 66128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 66228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic struct ureg get_eye_normal( struct tnl_program *p ) 66340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 66440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (is_undef(p->eye_normal)) { 665b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); 666b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg mvinv[3]; 66728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 66897077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2, 669b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org STATE_MATRIX_INVTRANS, mvinv ); 67028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 67128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org p->eye_normal = reserve_temp(p); 67228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 67328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org /* Transform to eye space: 67428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 67528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal ); 67628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 67728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org /* Normalize/Rescale: 67828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 67928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (p->state->normalize) { 68028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_normalize_vec3( p, p->eye_normal, p->eye_normal ); 68140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 68228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org else if (p->state->rescale_normals) { 68340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg rescale = register_param2(p, STATE_INTERNAL, 68440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org STATE_NORMAL_SCALE); 685b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 68628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2( p, OPCODE_MUL, p->eye_normal, 0, normal, 68740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org swizzle1(rescale, X)); 68840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 68928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 69028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 69128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return p->eye_normal; 69228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 69328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 69428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 69528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 69640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic void build_hpos( struct tnl_program *p ) 69728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org{ 69840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 69940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); 700b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg mvp[4]; 701b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 70228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (PREFER_DP4) { 70340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, 70440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org STATE_MATRIX, mvp ); 70528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_matrix_transform_vec4( p, hpos, mvp, pos ); 70628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 70740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org else { 70828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, 70928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org STATE_MATRIX_TRANSPOSE, mvp ); 71028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos ); 71128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 71228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 71328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 71428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7154cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic GLuint material_attrib( GLuint side, GLuint property ) 71628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org{ 71728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return ((property - STATE_AMBIENT) * 2 + 7184cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org side); 71997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org} 72028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 72128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/* Get a bitmask of which material values vary on a per-vertex basis. 72228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 72340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic void set_material_flags( struct tnl_program *p ) 72428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org{ 72528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org p->color_materials = 0; 72628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org p->materials = 0; 72728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 72840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (p->state->light_color_material) { 72928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org p->materials = 73028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org p->color_materials = p->state->light_color_material_mask; 73128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 73240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 73328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org p->materials |= p->state->light_material_mask; 73440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 7354cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 73628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 73728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic struct ureg get_material( struct tnl_program *p, GLuint side, 73828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLuint property ) 73928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org{ 74028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLuint attrib = material_attrib(side, property); 74128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7424cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->color_materials & (1<<attrib)) 74328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return register_input(p, VERT_ATTRIB_COLOR0); 74428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org else if (p->materials & (1<<attrib)) 7454cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org return register_input( p, attrib + _TNL_ATTRIB_MAT_FRONT_AMBIENT ); 74697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org else 74728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return register_param3( p, STATE_MATERIAL, side, property ); 74828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 74928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 75040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org#define SCENE_COLOR_BITS(side) (( MAT_BIT_FRONT_EMISSION | \ 75128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MAT_BIT_FRONT_AMBIENT | \ 75228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MAT_BIT_FRONT_DIFFUSE) << (side)) 75328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 75428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/* Either return a precalculated constant value or emit code to 75528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * calculate these values dynamically in the case where material calls 75628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * are present between begin/end pairs. 75728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 7585bc25c41fc7880545052770dbcfe67f233c9b0c0sergeyu@chromium.org * Probably want to shift this to the program compilation phase - if 75928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * we always emitted the calculation here, a smart compiler could 76028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * detect that it was constant (given a certain set of inputs), and 76128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * lift it out of the main loop. That way the programs created here 76240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org * would be independent of the vertex_buffer details. 76340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org */ 764b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.orgstatic struct ureg get_scenecolor( struct tnl_program *p, GLuint side ) 765b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org{ 76628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (p->materials & SCENE_COLOR_BITS(side)) { 76728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg lm_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT); 768b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg material_emission = get_material(p, side, STATE_EMISSION); 76928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg material_ambient = get_material(p, side, STATE_AMBIENT); 77097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE); 77197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org struct ureg tmp = make_temp(p, material_diffuse); 77297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org emit_op3(p, OPCODE_MAD, tmp, WRITEMASK_XYZ, lm_ambient, 77340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org material_ambient, material_emission); 77440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org return tmp; 7754cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 77628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org else 7774cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side ); 77897077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org} 77997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 78097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 78197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.orgstatic struct ureg get_lightprod( struct tnl_program *p, GLuint light, 78228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLuint side, GLuint property ) 78340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 7844cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint attrib = material_attrib(side, property); 78528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (p->materials & (1<<attrib)) { 78628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg light_value = 78740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org register_param3(p, STATE_LIGHT, light, property); 78828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg material_value = get_material(p, side, property); 78928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg tmp = get_temp(p); 79028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_MUL, tmp, 0, light_value, material_value); 79140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org return tmp; 7924cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 79328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org else 79428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return register_param4(p, STATE_LIGHTPROD, light, side, property); 79528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 79628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 79728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic struct ureg calculate_light_attenuation( struct tnl_program *p, 79828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GLuint i, 7994cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg VPpli, 80028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg dist ) 80128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org{ 80228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg attenuation = register_param3(p, STATE_LIGHT, i, 80328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org STATE_ATTENUATION); 8044cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg att = get_temp(p); 80597077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 80628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org /* Calculate spot attenuation: 80728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 80828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!p->state->unit[i].light_spotcutoff_is_180) { 80940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg spot_dir = register_param3(p, STATE_LIGHT, i, 81028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org STATE_SPOT_DIRECTION); 81128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg spot = get_temp(p); 81228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org struct ureg slt = get_temp(p); 81328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 81428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_normalize_vec3( p, spot, spot_dir ); /* XXX: precompute! */ 81528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot); 81628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir,W), spot); 8175bc25c41fc7880545052770dbcfe67f233c9b0c0sergeyu@chromium.org emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); 81828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_MUL, att, 0, slt, spot); 81928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 82028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org release_temp(p, spot); 82140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org release_temp(p, slt); 82240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 823b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 824b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org /* Calculate distance attenuation: 82528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 82628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (p->state->unit[i].light_attenuated) { 82797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 82828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org /* 1/d,d,d,1/d */ 82940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op1(p, OPCODE_RCP, dist, WRITEMASK_YZ, dist); 83040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* 1,d,d*d,1/d */ 83128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_MUL, dist, WRITEMASK_XZ, dist, swizzle1(dist,Y)); 832b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org /* 1/dist-atten */ 83328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op2(p, OPCODE_DP3, dist, 0, attenuation, dist); 83428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 83540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (!p->state->unit[i].light_spotcutoff_is_180) { 83628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org /* dist-atten */ 83740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op1(p, OPCODE_RCP, dist, 0, dist); 83828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org /* spot-atten * dist-atten */ 83940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_MUL, att, 0, dist, att); 84040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } else { 84128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org /* dist-atten */ 84228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org emit_op1(p, OPCODE_RCP, att, 0, dist); 84328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 84497077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org } 84597077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 84697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org return att; 84797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org} 8484cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 84997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 85097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 85197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 85297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 8534cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org/* Need to add some addtional parameters to allow lighting in object 85497077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org * space - STATE_SPOT_DIRECTION and STATE_HALF implicitly assume eye 85597077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org * space lighting. 85697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org */ 85797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.orgstatic void build_lighting( struct tnl_program *p ) 85840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 85940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org const GLboolean twoside = p->state->light_twoside; 86097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org const GLboolean separate = p->state->separate_specular; 861b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org GLuint nr_lights = 0, count = 0; 86240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg normal = get_eye_normal(p); 86397077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org struct ureg lit = get_temp(p); 86440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg dots = get_temp(p); 86540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg _col0 = undef, _col1 = undef; 86697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org struct ureg _bfc0 = undef, _bfc1 = undef; 86797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org GLuint i; 86897077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 86997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org for (i = 0; i < MAX_LIGHTS; i++) 87097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org if (p->state->unit[i].light_enabled) 87197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org nr_lights++; 87297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 8734cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org set_material_flags(p); 87497077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 87597077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org { 87697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org struct ureg shininess = get_material(p, 0, STATE_SHININESS); 87797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org emit_op1(p, OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); 8784cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org release_temp(p, shininess); 87997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 88097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org _col0 = make_temp(p, get_scenecolor(p, 0)); 88197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org if (separate) 88297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org _col1 = make_temp(p, get_identity_param(p)); 88340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org else 88497077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org _col1 = _col0; 88597077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 88697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org } 88797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 88840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (twoside) { 88940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg shininess = get_material(p, 1, STATE_SHININESS); 89097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, 89197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org negate(swizzle1(shininess,X))); 89297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org release_temp(p, shininess); 89397077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 89497077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org _bfc0 = make_temp(p, get_scenecolor(p, 1)); 89597077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org if (separate) 89697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org _bfc1 = make_temp(p, get_identity_param(p)); 89797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org else 8985bc25c41fc7880545052770dbcfe67f233c9b0c0sergeyu@chromium.org _bfc1 = _bfc0; 89997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org } 90097077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 90197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 90240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* If no lights, still need to emit the scenecolor. 90340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org */ 904b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org { 905b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg res0 = register_output( p, VERT_RESULT_COL0 ); 90697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org emit_op1(p, OPCODE_MOV, res0, 0, _col0); 90797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org } 908b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 90997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org if (separate) { 9104cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg res1 = register_output( p, VERT_RESULT_COL1 ); 91140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op1(p, OPCODE_MOV, res1, 0, _col1); 91240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 91397077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org 91497077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org if (twoside) { 91597077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org struct ureg res0 = register_output( p, VERT_RESULT_BFC0 ); 91697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org emit_op1(p, OPCODE_MOV, res0, 0, _bfc0); 9174cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 9184cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9194cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (twoside && separate) { 9204cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg res1 = register_output( p, VERT_RESULT_BFC1 ); 9214cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_op1(p, OPCODE_MOV, res1, 0, _bfc1); 9224cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 9234cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9244cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (nr_lights == 0) { 9254cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org release_temps(p); 9264cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org return; 9274cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 9284cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9294cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9304cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org for (i = 0; i < MAX_LIGHTS; i++) { 9314cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->state->unit[i].light_enabled) { 9324cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg half = undef; 9334cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg att = undef, VPpli = undef; 9344cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9354cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org count++; 9364cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9374cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->state->unit[i].light_eyepos3_is_zero) { 9384cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org /* Can used precomputed constants in this case. 9394cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org * Attenuation never applies to infinite lights. 9404cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org */ 9414cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org VPpli = register_param3(p, STATE_LIGHT, i, 9424cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org STATE_POSITION_NORMALIZED); 9434cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org half = register_param3(p, STATE_LIGHT, i, STATE_HALF); 9444cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 9454cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org else { 9464cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg Ppli = register_param3(p, STATE_LIGHT, i, 9474cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org STATE_POSITION); 9484cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg V = get_eye_position(p); 9494cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg dist = get_temp(p); 9504cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9514cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org VPpli = get_temp(p); 9524cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org half = get_temp(p); 9534cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9544cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org /* Calulate VPpli vector 9554cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org */ 9564cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); 9574cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9584cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org /* Normalize VPpli. The dist value also used in 9594cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org * attenuation below. 9604cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org */ 9614cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli); 9624cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_op1(p, OPCODE_RSQ, dist, 0, dist); 9634cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist); 9644cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 9654551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 9664551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org /* Calculate attenuation: 96719f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org */ 9684551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (!p->state->unit[i].light_spotcutoff_is_180 || 9694551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org p->state->unit[i].light_attenuated) { 9704551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org att = calculate_light_attenuation(p, i, VPpli, dist); 9714551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 9724551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 9734551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 9744551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org /* Calculate viewer direction, or use infinite viewer: 9754551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org */ 9764551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (p->state->light_local_viewer) { 9774551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg eye_hat = get_eye_position_normalized(p); 9784551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); 9794551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 9804551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org else { 9814551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); 9824551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir); 9834551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 9844551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 9854551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_normalize_vec3(p, half, half); 9864551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 9874551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org release_temp(p, dist); 9884551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 9894551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 99019f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org /* Calculate dot products: 9914551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org */ 9924551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); 9934551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half); 9944551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 9954551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 9964551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org /* Front face lighting: 9974551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org */ 9984551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org { 9994551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT); 10004551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE); 10014551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR); 10024551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg res0, res1; 10034551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org GLuint mask0, mask1; 10044551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 100519f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org emit_op1(p, OPCODE_LIT, lit, 0, dots); 10064551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 100740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (!is_undef(att)) 10084551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op2(p, OPCODE_MUL, lit, 0, lit, att); 10094551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 10104551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 10114551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (count == nr_lights) { 10124551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (separate) { 10134551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask0 = WRITEMASK_XYZ; 10144551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask1 = WRITEMASK_XYZ; 10154551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res0 = register_output( p, VERT_RESULT_COL0 ); 10164551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res1 = register_output( p, VERT_RESULT_COL1 ); 10174551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 10184551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org else { 10194551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask0 = 0; 10204551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask1 = WRITEMASK_XYZ; 10214551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res0 = _col0; 10224551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res1 = register_output( p, VERT_RESULT_COL0 ); 10234551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 10244551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } else { 10254551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask0 = 0; 10264551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask1 = 0; 10274551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res0 = _col0; 102897077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org res1 = _col1; 102940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 103040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 10314551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op3(p, OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); 1032b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _col0); 10334551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _col1); 10344551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 10354551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org release_temp(p, ambient); 10364551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org release_temp(p, diffuse); 103740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org release_temp(p, specular); 10384551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 103940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 10404551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org /* Back face lighting: 10414551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org */ 10424551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (twoside) { 10434551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT); 104440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE); 10454551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR); 104640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg res0, res1; 10474551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org GLuint mask0, mask1; 10484551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 10494551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op1(p, OPCODE_LIT, lit, 0, negate(swizzle(dots,X,Y,W,Z))); 10504551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 10514551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (!is_undef(att)) 105219f27e6a24f877fc2b0409a94b02d5f40ba3dc8cmallinath@webrtc.org emit_op2(p, OPCODE_MUL, lit, 0, lit, att); 10534551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 105440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (count == nr_lights) { 10554551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (separate) { 10564551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask0 = WRITEMASK_XYZ; 10574551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask1 = WRITEMASK_XYZ; 10584551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res0 = register_output( p, VERT_RESULT_BFC0 ); 10594551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res1 = register_output( p, VERT_RESULT_BFC1 ); 10604551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 10614551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org else { 10624551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask0 = 0; 10634551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask1 = WRITEMASK_XYZ; 10644551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res0 = _bfc0; 10654551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res1 = register_output( p, VERT_RESULT_BFC0 ); 10664551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 10674551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } else { 10684551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res0 = _bfc0; 10694551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org res1 = _bfc1; 10704551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask0 = 0; 10714551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org mask1 = 0; 10724551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 10734551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 10744551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op3(p, OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0); 10754551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0); 10764551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1); 10774551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 10784551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org release_temp(p, ambient); 10794551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org release_temp(p, diffuse); 10804551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org release_temp(p, specular); 10814551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 108240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 108340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org release_temp(p, half); 10844551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org release_temp(p, VPpli); 1085b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org release_temp(p, att); 10864551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 10874551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 10884551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 10894551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org release_temps( p ); 109040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 10914551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org 109240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 10934551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.orgstatic void build_fog( struct tnl_program *p ) 10944551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org{ 10954551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg fog = register_output(p, VERT_RESULT_FOGC); 10964551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org struct ureg input; 109740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 10984551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org if (p->state->fog_source_is_depth) { 109940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org input = swizzle1(get_eye_position(p), Z); 11004551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org } 11014551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org else { 11024551b793dea4b5451cbfa13b206b6d11a25081d0wu@webrtc.org input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); 1103b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org } 1104b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 1105b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org if (p->state->tnl_do_vertex_fog) { 1106b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg params = register_param1(p, STATE_FOG_PARAMS); 1107b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg tmp = get_temp(p); 1108b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 1109b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org switch (p->state->fog_mode) { 1110b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org case FOG_LINEAR: { 1111b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg id = get_identity_param(p); 1112b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_SUB, tmp, 0, swizzle1(params,Z), input); 1113b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,W)); 1114b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ 1115b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); 1116b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org break; 1117b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org } 1118b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org case FOG_EXP: 1119b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op1(p, OPCODE_ABS, tmp, 0, input); 1120b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,X)); 1121b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_POW, fog, WRITEMASK_X, 1122b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org register_const1f(p, M_E), negate(tmp)); 11234cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org break; 1124b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org case FOG_EXP2: 1125b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,X)); 1126b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); 1127b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_POW, fog, WRITEMASK_X, 112840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org register_const1f(p, M_E), negate(tmp)); 1129b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org break; 1130b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org } 1131b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 1132b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org release_temp(p, tmp); 1133b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org } 1134b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org else { 1135b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org /* results = incoming fog coords (compute fog per-fragment later) 1136b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org * 1137b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org * KW: Is it really necessary to do anything in this case? 1138b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org */ 1139b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op1(p, OPCODE_MOV, fog, WRITEMASK_X, input); 114040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 1141b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org} 1142b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 1143b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.orgstatic void build_reflect_texgen( struct tnl_program *p, 1144b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg dest, 1145b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org GLuint writemask ) 1146b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org{ 1147b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg normal = get_eye_normal(p); 1148b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg eye_hat = get_eye_position_normalized(p); 1149b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg tmp = get_temp(p); 1150b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 1151b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org /* n.u */ 1152b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); 1153b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org /* 2n.u */ 1154b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); 1155b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org /* (-2n.u)n + u */ 1156b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org emit_op3(p, OPCODE_MAD, dest, writemask, negate(tmp), normal, eye_hat); 1157b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 1158b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org release_temp(p, tmp); 1159b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org} 1160b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org 1161b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.orgstatic void build_sphere_texgen( struct tnl_program *p, 1162b9a088b920d1ba16e0593698d4a613bb7bb5481fwu@webrtc.org struct ureg dest, 116340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLuint writemask ) 116440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 116540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg normal = get_eye_normal(p); 116640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg eye_hat = get_eye_position_normalized(p); 116740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg tmp = get_temp(p); 116840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg half = register_scalar_const(p, .5); 116940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg r = get_temp(p); 117040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg inv_m = get_temp(p); 117140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg id = get_identity_param(p); 11724cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 117340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* Could share the above calculations, but it would be 117440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org * a fairly odd state for someone to set (both sphere and 117540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org * reflection active for different texture coordinate 117640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org * components. Of course - if two texture units enable 117740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org * reflect and/or sphere, things start to tilt in favour 117840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org * of seperating this out: 117940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org */ 118040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 118140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* n.u */ 118240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); 118340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* 2n.u */ 118440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); 11854cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org /* (-2n.u)n + u */ 118640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op3(p, OPCODE_MAD, r, 0, negate(tmp), normal, eye_hat); 118740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* r + 0,0,1 */ 118840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_ADD, tmp, 0, r, swizzle(id,X,Y,W,Z)); 118940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* rx^2 + ry^2 + (rz+1)^2 */ 119040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_DP3, tmp, 0, tmp, tmp); 119140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* 2/m */ 119240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op1(p, OPCODE_RSQ, tmp, 0, tmp); 119340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* 1/m */ 119440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_MUL, inv_m, 0, tmp, half); 119540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* r/m + 1/2 */ 119640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op3(p, OPCODE_MAD, dest, writemask, r, inv_m, half); 119740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 119840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org release_temp(p, tmp); 119940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org release_temp(p, r); 120040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org release_temp(p, inv_m); 120140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 120240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 120340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 120440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic void build_texture_transform( struct tnl_program *p ) 120540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 120640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLuint i, j; 12074cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 120840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 120940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 121040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (!(p->state->fragprog_inputs_read & (FRAG_BIT_TEX0<<i))) 121140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org continue; 121240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 12134cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->state->unit[i].texgen_enabled || 121440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org p->state->unit[i].texmat_enabled) { 121540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 121640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLuint texmat_enabled = p->state->unit[i].texmat_enabled; 121740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg out = register_output(p, VERT_RESULT_TEX0 + i); 121840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg out_texgen = undef; 121940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 122040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (p->state->unit[i].texgen_enabled) { 12214cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint copy_mask = 0; 122240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLuint sphere_mask = 0; 122340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLuint reflect_mask = 0; 12244cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint normal_mask = 0; 122540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org GLuint modes[4]; 122640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 122740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (texmat_enabled) 122840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org out_texgen = get_temp(p); 122940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org else 12304cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org out_texgen = out; 12314cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 12324cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org modes[0] = p->state->unit[i].texgen_mode0; 12334cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org modes[1] = p->state->unit[i].texgen_mode1; 12344cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org modes[2] = p->state->unit[i].texgen_mode2; 12354cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org modes[3] = p->state->unit[i].texgen_mode3; 12363e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 12373e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org for (j = 0; j < 4; j++) { 12383e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org switch (modes[j]) { 12393e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org case TXG_OBJ_LINEAR: { 12403e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org struct ureg obj = register_input(p, VERT_ATTRIB_POS); 12413e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org struct ureg plane = 12423e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org register_param3(p, STATE_TEXGEN, i, 12433e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org STATE_TEXGEN_OBJECT_S + j); 12443e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 12453e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 12464cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org obj, plane ); 12473e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org break; 12483e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org } 12493e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org case TXG_EYE_LINEAR: { 12503e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org struct ureg eye = get_eye_position(p); 12513e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org struct ureg plane = 12523e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org register_param3(p, STATE_TEXGEN, i, 12533e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org STATE_TEXGEN_EYE_S + j); 12543e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 12553e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 12563e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org eye, plane ); 12573e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org break; 12584cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 12597e71b77f8aab5b7a6f2b669c16f90ec9a4b4609cbuildbot@webrtc.org case TXG_SPHERE_MAP: 12603e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org sphere_mask |= WRITEMASK_X << j; 12613e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org break; 12623e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org case TXG_REFLECTION_MAP: 12633e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org reflect_mask |= WRITEMASK_X << j; 12643e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org break; 12653e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org case TXG_NORMAL_MAP: 12663e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org normal_mask |= WRITEMASK_X << j; 12673e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org break; 12683e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org case TXG_NONE: 12693e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org copy_mask |= WRITEMASK_X << j; 12703e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org } 12713e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 12723e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org } 12733e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 12743e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 12754cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (sphere_mask) { 12764cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org build_sphere_texgen(p, out_texgen, sphere_mask); 12774cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 12784cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 12794cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (reflect_mask) { 12804cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org build_reflect_texgen(p, out_texgen, reflect_mask); 12813e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org } 12823e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org 12833e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org if (normal_mask) { 12843e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org struct ureg normal = get_eye_normal(p); 12853e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org emit_op1(p, OPCODE_MOV, out_texgen, normal_mask, normal ); 12863e01e0b16cbde481241b9bcfdbbdd591cd920b99buildbot@webrtc.org } 128740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 128840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (copy_mask) { 128940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); 129040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); 129140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 129240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 129340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 129440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (texmat_enabled) { 129540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg texmat[4]; 12964cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct ureg in = (!is_undef(out_texgen) ? 129740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org out_texgen : 129840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org register_input(p, VERT_ATTRIB_TEX0+i)); 129940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org if (PREFER_DP4) { 130040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 130140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 0, 3, STATE_MATRIX, texmat ); 130240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_matrix_transform_vec4( p, out, texmat, in ); 130340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 130440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org else { 130540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 130640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 0, 3, STATE_MATRIX_TRANSPOSE, texmat ); 130740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_transpose_matrix_transform_vec4( p, out, texmat, in ); 130840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 130940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 13104cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 131140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org release_temps(p); 131240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 131340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org else { 131440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); 131540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 131640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org } 131740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org} 131840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 131940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 132040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org/* Seems like it could be tighter: 132140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org */ 132240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.orgstatic void build_pointsize( struct tnl_program *p ) 132340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org{ 132440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg eye = get_eye_position(p); 132540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg state_size = register_param1(p, STATE_POINT_SIZE); 132640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); 132740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg out = register_output(p, VERT_RESULT_PSIZ); 132840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org struct ureg ut = get_temp(p); 132940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 133040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* 1, -Z, Z * Z, 1 */ 133140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op1(p, OPCODE_MOV, ut, 0, swizzle1(get_identity_param(p), W)); 13324cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_op2(p, OPCODE_MUL, ut, WRITEMASK_YZ, ut, negate(swizzle1(eye, Z))); 133340b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_MUL, ut, WRITEMASK_Z, ut, negate(swizzle1(eye, Z))); 133440b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 133540b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 133640b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* p1 + p2 * dist + p3 * dist * dist, 0 */ 133740b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op2(p, OPCODE_DP3, ut, 0, ut, state_attenuation); 133840b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 133940b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* 1 / factor */ 134040b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org emit_op1(p, OPCODE_RCP, ut, 0, ut ); 134140b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org 134240b3b68cdf47d7c9c3b57fca5d0a372292025f9ehenrike@webrtc.org /* out = pointSize / factor */ 13434cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); 13444cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13454cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org release_temp(p, ut); 13464cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org} 13474cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13484cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic void build_tnl_program( struct tnl_program *p ) 13494cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ /* Emit the program, starting with modelviewproject: 13504cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org */ 13514cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org build_hpos(p); 13524cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13534cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org /* Lighting calculations: 13544cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org */ 13554cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->state->fragprog_inputs_read & (FRAG_BIT_COL0|FRAG_BIT_COL1)) { 13564cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->state->light_global_enabled) 13574cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org build_lighting(p); 13584cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org else { 13594cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) 13604cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0); 13614cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13624cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->state->fragprog_inputs_read & FRAG_BIT_COL1) 13634cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_passthrough(p, VERT_ATTRIB_COLOR1, VERT_RESULT_COL1); 13644cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 13654cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 13664cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13674cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if ((p->state->fragprog_inputs_read & FRAG_BIT_FOGC) || 13684cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p->state->fog_mode != FOG_NONE) 13694cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org build_fog(p); 13704cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13714cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->state->fragprog_inputs_read & FRAG_BITS_TEX_ANY) 13724cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org build_texture_transform(p); 13734cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13744cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (p->state->point_attenuated) 13754cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org build_pointsize(p); 13764cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13774cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org /* Finish up: 13784cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org */ 13794cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org emit_op1(p, OPCODE_END, undef, 0, undef); 13804cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13814cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org /* Disassemble: 13824cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org */ 13834cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (DISASSEM) { 13844cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org _mesa_printf ("\n"); 13854cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org } 13864cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org} 13874cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13884cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13894cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgstatic void 13904cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.orgcreate_new_program( const struct state_key *key, 13914cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct vertex_program *program, 13924cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org GLuint max_temps) 13934cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org{ 13944cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org struct tnl_program p; 13954cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 13964cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org _mesa_memset(&p, 0, sizeof(p)); 13974cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.state = key; 13984cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program = program; 13994cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.eye_position = undef; 14004cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.eye_position_normalized = undef; 14014cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.eye_normal = undef; 14024cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.identity = undef; 14034cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.temp_in_use = 0; 14044cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 14054cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org if (max_temps >= sizeof(int) * 8) 14064cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.temp_reserved = 0; 14074cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org else 14084cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.temp_reserved = ~((1<<max_temps)-1); 14094cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 14104cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program->Base.Instructions 14114cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org = (struct prog_instruction*) MALLOC(sizeof(struct prog_instruction) * MAX_INSN); 14124cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program->Base.String = 0; 14134cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program->Base.NumInstructions = 14144cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program->Base.NumTemporaries = 14154cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program->Base.NumParameters = 14164cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; 14174cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program->Base.Parameters = _mesa_new_parameter_list(); 14184cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program->Base.InputsRead = 0; 14194cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org p.program->Base.OutputsWritten = 0; 14204cb012858f7461015e405c0c2cfc4b9f10a086cexians@webrtc.org 142128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org build_tnl_program( &p ); 1422} 1423 1424static void *search_cache( struct tnl_cache *cache, 1425 GLuint hash, 1426 const void *key, 1427 GLuint keysize) 1428{ 1429 struct tnl_cache_item *c; 1430 1431 for (c = cache->items[hash % cache->size]; c; c = c->next) { 1432 if (c->hash == hash && _mesa_memcmp(c->key, key, keysize) == 0) 1433 return c->data; 1434 } 1435 1436 return NULL; 1437} 1438 1439static void rehash( struct tnl_cache *cache ) 1440{ 1441 struct tnl_cache_item **items; 1442 struct tnl_cache_item *c, *next; 1443 GLuint size, i; 1444 1445 size = cache->size * 3; 1446 items = (struct tnl_cache_item**) _mesa_malloc(size * sizeof(*items)); 1447 _mesa_memset(items, 0, size * sizeof(*items)); 1448 1449 for (i = 0; i < cache->size; i++) 1450 for (c = cache->items[i]; c; c = next) { 1451 next = c->next; 1452 c->next = items[c->hash % size]; 1453 items[c->hash % size] = c; 1454 } 1455 1456 FREE(cache->items); 1457 cache->items = items; 1458 cache->size = size; 1459} 1460 1461static void cache_item( struct tnl_cache *cache, 1462 GLuint hash, 1463 void *key, 1464 void *data ) 1465{ 1466 struct tnl_cache_item *c = (struct tnl_cache_item*) _mesa_malloc(sizeof(*c)); 1467 c->hash = hash; 1468 c->key = key; 1469 c->data = data; 1470 1471 if (++cache->n_items > cache->size * 1.5) 1472 rehash(cache); 1473 1474 c->next = cache->items[hash % cache->size]; 1475 cache->items[hash % cache->size] = c; 1476} 1477 1478static GLuint hash_key( struct state_key *key ) 1479{ 1480 GLuint *ikey = (GLuint *)key; 1481 GLuint hash = 0, i; 1482 1483 /* I'm sure this can be improved on, but speed is important: 1484 */ 1485 for (i = 0; i < sizeof(*key)/sizeof(GLuint); i++) 1486 hash ^= ikey[i]; 1487 1488 return hash; 1489} 1490 1491void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx ) 1492{ 1493 TNLcontext *tnl = TNL_CONTEXT(ctx); 1494 struct state_key *key; 1495 GLuint hash; 1496 const struct vertex_program *prev = ctx->VertexProgram._Current; 1497 1498 if (ctx->VertexProgram._Enabled == GL_FALSE) { 1499 /* Grab all the relevent state and put it in a single structure: 1500 */ 1501 key = make_state_key(ctx); 1502 hash = hash_key(key); 1503 1504 /* Look for an already-prepared program for this state: 1505 */ 1506 ctx->_TnlProgram = (struct vertex_program *) 1507 search_cache( tnl->vp_cache, hash, key, sizeof(*key) ); 1508 1509 /* OK, we'll have to build a new one: 1510 */ 1511 if (!ctx->_TnlProgram) { 1512 if (0) 1513 _mesa_printf("Build new TNL program\n"); 1514 1515 ctx->_TnlProgram = (struct vertex_program *) 1516 ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); 1517 1518 create_new_program( key, ctx->_TnlProgram, 1519 ctx->Const.VertexProgram.MaxTemps ); 1520 1521 if (ctx->Driver.ProgramStringNotify) 1522 ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB, 1523 &ctx->_TnlProgram->Base ); 1524 1525 cache_item(tnl->vp_cache, hash, key, ctx->_TnlProgram ); 1526 } 1527 else { 1528 FREE(key); 1529 if (0) 1530 _mesa_printf("Found existing TNL program for key %x\n", hash); 1531 } 1532 ctx->VertexProgram._Current = ctx->_TnlProgram; 1533 } 1534 else { 1535 ctx->VertexProgram._Current = ctx->VertexProgram.Current; 1536 } 1537 1538 /* Tell the driver about the change. Could define a new target for 1539 * this? 1540 */ 1541 if (ctx->VertexProgram._Current != prev && 1542 ctx->Driver.BindProgram) 1543 ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, (struct program *) 1544 ctx->VertexProgram._Current); 1545} 1546 1547void _tnl_ProgramCacheInit( GLcontext *ctx ) 1548{ 1549 TNLcontext *tnl = TNL_CONTEXT(ctx); 1550 1551 tnl->vp_cache = (struct tnl_cache *) MALLOC(sizeof(*tnl->vp_cache)); 1552 tnl->vp_cache->size = 17; 1553 tnl->vp_cache->n_items = 0; 1554 tnl->vp_cache->items = (struct tnl_cache_item**) 1555 _mesa_calloc(tnl->vp_cache->size * sizeof(*tnl->vp_cache->items)); 1556} 1557 1558void _tnl_ProgramCacheDestroy( GLcontext *ctx ) 1559{ 1560 TNLcontext *tnl = TNL_CONTEXT(ctx); 1561 struct tnl_cache_item *c, *next; 1562 GLuint i; 1563 1564 for (i = 0; i < tnl->vp_cache->size; i++) 1565 for (c = tnl->vp_cache->items[i]; c; c = next) { 1566 next = c->next; 1567 FREE(c->key); 1568 FREE(c->data); 1569 FREE(c); 1570 } 1571 1572 FREE(tnl->vp_cache->items); 1573 FREE(tnl->vp_cache); 1574} 1575