14c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org/* 24c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * Copyright (C) 2009-2010 Francisco Jerez. 34c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * All Rights Reserved. 44c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * 54c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * Permission is hereby granted, free of charge, to any person obtaining 64c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * a copy of this software and associated documentation files (the 74c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * "Software"), to deal in the Software without restriction, including 84c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 94c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to 104c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * permit persons to whom the Software is furnished to do so, subject to 114c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * the following conditions: 124c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * 134c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * The above copyright notice and this permission notice (including the 144c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * next paragraph) shall be included in all copies or substantial 154c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * portions of the Software. 164c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * 174c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 184c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 194c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 204c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 214c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 224c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 234c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 244c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * 254c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org */ 264c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 274c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org#include "nouveau_driver.h" 284c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org#include "nouveau_context.h" 294c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org#include "nouveau_gldefs.h" 304c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org#include "nouveau_util.h" 314c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org#include "nv10_3d.xml.h" 324c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org#include "nv10_driver.h" 334c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 344c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgvoid 354c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgnv10_emit_clip_plane(struct gl_context *ctx, int emit) 364c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 374c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 384c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 394c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgstatic inline unsigned 404c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgget_material_bitmask(unsigned m) 414c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 424c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org unsigned ret = 0; 434c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 444c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (m & MAT_BIT_FRONT_EMISSION) 454c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org ret |= NV10_3D_COLOR_MATERIAL_EMISSION; 464c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (m & MAT_BIT_FRONT_AMBIENT) 474c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org ret |= NV10_3D_COLOR_MATERIAL_AMBIENT; 484c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (m & MAT_BIT_FRONT_DIFFUSE) 494c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org ret |= NV10_3D_COLOR_MATERIAL_DIFFUSE; 504c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (m & MAT_BIT_FRONT_SPECULAR) 514c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org ret |= NV10_3D_COLOR_MATERIAL_SPECULAR; 524c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 534c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return ret; 544c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 554c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 564c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgvoid 574c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgnv10_emit_color_material(struct gl_context *ctx, int emit) 584c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 594c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org struct nouveau_pushbuf *push = context_push(ctx); 604c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org unsigned mask = get_material_bitmask(ctx->Light._ColorMaterialBitmask); 614c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 624c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org BEGIN_NV04(push, NV10_3D(COLOR_MATERIAL), 1); 634c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATA (push, ctx->Light.ColorMaterialEnabled ? mask : 0); 644c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 654c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 664c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgstatic unsigned 674c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgget_fog_mode(unsigned mode) 684c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 694c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org switch (mode) { 7006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org case GL_LINEAR: 714c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_FOG_MODE_LINEAR; 724c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org case GL_EXP: 734c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_FOG_MODE_EXP; 744c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org case GL_EXP2: 754c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_FOG_MODE_EXP2; 764c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org default: 774c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org assert(0); 784c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org } 794c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 804c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 814c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgstatic unsigned 824c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgget_fog_source(unsigned source, unsigned distance_mode) 834c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 844c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org switch (source) { 854c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org case GL_FOG_COORDINATE_EXT: 864c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_FOG_COORD_FOG; 874c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org case GL_FRAGMENT_DEPTH_EXT: 884c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org switch (distance_mode) { 894c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org case GL_EYE_PLANE_ABSOLUTE_NV: 904c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_FOG_COORD_DIST_ORTHOGONAL_ABS; 914c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org case GL_EYE_PLANE: 924c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_FOG_COORD_DIST_ORTHOGONAL; 934c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org case GL_EYE_RADIAL_NV: 944c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_FOG_COORD_DIST_RADIAL; 954c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org default: 964c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org assert(0); 974c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org } 984c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org default: 994c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org assert(0); 1004c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org } 1014c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 1024c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1034c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgvoid 1044c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgnv10_get_fog_coeff(struct gl_context *ctx, float k[3]) 1054c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 1064c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org struct gl_fog_attrib *f = &ctx->Fog; 1074c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1084c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org switch (f->Mode) { 1094c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org case GL_LINEAR: 1104c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org k[0] = 2 + f->Start / (f->End - f->Start); 1114c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org k[1] = -1 / (f->End - f->Start); 1124c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org break; 1134c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1144c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org case GL_EXP: 1154c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org k[0] = 1.5; 1164c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org k[1] = -0.09 * f->Density; 1174c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org break; 1184c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 11906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org case GL_EXP2: 1204c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org k[0] = 1.5; 1214c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org k[1] = -0.21 * f->Density; 1224c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org break; 1234c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1244c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org default: 1254c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org assert(0); 1264c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org } 1274c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1284c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org k[2] = 0; 1294c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 1304c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1314c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgvoid 1324c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgnv10_emit_fog(struct gl_context *ctx, int emit) 1334c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 1344c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org struct nouveau_context *nctx = to_nouveau_context(ctx); 1354c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org struct nouveau_pushbuf *push = context_push(ctx); 1364c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org struct gl_fog_attrib *f = &ctx->Fog; 1374c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org unsigned source = nctx->fallback == HWTNL ? 1384c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org f->FogCoordinateSource : GL_FOG_COORDINATE_EXT; 1394c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org float k[3]; 1404c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1414c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org nv10_get_fog_coeff(ctx, k); 1424c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1434c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org BEGIN_NV04(push, NV10_3D(FOG_MODE), 4); 1444c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATA (push, get_fog_mode(f->Mode)); 1454c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATA (push, get_fog_source(source, f->FogDistanceMode)); 1464c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATAb(push, f->Enabled); 1474c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATA (push, pack_rgba_f(MESA_FORMAT_RGBA8888_REV, f->Color)); 1484c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1494c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org BEGIN_NV04(push, NV10_3D(FOG_COEFF(0)), 3); 1504c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATAp(push, k, 3); 1514c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1524c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org context_dirty(ctx, FRAG); 1534c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 1544c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1554c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgstatic inline unsigned 1564c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgget_light_mode(struct gl_light *l) 1574c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 1584c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (l->Enabled) { 1594c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (l->_Flags & LIGHT_SPOT) 1604c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_ENABLED_LIGHTS_0_DIRECTIONAL; 1614c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org else if (l->_Flags & LIGHT_POSITIONAL) 1624c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_ENABLED_LIGHTS_0_POSITIONAL; 1634c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org else 1644c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_ENABLED_LIGHTS_0_NONPOSITIONAL; 1654c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org } else { 1664c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return NV10_3D_ENABLED_LIGHTS_0_DISABLED; 1674c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org } 1684c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 1694c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1704c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgvoid 1714c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgnv10_emit_light_enable(struct gl_context *ctx, int emit) 1724c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 1734c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org struct nouveau_context *nctx = to_nouveau_context(ctx); 1744c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org struct nouveau_pushbuf *push = context_push(ctx); 1754c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org uint32_t en_lights = 0; 1764c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org int i; 1774c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1784c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (nctx->fallback != HWTNL) { 1794c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org BEGIN_NV04(push, NV10_3D(LIGHTING_ENABLE), 1); 1804c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATA (push, 0); 1814c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return; 1824c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org } 1834c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1844c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org for (i = 0; i < MAX_LIGHTS; i++) 1854c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org en_lights |= get_light_mode(&ctx->Light.Light[i]) << 2 * i; 1864c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 1874c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org BEGIN_NV04(push, NV10_3D(ENABLED_LIGHTS), 1); 1884c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATA (push, en_lights); 1894c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org BEGIN_NV04(push, NV10_3D(LIGHTING_ENABLE), 1); 1904c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATAb(push, ctx->Light.Enabled); 19106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org BEGIN_NV04(push, NV10_3D(NORMALIZE_ENABLE), 1); 1924c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATAb(push, ctx->Transform.Normalize); 1934c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 19442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org 19542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.orgvoid 19642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.orgnv10_emit_light_model(struct gl_context *ctx, int emit) 19742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org{ 19842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org struct nouveau_pushbuf *push = context_push(ctx); 19942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org struct gl_lightmodel *m = &ctx->Light.Model; 20042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org 20142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org BEGIN_NV04(push, NV10_3D(SEPARATE_SPECULAR_ENABLE), 1); 20242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org PUSH_DATAb(push, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR); 20342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org 2044c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org BEGIN_NV04(push, NV10_3D(LIGHT_MODEL), 1); 2054c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org PUSH_DATA (push, ((m->LocalViewer ? 2064c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org NV10_3D_LIGHT_MODEL_LOCAL_VIEWER : 0) | 2074c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org (_mesa_need_secondary_color(ctx) ? 2084c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org NV10_3D_LIGHT_MODEL_SEPARATE_SPECULAR : 0) | 2094c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org (!ctx->Light.Enabled && ctx->Fog.ColorSumEnabled ? 2104c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org NV10_3D_LIGHT_MODEL_VERTEX_SPECULAR : 0))); 2114c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 2124c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 2134c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgstatic float 2144c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgget_shine(const float p[], float x) 2154c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 2164c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org const int n = 15; 2174c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org const float *y = &p[1]; 2184c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org float f = (n - 1) * (1 - 1 / (1 + p[0] * x)) 2194c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org / (1 - 1 / (1 + p[0] * 1024)); 2204c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org int i = f; 2214c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 2224c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org /* Linear interpolation in f-space (Faster and somewhat more 2234c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org * accurate than x-space). */ 2244c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (x == 0) 22506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return y[0]; 22606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org else if (i > n - 2) 22706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return y[n - 1]; 22806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org else 22906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return y[i] + (y[i + 1] - y[i]) * (f - i); 2304c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org} 2314c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 2324c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgstatic const float nv10_spot_params[2][16] = { 2334c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org { 0.02, -3.80e-05, -1.77, -2.41, -2.71, -2.88, -2.98, -3.06, 2344c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org -3.11, -3.17, -3.23, -3.28, -3.37, -3.47, -3.83, -5.11 }, 2354c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org { 0.02, -0.01, 1.77, 2.39, 2.70, 2.87, 2.98, 3.06, 2364c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 3.10, 3.16, 3.23, 3.27, 3.37, 3.47, 3.83, 5.11 }, 2374c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org}; 2384c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 2394c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgvoid 2404c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgnv10_get_spot_coeff(struct gl_light *l, float k[7]) 2414c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org{ 2424c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org float e = l->SpotExponent; 2434c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org float a0, b0, a1, a2, b2, a3; 2444c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 24506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (e > 0) 246 a0 = -1 - 5.36e-3 / sqrt(e); 247 else 248 a0 = -1; 249 b0 = 1 / (1 + 0.273 * e); 250 251 a1 = get_shine(nv10_spot_params[0], e); 252 253 a2 = get_shine(nv10_spot_params[1], e); 254 b2 = 1 / (1 + 0.273 * e); 255 256 a3 = 0.9 + 0.278 * e; 257 258 if (l->SpotCutoff > 0) { 259 float cutoff = MAX2(a3, 1 / (1 - l->_CosCutoff)); 260 261 k[0] = MAX2(0, a0 + b0 * cutoff); 262 k[1] = a1; 263 k[2] = a2 + b2 * cutoff; 264 k[3] = - cutoff * l->_NormSpotDirection[0]; 265 k[4] = - cutoff * l->_NormSpotDirection[1]; 266 k[5] = - cutoff * l->_NormSpotDirection[2]; 267 k[6] = 1 - cutoff; 268 269 } else { 270 k[0] = b0; 271 k[1] = a1; 272 k[2] = a2 + b2; 273 k[3] = - l->_NormSpotDirection[0]; 274 k[4] = - l->_NormSpotDirection[1]; 275 k[5] = - l->_NormSpotDirection[2]; 276 k[6] = -1; 277 } 278} 279 280void 281nv10_emit_light_source(struct gl_context *ctx, int emit) 282{ 283 const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0; 284 struct nouveau_pushbuf *push = context_push(ctx); 285 struct gl_light *l = &ctx->Light.Light[i]; 286 287 if (l->_Flags & LIGHT_POSITIONAL) { 288 BEGIN_NV04(push, NV10_3D(LIGHT_POSITION_X(i)), 3); 289 PUSH_DATAp(push, l->_Position, 3); 290 291 BEGIN_NV04(push, NV10_3D(LIGHT_ATTENUATION_CONSTANT(i)), 3); 292 PUSH_DATAf(push, l->ConstantAttenuation); 293 PUSH_DATAf(push, l->LinearAttenuation); 294 PUSH_DATAf(push, l->QuadraticAttenuation); 295 296 } else { 297 BEGIN_NV04(push, NV10_3D(LIGHT_DIRECTION_X(i)), 3); 298 PUSH_DATAp(push, l->_VP_inf_norm, 3); 299 300 BEGIN_NV04(push, NV10_3D(LIGHT_HALF_VECTOR_X(i)), 3); 301 PUSH_DATAp(push, l->_h_inf_norm, 3); 302 } 303 304 if (l->_Flags & LIGHT_SPOT) { 305 float k[7]; 306 307 nv10_get_spot_coeff(l, k); 308 309 BEGIN_NV04(push, NV10_3D(LIGHT_SPOT_CUTOFF(i, 0)), 7); 310 PUSH_DATAp(push, k, 7); 311 } 312} 313 314#define USE_COLOR_MATERIAL(attr) \ 315 (ctx->Light.ColorMaterialEnabled && \ 316 ctx->Light._ColorMaterialBitmask & (1 << MAT_ATTRIB_FRONT_##attr)) 317 318void 319nv10_emit_material_ambient(struct gl_context *ctx, int emit) 320{ 321 struct nouveau_pushbuf *push = context_push(ctx); 322 float (*mat)[4] = ctx->Light.Material.Attrib; 323 float c_scene[3], c_factor[3]; 324 struct gl_light *l; 325 326 if (USE_COLOR_MATERIAL(AMBIENT)) { 327 COPY_3V(c_scene, ctx->Light.Model.Ambient); 328 COPY_3V(c_factor, mat[MAT_ATTRIB_FRONT_EMISSION]); 329 330 } else if (USE_COLOR_MATERIAL(EMISSION)) { 331 SCALE_3V(c_scene, mat[MAT_ATTRIB_FRONT_AMBIENT], 332 ctx->Light.Model.Ambient); 333 ZERO_3V(c_factor); 334 335 } else { 336 COPY_3V(c_scene, ctx->Light._BaseColor[0]); 337 ZERO_3V(c_factor); 338 } 339 340 BEGIN_NV04(push, NV10_3D(LIGHT_MODEL_AMBIENT_R), 3); 341 PUSH_DATAp(push, c_scene, 3); 342 343 if (ctx->Light.ColorMaterialEnabled) { 344 BEGIN_NV04(push, NV10_3D(MATERIAL_FACTOR_R), 3); 345 PUSH_DATAp(push, c_factor, 3); 346 } 347 348 foreach(l, &ctx->Light.EnabledList) { 349 const int i = l - ctx->Light.Light; 350 float *c_light = (USE_COLOR_MATERIAL(AMBIENT) ? 351 l->Ambient : 352 l->_MatAmbient[0]); 353 354 BEGIN_NV04(push, NV10_3D(LIGHT_AMBIENT_R(i)), 3); 355 PUSH_DATAp(push, c_light, 3); 356 } 357} 358 359void 360nv10_emit_material_diffuse(struct gl_context *ctx, int emit) 361{ 362 struct nouveau_pushbuf *push = context_push(ctx); 363 GLfloat (*mat)[4] = ctx->Light.Material.Attrib; 364 struct gl_light *l; 365 366 BEGIN_NV04(push, NV10_3D(MATERIAL_FACTOR_A), 1); 367 PUSH_DATAf(push, mat[MAT_ATTRIB_FRONT_DIFFUSE][3]); 368 369 foreach(l, &ctx->Light.EnabledList) { 370 const int i = l - ctx->Light.Light; 371 float *c_light = (USE_COLOR_MATERIAL(DIFFUSE) ? 372 l->Diffuse : 373 l->_MatDiffuse[0]); 374 375 BEGIN_NV04(push, NV10_3D(LIGHT_DIFFUSE_R(i)), 3); 376 PUSH_DATAp(push, c_light, 3); 377 } 378} 379 380void 381nv10_emit_material_specular(struct gl_context *ctx, int emit) 382{ 383 struct nouveau_pushbuf *push = context_push(ctx); 384 struct gl_light *l; 385 386 foreach(l, &ctx->Light.EnabledList) { 387 const int i = l - ctx->Light.Light; 388 float *c_light = (USE_COLOR_MATERIAL(SPECULAR) ? 389 l->Specular : 390 l->_MatSpecular[0]); 391 392 BEGIN_NV04(push, NV10_3D(LIGHT_SPECULAR_R(i)), 3); 393 PUSH_DATAp(push, c_light, 3); 394 } 395} 396 397static const float nv10_shininess_param[6][16] = { 398 { 0.70, 0.00, 0.06, 0.06, 0.05, 0.04, 0.02, 0.00, 399 -0.06, -0.13, -0.24, -0.36, -0.51, -0.66, -0.82, -1.00 }, 400 { 0.01, 1.00, -2.29, -2.77, -2.96, -3.06, -3.12, -3.18, 401 -3.24, -3.29, -3.36, -3.43, -3.51, -3.75, -4.33, -5.11 }, 402 { 0.02, 0.00, 2.28, 2.75, 2.94, 3.04, 3.1, 3.15, 403 3.18, 3.22, 3.27, 3.32, 3.39, 3.48, 3.84, 5.11 }, 404 { 0.70, 0.00, 0.05, 0.06, 0.06, 0.06, 0.05, 0.04, 405 0.02, 0.01, -0.03, -0.12, -0.25, -0.43, -0.68, -0.99 }, 406 { 0.01, 1.00, -1.61, -2.35, -2.67, -2.84, -2.96, -3.05, 407 -3.08, -3.14, -3.2, -3.26, -3.32, -3.42, -3.54, -4.21 }, 408 { 0.01, 0.00, 2.25, 2.73, 2.92, 3.03, 3.09, 3.15, 409 3.16, 3.21, 3.25, 3.29, 3.35, 3.43, 3.56, 4.22 }, 410}; 411 412void 413nv10_get_shininess_coeff(float s, float k[6]) 414{ 415 int i; 416 417 for (i = 0; i < 6; i++) 418 k[i] = get_shine(nv10_shininess_param[i], s); 419} 420 421void 422nv10_emit_material_shininess(struct gl_context *ctx, int emit) 423{ 424 struct nouveau_pushbuf *push = context_push(ctx); 425 float (*mat)[4] = ctx->Light.Material.Attrib; 426 float k[6]; 427 428 nv10_get_shininess_coeff( 429 CLAMP(mat[MAT_ATTRIB_FRONT_SHININESS][0], 0, 1024), 430 k); 431 432 BEGIN_NV04(push, NV10_3D(MATERIAL_SHININESS(0)), 6); 433 PUSH_DATAp(push, k, 6); 434} 435 436void 437nv10_emit_modelview(struct gl_context *ctx, int emit) 438{ 439 struct nouveau_context *nctx = to_nouveau_context(ctx); 440 struct nouveau_pushbuf *push = context_push(ctx); 441 GLmatrix *m = ctx->ModelviewMatrixStack.Top; 442 443 if (nctx->fallback != HWTNL) 444 return; 445 446 if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled || 447 (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) { 448 BEGIN_NV04(push, NV10_3D(MODELVIEW_MATRIX(0, 0)), 16); 449 PUSH_DATAm(push, m->m); 450 } 451 452 if (ctx->Light.Enabled || 453 (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) { 454 int i, j; 455 456 BEGIN_NV04(push, NV10_3D(INVERSE_MODELVIEW_MATRIX(0, 0)), 12); 457 for (i = 0; i < 3; i++) 458 for (j = 0; j < 4; j++) 459 PUSH_DATAf(push, m->inv[4*i + j]); 460 } 461} 462 463void 464nv10_emit_point_parameter(struct gl_context *ctx, int emit) 465{ 466} 467 468void 469nv10_emit_projection(struct gl_context *ctx, int emit) 470{ 471 struct nouveau_context *nctx = to_nouveau_context(ctx); 472 struct nouveau_pushbuf *push = context_push(ctx); 473 GLmatrix m; 474 475 _math_matrix_ctr(&m); 476 get_viewport_scale(ctx, m.m); 477 478 if (nv10_use_viewport_zclear(ctx)) 479 m.m[MAT_SZ] /= 8; 480 481 if (nctx->fallback == HWTNL) 482 _math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix); 483 484 BEGIN_NV04(push, NV10_3D(PROJECTION_MATRIX(0)), 16); 485 PUSH_DATAm(push, m.m); 486 487 _math_matrix_dtr(&m); 488} 489