nv10_state_tnl.c revision c944fb5ffe7cf16154d6395001f43a6c965cab1f
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"
31bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_class.h"
32bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nv10_driver.h"
33bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
35bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_clip_plane(GLcontext *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)
45bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		ret |= NV10TCL_COLOR_MATERIAL_EMISSION;
46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (m & MAT_BIT_FRONT_AMBIENT)
47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		ret |= NV10TCL_COLOR_MATERIAL_AMBIENT;
48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (m & MAT_BIT_FRONT_DIFFUSE)
49bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		ret |= NV10TCL_COLOR_MATERIAL_DIFFUSE;
50bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (m & MAT_BIT_FRONT_SPECULAR)
51bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		ret |= NV10TCL_COLOR_MATERIAL_SPECULAR;
52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
53bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return ret;
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_color_material(GLcontext *ctx, int emit)
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
59bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	unsigned mask = get_material_bitmask(ctx->Light.ColorMaterialBitmask);
62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_COLOR_MATERIAL, 1);
64bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, ctx->Light.ColorMaterialEnabled ? mask : 0);
65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
66bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
67bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic unsigned
68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_fog_mode(unsigned mode)
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (mode) {
71bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LINEAR:
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NV10TCL_FOG_MODE_LINEAR;
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_EXP:
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NV10TCL_FOG_MODE_EXP;
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_EXP2:
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NV10TCL_FOG_MODE_EXP2;
77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
80bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
82bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic unsigned
83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_fog_source(unsigned source)
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
85bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (source) {
86bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_FOG_COORDINATE_EXT:
87bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NV10TCL_FOG_COORD_FOG;
88bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_FRAGMENT_DEPTH_EXT:
89bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NV10TCL_FOG_COORD_DIST_ORTHOGONAL_ABS;
90bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
91bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
92bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
96bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_get_fog_coeff(GLcontext *ctx, float k[3])
97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_fog_attrib *f = &ctx->Fog;
99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (f->Mode) {
101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_LINEAR:
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = 2 + f->Start / (f->End - f->Start);
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = -1 / (f->End - f->Start);
104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_EXP:
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = 1.5;
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = -0.09 * f->Density;
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_EXP2:
112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = 1.5;
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = -0.21 * f->Density;
114bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
118bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	k[2] = 0;
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_fog(GLcontext *ctx, int emit)
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_fog_attrib *f = &ctx->Fog;
130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	unsigned source = nctx->fallback == HWTNL ?
131bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		f->FogCoordinateSource : GL_FOG_COORDINATE_EXT;
132bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float k[3];
133bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
134bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nv10_get_fog_coeff(ctx, k);
135bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
136bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 4);
137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, get_fog_mode(f->Mode));
138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, get_fog_source(source));
139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, f->Enabled ? 1 : 0);
140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, pack_rgba_f(MESA_FORMAT_RGBA8888_REV, f->Color));
141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3);
143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, k[0]);
144bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, k[1]);
145bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, k[2]);
146bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
147bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAG);
148bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
149bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
150bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic inline unsigned
151bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_light_mode(struct gl_light *l)
152bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
153bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (l->Enabled) {
154bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (l->_Flags & LIGHT_SPOT)
155bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			return NV10TCL_ENABLED_LIGHTS_0_DIRECTIONAL;
156bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		else if (l->_Flags & LIGHT_POSITIONAL)
157bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			return NV10TCL_ENABLED_LIGHTS_0_POSITIONAL;
158bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		else
159bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			return NV10TCL_ENABLED_LIGHTS_0_NONPOSITIONAL;
160bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NV10TCL_ENABLED_LIGHTS_0_DISABLED;
162bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
163bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
164bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
165bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
166bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_light_enable(GLcontext *ctx, int emit)
167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
168bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
171bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	uint32_t en_lights = 0;
172bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
173bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
174bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (nctx->fallback != HWTNL) {
175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_LIGHTING_ENABLE, 1);
176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RING(chan, 0);
177bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return;
178bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
179bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
180bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < MAX_LIGHTS; i++)
181bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		en_lights |= get_light_mode(&ctx->Light.Light[i]) << 2 * i;
182bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
183bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1);
184bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, en_lights);
185bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_LIGHTING_ENABLE, 1);
186bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, ctx->Light.Enabled ? 1 : 0);
187bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1);
188bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, ctx->Transform.Normalize ? 1 : 0);
189bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
190bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
191bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
192bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_light_model(GLcontext *ctx, int emit)
193bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
194bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
196bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_lightmodel *m = &ctx->Light.Model;
197bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
198bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_SEPARATE_SPECULAR_ENABLE, 1);
199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? 1 : 0);
200bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
201bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1);
202bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RING(chan, ((m->LocalViewer ?
203bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 NV10TCL_LIGHT_MODEL_LOCAL_VIEWER : 0) |
20475f52d1e5210944d7e92787c637285fd83533053Francisco Jerez			(NEED_SECONDARY_COLOR(ctx) ?
20575f52d1e5210944d7e92787c637285fd83533053Francisco Jerez			 NV10TCL_LIGHT_MODEL_SEPARATE_SPECULAR : 0) |
20675f52d1e5210944d7e92787c637285fd83533053Francisco Jerez			(!ctx->Light.Enabled && ctx->Fog.ColorSumEnabled ?
20775f52d1e5210944d7e92787c637285fd83533053Francisco Jerez			 NV10TCL_LIGHT_MODEL_VERTEX_SPECULAR : 0)));
208bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
209bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
210bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic float
211bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_shine(const float p[], float x)
212bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
213bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	const int n = 15;
214bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	const float *y = &p[1];
215bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float f = (n - 1) * (1 - 1 / (1 + p[0] * x))
216bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		/ (1 - 1 / (1 + p[0] * 1024));
217bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i = f;
218bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
219bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Linear interpolation in f-space (Faster and somewhat more
220bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 * accurate than x-space). */
221bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (x == 0)
222bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return y[0];
223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	else if (i > n - 2)
224bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return y[n - 1];
225bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	else
226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return y[i] + (y[i + 1] - y[i]) * (f - i);
227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
228bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
229bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic const float nv10_spot_params[2][16] = {
230bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.02, -3.80e-05, -1.77, -2.41, -2.71, -2.88, -2.98, -3.06,
231bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  -3.11, -3.17, -3.23, -3.28, -3.37, -3.47, -3.83, -5.11 },
232bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.02, -0.01, 1.77, 2.39, 2.70, 2.87, 2.98, 3.06,
233bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  3.10, 3.16, 3.23, 3.27, 3.37, 3.47, 3.83, 5.11 },
234bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez};
235bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
236bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
237bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_get_spot_coeff(struct gl_light *l, float k[7])
238bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
239bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float e = l->SpotExponent;
240bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float a0, b0, a1, a2, b2, a3;
241bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
242bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (e > 0)
243bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		a0 = -1 - 5.36e-3 / sqrt(e);
244bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	else
245bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		a0 = -1;
246bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	b0 = 1 / (1 + 0.273 * e);
247bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
248bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a1 = get_shine(nv10_spot_params[0], e);
249bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
250bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a2 = get_shine(nv10_spot_params[1], e);
251bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	b2 = 1 / (1 + 0.273 * e);
252bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
253bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a3 = 0.9 + 0.278 * e;
254bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
255bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (l->SpotCutoff > 0) {
256bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float cutoff = MAX2(a3, 1 / (1 - l->_CosCutoff));
257bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
258bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = MAX2(0, a0 + b0 * cutoff);
259bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = a1;
260bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[2] = a2 + b2 * cutoff;
261bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[3] = - cutoff * l->_NormSpotDirection[0];
262bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[4] = - cutoff * l->_NormSpotDirection[1];
263bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[5] = - cutoff * l->_NormSpotDirection[2];
264bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[6] = 1 - cutoff;
265bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
266bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
267bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[0] = b0;
268bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[1] = a1;
269bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[2] = a2 + b2;
270bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[3] = - l->_NormSpotDirection[0];
271bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[4] = - l->_NormSpotDirection[1];
272bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[5] = - l->_NormSpotDirection[2];
273bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[6] = -1;
274bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
275bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
276bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
277bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
278bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_light_source(GLcontext *ctx, int emit)
279bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
280bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0;
281bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
282bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
283bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_light *l = &ctx->Light.Light[i];
284bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
285bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (l->_Flags & LIGHT_POSITIONAL) {
286bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_LIGHT_POSITION_X(i), 3);
287bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->_Position[0]);
288bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->_Position[1]);
289bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->_Position[2]);
290bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
291bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius,
292bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			   NV10TCL_LIGHT_ATTENUATION_CONSTANT(i), 3);
293bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->ConstantAttenuation);
294bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->LinearAttenuation);
295bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->QuadraticAttenuation);
296bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
297bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
298bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_LIGHT_DIRECTION_X(i), 3);
299bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->_VP_inf_norm[0]);
300bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->_VP_inf_norm[1]);
301bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->_VP_inf_norm[2]);
302bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
303bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_LIGHT_HALF_VECTOR_X(i), 3);
304bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->_h_inf_norm[0]);
305bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->_h_inf_norm[1]);
306bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, l->_h_inf_norm[2]);
307bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
308bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
309bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (l->_Flags & LIGHT_SPOT) {
310bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float k[7];
311bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
312bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		nv10_get_spot_coeff(l, k);
313bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
314bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_LIGHT_SPOT_CUTOFF_A(i), 7);
315bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, k[0]);
316bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, k[1]);
317bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, k[2]);
318bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, k[3]);
319bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, k[4]);
320bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, k[5]);
321bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, k[6]);
322bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
323bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
324bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
325bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define USE_COLOR_MATERIAL(attr)					\
326bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	(ctx->Light.ColorMaterialEnabled &&				\
327bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 ctx->Light.ColorMaterialBitmask & (1 << MAT_ATTRIB_FRONT_##attr))
328bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
329bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
330bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_material_ambient(GLcontext *ctx, int emit)
331bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
332bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
333bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
334bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float (*mat)[4] = ctx->Light.Material.Attrib;
335bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float c_scene[3], c_factor[3];
336bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_light *l;
337bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
338bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (USE_COLOR_MATERIAL(AMBIENT)) {
339bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		COPY_3V(c_scene, ctx->Light.Model.Ambient);
340bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		COPY_3V(c_factor, mat[MAT_ATTRIB_FRONT_EMISSION]);
341bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
342bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else if (USE_COLOR_MATERIAL(EMISSION)) {
343bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		SCALE_3V(c_scene, mat[MAT_ATTRIB_FRONT_AMBIENT],
344bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 ctx->Light.Model.Ambient);
345bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		ZERO_3V(c_factor);
346bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
347bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
348bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		COPY_3V(c_scene, ctx->Light._BaseColor[0]);
349bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		ZERO_3V(c_factor);
350bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
351bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
352bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL_AMBIENT_R, 3);
353bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, c_scene[0]);
354bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, c_scene[1]);
355bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, c_scene[2]);
356bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
357bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Light.ColorMaterialEnabled) {
358bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_FACTOR_R, 3);
359bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_factor[0]);
360bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_factor[1]);
361bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_factor[2]);
362bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
363bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
364bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	foreach(l, &ctx->Light.EnabledList) {
365bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		const int i = l - ctx->Light.Light;
366bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float *c_light = (USE_COLOR_MATERIAL(AMBIENT) ?
367bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->Ambient :
368bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->_MatAmbient[0]);
369bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
370bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_LIGHT_AMBIENT_R(i), 3);
371bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_light[0]);
372bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_light[1]);
373bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_light[2]);
374bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
375bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
376bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
377bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
378bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_material_diffuse(GLcontext *ctx, int emit)
379bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
380bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
381bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
382bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
383bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_light *l;
384bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
385bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_FACTOR_A, 1);
386bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, mat[MAT_ATTRIB_FRONT_DIFFUSE][3]);
387bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
388bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	foreach(l, &ctx->Light.EnabledList) {
389bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		const int i = l - ctx->Light.Light;
390bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float *c_light = (USE_COLOR_MATERIAL(DIFFUSE) ?
391bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->Diffuse :
392bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->_MatDiffuse[0]);
393bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
394bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_LIGHT_DIFFUSE_R(i), 3);
395bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_light[0]);
396bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_light[1]);
397bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_light[2]);
398bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
399bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
400bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
401bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
402bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_material_specular(GLcontext *ctx, int emit)
403bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
404bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
405bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
406bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_light *l;
407bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
408bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	foreach(l, &ctx->Light.EnabledList) {
409bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		const int i = l - ctx->Light.Light;
410bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		float *c_light = (USE_COLOR_MATERIAL(SPECULAR) ?
411bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->Specular :
412bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				  l->_MatSpecular[0]);
413bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
414bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_LIGHT_SPECULAR_R(i), 3);
415bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_light[0]);
416bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_light[1]);
417bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGf(chan, c_light[2]);
418bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
419bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
420bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
421bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic const float nv10_shininess_param[6][16] = {
422bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.70, 0.00, 0.06, 0.06, 0.05, 0.04, 0.02, 0.00,
423bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  -0.06, -0.13, -0.24, -0.36, -0.51, -0.66, -0.82, -1.00 },
424bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.01, 1.00, -2.29, -2.77, -2.96, -3.06, -3.12, -3.18,
425bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  -3.24, -3.29, -3.36, -3.43, -3.51, -3.75, -4.33, -5.11 },
426bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.02, 0.00, 2.28, 2.75, 2.94, 3.04, 3.1, 3.15,
427bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  3.18, 3.22, 3.27, 3.32, 3.39, 3.48, 3.84, 5.11 },
428bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.70, 0.00, 0.05, 0.06, 0.06, 0.06, 0.05, 0.04,
429bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  0.02, 0.01, -0.03, -0.12, -0.25, -0.43, -0.68, -0.99 },
430bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.01, 1.00, -1.61, -2.35, -2.67, -2.84, -2.96, -3.05,
431bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  -3.08, -3.14, -3.2, -3.26, -3.32, -3.42, -3.54, -4.21 },
432bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	{ 0.01, 0.00, 2.25, 2.73, 2.92, 3.03, 3.09, 3.15,
433bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	  3.16, 3.21, 3.25, 3.29, 3.35, 3.43, 3.56, 4.22 },
434bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez};
435bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
436bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
437bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_get_shininess_coeff(float s, float k[6])
438bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
439bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
440bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
441bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < 6; i++)
442bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k[i] = get_shine(nv10_shininess_param[i], s);
443bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
444bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
445bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
446bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_material_shininess(GLcontext *ctx, int emit)
447bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
448bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
449bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
450bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float (*mat)[4] = ctx->Light.Material.Attrib;
451bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	float k[6];
452bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
453bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nv10_get_shininess_coeff(
454bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		CLAMP(mat[MAT_ATTRIB_FRONT_SHININESS][0], 0, 1024),
455bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		k);
456bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
457bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_SHININESS(0), 6);
458bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, k[0]);
459bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, k[1]);
460bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, k[2]);
461bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, k[3]);
462bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, k[4]);
463bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGf(chan, k[5]);
464bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
465bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
466bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
467bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_modelview(GLcontext *ctx, int emit)
468bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
469bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
470bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
471bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
472bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLmatrix *m = ctx->ModelviewMatrixStack.Top;
473bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
474bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (nctx->fallback != HWTNL)
475bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return;
476bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
477c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled ||
478c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	    (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
479bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius, NV10TCL_MODELVIEW0_MATRIX(0), 16);
480bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		OUT_RINGm(chan, m->m);
481bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
482bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
483c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	if (ctx->Light.Enabled ||
484c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	    (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
485bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		int i, j;
486bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
487bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BEGIN_RING(chan, celsius,
488bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			   NV10TCL_INVERSE_MODELVIEW0_MATRIX(0), 12);
489bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		for (i = 0; i < 3; i++)
490bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			for (j = 0; j < 4; j++)
491bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				OUT_RINGf(chan, m->inv[4*i + j]);
492bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
493bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
494bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
495bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
496bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_point_parameter(GLcontext *ctx, int emit)
497bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
498bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
499bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
500bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
501bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznv10_emit_projection(GLcontext *ctx, int emit)
502bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
503bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
504bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
505bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_grobj *celsius = context_eng3d(ctx);
506bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLmatrix m;
507bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
508bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_math_matrix_ctr(&m);
509bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	get_viewport_scale(ctx, m.m);
510bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
511bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (nctx->fallback == HWTNL)
512bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		_math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix);
513bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
514bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	BEGIN_RING(chan, celsius, NV10TCL_PROJECTION_MATRIX(0), 16);
515bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	OUT_RINGm(chan, m.m);
516bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
517bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_math_matrix_dtr(&m);
518bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
519