1bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/*
2bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Copyright (C) 2009-2010 Francisco Jerez.
3bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * All Rights Reserved.
4bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
5bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Permission is hereby granted, free of charge, to any person obtaining
6bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * a copy of this software and associated documentation files (the
7bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * "Software"), to deal in the Software without restriction, including
8bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * without limitation the rights to use, copy, modify, merge, publish,
9bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * distribute, sublicense, and/or sell copies of the Software, and to
10bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * permit persons to whom the Software is furnished to do so, subject to
11bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * the following conditions:
12bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
13bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * The above copyright notice and this permission notice (including the
14bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * next paragraph) shall be included in all copies or substantial
15bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * portions of the Software.
16bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
17bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
25bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez */
26bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
27bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_driver.h"
28bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_context.h"
29bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_gldefs.h"
30bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_util.h"
31f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný#include "nv10_3d.xml.h"
32bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nv10_driver.h"
33bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
35f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_clip_plane(struct gl_context *ctx, int emit)
36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
39bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic inline unsigned
40bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_material_bitmask(unsigned m)
41bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	unsigned ret = 0;
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
44bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (m & MAT_BIT_FRONT_EMISSION)
45f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný		ret |= NV10_3D_COLOR_MATERIAL_EMISSION;
46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (m & MAT_BIT_FRONT_AMBIENT)
47f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný		ret |= NV10_3D_COLOR_MATERIAL_AMBIENT;
48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (m & MAT_BIT_FRONT_DIFFUSE)
49f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný		ret |= NV10_3D_COLOR_MATERIAL_DIFFUSE;
50bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (m & MAT_BIT_FRONT_SPECULAR)
51f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný		ret |= NV10_3D_COLOR_MATERIAL_SPECULAR;
52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
53bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return ret;
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
57f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_color_material(struct gl_context *ctx, int emit)
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
592e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
604cb3579e52fed48d623698610e31d05ac8c8946fBrian Paul	unsigned mask = get_material_bitmask(ctx->Light._ColorMaterialBitmask);
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
622e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(COLOR_MATERIAL), 1);
632e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, ctx->Light.ColorMaterialEnabled ? mask : 0);
64bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
66bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic unsigned
67bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_fog_mode(unsigned mode)
68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (mode) {
70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LINEAR:
71f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný		return NV10_3D_FOG_MODE_LINEAR;
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_EXP:
73f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný		return NV10_3D_FOG_MODE_EXP;
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_EXP2:
75f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný		return NV10_3D_FOG_MODE_EXP2;
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
80bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic unsigned
8266389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miellget_fog_source(unsigned source, unsigned distance_mode)
83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (source) {
85bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_FOG_COORDINATE_EXT:
86f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný		return NV10_3D_FOG_COORD_FOG;
87bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_FRAGMENT_DEPTH_EXT:
8866389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell		switch (distance_mode) {
8966389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell		case GL_EYE_PLANE_ABSOLUTE_NV:
9066389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell			return NV10_3D_FOG_COORD_DIST_ORTHOGONAL_ABS;
9166389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell		case GL_EYE_PLANE:
9266389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell			return NV10_3D_FOG_COORD_DIST_ORTHOGONAL;
9366389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell		case GL_EYE_RADIAL_NV:
9466389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell			return NV10_3D_FOG_COORD_DIST_RADIAL;
9566389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell		default:
9666389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell			assert(0);
9766389bb99d86c8d96c2a7dbd83a5227c0e13e767Nicholas Miell		}
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
104f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_get_fog_coeff(struct gl_context *ctx, float k[3])
105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_fog_attrib *f = &ctx->Fog;
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (f->Mode) {
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LINEAR:
110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = 2 + f->Start / (f->End - f->Start);
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = -1 / (f->End - f->Start);
112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
114bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_EXP:
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = 1.5;
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = -0.09 * f->Density;
117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
118bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_EXP2:
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = 1.5;
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = -0.21 * f->Density;
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	k[2] = 0;
129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
131bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
132f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_fog(struct gl_context *ctx, int emit)
133bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
134bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
1352e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
136bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_fog_attrib *f = &ctx->Fog;
137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	unsigned source = nctx->fallback == HWTNL ?
138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		f->FogCoordinateSource : GL_FOG_COORDINATE_EXT;
139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float k[3];
140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nv10_get_fog_coeff(ctx, k);
142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1432e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(FOG_MODE), 4);
1442e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, get_fog_mode(f->Mode));
1452e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, get_fog_source(source, f->FogDistanceMode));
1462e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATAb(push, f->Enabled);
1472e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, pack_rgba_f(MESA_FORMAT_RGBA8888_REV, f->Color));
148bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1492e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(FOG_COEFF(0)), 3);
1502e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATAp(push, k, 3);
151bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
152bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAG);
153bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
154bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
155bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic inline unsigned
156bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_light_mode(struct gl_light *l)
157bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
158bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (l->Enabled) {
159bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (l->_Flags & LIGHT_SPOT)
160f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný			return NV10_3D_ENABLED_LIGHTS_0_DIRECTIONAL;
161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		else if (l->_Flags & LIGHT_POSITIONAL)
162f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný			return NV10_3D_ENABLED_LIGHTS_0_POSITIONAL;
163bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		else
164f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný			return NV10_3D_ENABLED_LIGHTS_0_NONPOSITIONAL;
165bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
166f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný		return NV10_3D_ENABLED_LIGHTS_0_DISABLED;
167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
168bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
171f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_light_enable(struct gl_context *ctx, int emit)
172bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
173bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
1742e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	uint32_t en_lights = 0;
176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
177bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
178bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (nctx->fallback != HWTNL) {
1792e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(LIGHTING_ENABLE), 1);
1802e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATA (push, 0);
181bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return;
182bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
183bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
184bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < MAX_LIGHTS; i++)
185bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		en_lights |= get_light_mode(&ctx->Light.Light[i]) << 2 * i;
186bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1872e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(ENABLED_LIGHTS), 1);
1882e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, en_lights);
1892e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(LIGHTING_ENABLE), 1);
1902e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATAb(push, ctx->Light.Enabled);
1912e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(NORMALIZE_ENABLE), 1);
1922e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATAb(push, ctx->Transform.Normalize);
193bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
194bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
196f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_light_model(struct gl_context *ctx, int emit)
197bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
1982e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_lightmodel *m = &ctx->Light.Model;
200bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
2012e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(SEPARATE_SPECULAR_ENABLE), 1);
2022e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATAb(push, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR);
203bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
2042e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(LIGHT_MODEL), 1);
2052e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, ((m->LocalViewer ?
206f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný			 NV10_3D_LIGHT_MODEL_LOCAL_VIEWER : 0) |
207decc6e2a32ef49e673c081f30e19b8970155d887Brian Paul			(_mesa_need_secondary_color(ctx) ?
208f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný			 NV10_3D_LIGHT_MODEL_SEPARATE_SPECULAR : 0) |
20975f52d1e5210944d7e92787c637285fd83533053Francisco Jerez			(!ctx->Light.Enabled && ctx->Fog.ColorSumEnabled ?
210f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný			 NV10_3D_LIGHT_MODEL_VERTEX_SPECULAR : 0)));
211bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
212bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
213bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic float
214bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_shine(const float p[], float x)
215bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
216bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	const int n = 15;
217bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	const float *y = &p[1];
218bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float f = (n - 1) * (1 - 1 / (1 + p[0] * x))
219bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		/ (1 - 1 / (1 + p[0] * 1024));
220bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i = f;
221bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
222bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Linear interpolation in f-space (Faster and somewhat more
223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 * accurate than x-space). */
224bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (x == 0)
225bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return y[0];
226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	else if (i > n - 2)
227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return y[n - 1];
228bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	else
229bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return y[i] + (y[i + 1] - y[i]) * (f - i);
230bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
231bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
232bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic const float nv10_spot_params[2][16] = {
233bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.02, -3.80e-05, -1.77, -2.41, -2.71, -2.88, -2.98, -3.06,
234bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  -3.11, -3.17, -3.23, -3.28, -3.37, -3.47, -3.83, -5.11 },
235bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.02, -0.01, 1.77, 2.39, 2.70, 2.87, 2.98, 3.06,
236bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  3.10, 3.16, 3.23, 3.27, 3.37, 3.47, 3.83, 5.11 },
237bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez};
238bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
239bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
240bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_get_spot_coeff(struct gl_light *l, float k[7])
241bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
242bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float e = l->SpotExponent;
243bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float a0, b0, a1, a2, b2, a3;
244bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
245bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (e > 0)
246bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		a0 = -1 - 5.36e-3 / sqrt(e);
247bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	else
248bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		a0 = -1;
249bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	b0 = 1 / (1 + 0.273 * e);
250bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
251bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a1 = get_shine(nv10_spot_params[0], e);
252bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
253bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a2 = get_shine(nv10_spot_params[1], e);
254bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	b2 = 1 / (1 + 0.273 * e);
255bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
256bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a3 = 0.9 + 0.278 * e;
257bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
258bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (l->SpotCutoff > 0) {
259bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float cutoff = MAX2(a3, 1 / (1 - l->_CosCutoff));
260bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
261bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = MAX2(0, a0 + b0 * cutoff);
262bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = a1;
263bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[2] = a2 + b2 * cutoff;
264bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[3] = - cutoff * l->_NormSpotDirection[0];
265bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[4] = - cutoff * l->_NormSpotDirection[1];
266bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[5] = - cutoff * l->_NormSpotDirection[2];
267bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[6] = 1 - cutoff;
268bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
269bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
270bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = b0;
271bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = a1;
272bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[2] = a2 + b2;
273bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[3] = - l->_NormSpotDirection[0];
274bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[4] = - l->_NormSpotDirection[1];
275bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[5] = - l->_NormSpotDirection[2];
276bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[6] = -1;
277bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
278bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
279bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
280bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
281f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_light_source(struct gl_context *ctx, int emit)
282bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
283bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0;
2842e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
285bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_light *l = &ctx->Light.Light[i];
286bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
287bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (l->_Flags & LIGHT_POSITIONAL) {
2882e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(LIGHT_POSITION_X(i)), 3);
2892e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAp(push, l->_Position, 3);
290bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
2912e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(LIGHT_ATTENUATION_CONSTANT(i)), 3);
2922e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAf(push, l->ConstantAttenuation);
2932e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAf(push, l->LinearAttenuation);
2942e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAf(push, l->QuadraticAttenuation);
295bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
296bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
2972e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(LIGHT_DIRECTION_X(i)), 3);
2982e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAp(push, l->_VP_inf_norm, 3);
299bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3002e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(LIGHT_HALF_VECTOR_X(i)), 3);
3012e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAp(push, l->_h_inf_norm, 3);
302bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
303bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
304bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (l->_Flags & LIGHT_SPOT) {
305bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float k[7];
306bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
307bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		nv10_get_spot_coeff(l, k);
308bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3092e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(LIGHT_SPOT_CUTOFF(i, 0)), 7);
3102e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAp(push, k, 7);
311bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
312bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
313bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
314bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define USE_COLOR_MATERIAL(attr)					\
315bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	(ctx->Light.ColorMaterialEnabled &&				\
3164cb3579e52fed48d623698610e31d05ac8c8946fBrian Paul	 ctx->Light._ColorMaterialBitmask & (1 << MAT_ATTRIB_FRONT_##attr))
317bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
318bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
319f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_material_ambient(struct gl_context *ctx, int emit)
320bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
3212e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
322bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float (*mat)[4] = ctx->Light.Material.Attrib;
323bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float c_scene[3], c_factor[3];
324bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_light *l;
325bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
326bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (USE_COLOR_MATERIAL(AMBIENT)) {
327bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		COPY_3V(c_scene, ctx->Light.Model.Ambient);
328bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		COPY_3V(c_factor, mat[MAT_ATTRIB_FRONT_EMISSION]);
329bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
330bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else if (USE_COLOR_MATERIAL(EMISSION)) {
331bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		SCALE_3V(c_scene, mat[MAT_ATTRIB_FRONT_AMBIENT],
332bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 ctx->Light.Model.Ambient);
333bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		ZERO_3V(c_factor);
334bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
335bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
336bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		COPY_3V(c_scene, ctx->Light._BaseColor[0]);
337bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		ZERO_3V(c_factor);
338bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
339bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3402e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(LIGHT_MODEL_AMBIENT_R), 3);
3412e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATAp(push, c_scene, 3);
342bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
343bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Light.ColorMaterialEnabled) {
3442e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(MATERIAL_FACTOR_R), 3);
3452e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAp(push, c_factor, 3);
346bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
347bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
348bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	foreach(l, &ctx->Light.EnabledList) {
349bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		const int i = l - ctx->Light.Light;
350bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float *c_light = (USE_COLOR_MATERIAL(AMBIENT) ?
351bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->Ambient :
352bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->_MatAmbient[0]);
353bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3542e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(LIGHT_AMBIENT_R(i)), 3);
3552e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAp(push, c_light, 3);
356bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
357bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
358bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
359bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
360f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_material_diffuse(struct gl_context *ctx, int emit)
361bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
3622e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
363bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
364bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_light *l;
365bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3662e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(MATERIAL_FACTOR_A), 1);
3672e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATAf(push, mat[MAT_ATTRIB_FRONT_DIFFUSE][3]);
368bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
369bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	foreach(l, &ctx->Light.EnabledList) {
370bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		const int i = l - ctx->Light.Light;
371bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float *c_light = (USE_COLOR_MATERIAL(DIFFUSE) ?
372bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->Diffuse :
373bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->_MatDiffuse[0]);
374bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3752e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(LIGHT_DIFFUSE_R(i)), 3);
3762e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAp(push, c_light, 3);
377bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
378bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
379bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
380bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
381f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_material_specular(struct gl_context *ctx, int emit)
382bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
3832e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
384bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_light *l;
385bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
386bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	foreach(l, &ctx->Light.EnabledList) {
387bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		const int i = l - ctx->Light.Light;
388bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float *c_light = (USE_COLOR_MATERIAL(SPECULAR) ?
389bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->Specular :
390bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->_MatSpecular[0]);
391bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3922e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(LIGHT_SPECULAR_R(i)), 3);
3932e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAp(push, c_light, 3);
394bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
395bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
396bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
397bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic const float nv10_shininess_param[6][16] = {
398bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.70, 0.00, 0.06, 0.06, 0.05, 0.04, 0.02, 0.00,
399bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  -0.06, -0.13, -0.24, -0.36, -0.51, -0.66, -0.82, -1.00 },
400bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.01, 1.00, -2.29, -2.77, -2.96, -3.06, -3.12, -3.18,
401bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  -3.24, -3.29, -3.36, -3.43, -3.51, -3.75, -4.33, -5.11 },
402bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.02, 0.00, 2.28, 2.75, 2.94, 3.04, 3.1, 3.15,
403bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  3.18, 3.22, 3.27, 3.32, 3.39, 3.48, 3.84, 5.11 },
404bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.70, 0.00, 0.05, 0.06, 0.06, 0.06, 0.05, 0.04,
405bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  0.02, 0.01, -0.03, -0.12, -0.25, -0.43, -0.68, -0.99 },
406bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.01, 1.00, -1.61, -2.35, -2.67, -2.84, -2.96, -3.05,
407bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  -3.08, -3.14, -3.2, -3.26, -3.32, -3.42, -3.54, -4.21 },
408bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.01, 0.00, 2.25, 2.73, 2.92, 3.03, 3.09, 3.15,
409bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  3.16, 3.21, 3.25, 3.29, 3.35, 3.43, 3.56, 4.22 },
410bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez};
411bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
412bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
413bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_get_shininess_coeff(float s, float k[6])
414bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
415bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
416bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
417bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < 6; i++)
418bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[i] = get_shine(nv10_shininess_param[i], s);
419bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
420bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
421bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
422f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_material_shininess(struct gl_context *ctx, int emit)
423bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
4242e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
425bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float (*mat)[4] = ctx->Light.Material.Attrib;
426bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float k[6];
427bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
428bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nv10_get_shininess_coeff(
429bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		CLAMP(mat[MAT_ATTRIB_FRONT_SHININESS][0], 0, 1024),
430bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k);
431bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
4322e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(MATERIAL_SHININESS(0)), 6);
4332e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATAp(push, k, 6);
434bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
435bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
436bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
437f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_modelview(struct gl_context *ctx, int emit)
438bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
439bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
4402e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
441bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLmatrix *m = ctx->ModelviewMatrixStack.Top;
442bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
443bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (nctx->fallback != HWTNL)
444bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return;
445bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
446c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled ||
447c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	    (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
4482e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(MODELVIEW_MATRIX(0, 0)), 16);
4492e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		PUSH_DATAm(push, m->m);
450bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
451bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
452c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	if (ctx->Light.Enabled ||
453c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	    (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
454bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		int i, j;
455bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
4562e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs		BEGIN_NV04(push, NV10_3D(INVERSE_MODELVIEW_MATRIX(0, 0)), 12);
457bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		for (i = 0; i < 3; i++)
458bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			for (j = 0; j < 4; j++)
4592e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs				PUSH_DATAf(push, m->inv[4*i + j]);
460bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
461bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
462bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
463bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
464f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_point_parameter(struct gl_context *ctx, int emit)
465bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
466bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
467bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
468bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
469f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_projection(struct gl_context *ctx, int emit)
470bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
471bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
4722e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
473bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLmatrix m;
474bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
475bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_math_matrix_ctr(&m);
476bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	get_viewport_scale(ctx, m.m);
477bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
478e2acc7be2683fd3c295480724b02f5a497309cfdFrancisco Jerez	if (nv10_use_viewport_zclear(ctx))
479e2acc7be2683fd3c295480724b02f5a497309cfdFrancisco Jerez		m.m[MAT_SZ] /= 8;
480e2acc7be2683fd3c295480724b02f5a497309cfdFrancisco Jerez
481bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (nctx->fallback == HWTNL)
482bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		_math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix);
483bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
4842e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(PROJECTION_MATRIX(0)), 16);
4852e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATAm(push, m.m);
486bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
487bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_math_matrix_dtr(&m);
488bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
489