1bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/*
2bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Copyright (C) 2009 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_util.h"
308983855012301c8ebc023edf42ddf5e423189585Viktor Novotný#include "nv_object.xml.h"
318983855012301c8ebc023edf42ddf5e423189585Viktor Novotný#include "nv04_3d.xml.h"
32bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nv04_driver.h"
33bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define COMBINER_SHIFT(in)						\
358983855012301c8ebc023edf42ddf5e423189585Viktor Novotný	(NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT##in##__SHIFT	\
368983855012301c8ebc023edf42ddf5e423189585Viktor Novotný	 - NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0__SHIFT)
37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define COMBINER_SOURCE(reg)					\
38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_##reg
39bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define COMBINER_INVERT					\
40bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_INVERSE0
41bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define COMBINER_ALPHA					\
42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ALPHA0
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
44bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstruct combiner_state {
45f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg	struct gl_context *ctx;
46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int unit;
47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLboolean alpha;
48699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez	GLboolean premodulate;
49bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
50bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* GL state */
51bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLenum mode;
52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLenum *source;
53bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLenum *operand;
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLuint logscale;
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Derived HW state */
57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	uint32_t hw;
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez};
59bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define __INIT_COMBINER_ALPHA_A GL_TRUE
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define __INIT_COMBINER_ALPHA_RGB GL_FALSE
62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Initialize a combiner_state struct from the texture unit
64bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * context. */
653ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez#define INIT_COMBINER(chan, ctx, rc, i) do {			\
66bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		struct gl_tex_env_combine_state *c =		\
67bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			ctx->Texture.Unit[i]._CurrentCombine;	\
683ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		(rc)->ctx = ctx;				\
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->unit = i;					\
703ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		(rc)->alpha = __INIT_COMBINER_ALPHA_##chan;	\
71699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez		(rc)->premodulate = c->_NumArgs##chan == 4;	\
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->mode = c->Mode##chan;			\
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->source = c->Source##chan;			\
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->operand = c->Operand##chan;		\
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->logscale = c->ScaleShift##chan;		\
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->hw = 0;					\
77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} while (0)
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Get the combiner source for the specified EXT_texture_env_combine
803ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez * source. */
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic uint32_t
823ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerezget_input_source(struct combiner_state *rc, int source)
83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
843ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	switch (source) {
85699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez	case GL_ZERO:
86699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez		return COMBINER_SOURCE(ZERO);
87699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez
88bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_TEXTURE:
89bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return rc->unit ? COMBINER_SOURCE(TEXTURE1) :
90bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			COMBINER_SOURCE(TEXTURE0);
91bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
92bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_TEXTURE0:
93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return COMBINER_SOURCE(TEXTURE0);
94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_TEXTURE1:
96bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return COMBINER_SOURCE(TEXTURE1);
97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_CONSTANT:
99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return COMBINER_SOURCE(CONSTANT);
100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_PRIMARY_COLOR:
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return COMBINER_SOURCE(PRIMARY_COLOR);
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_PREVIOUS:
105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return rc->unit ? COMBINER_SOURCE(PREVIOUS) :
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			COMBINER_SOURCE(PRIMARY_COLOR);
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Get the (possibly inverted) combiner input mapping for the
1143ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez * specified EXT_texture_env_combine operand. */
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define INVERT 0x1
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic uint32_t
1183ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerezget_input_mapping(struct combiner_state *rc, int operand, int flags)
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int map = 0;
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1223ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	if (!is_color_operand(operand) && !rc->alpha)
1233ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		map |= COMBINER_ALPHA;
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1253ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	if (is_negative_operand(operand) == !(flags & INVERT))
1263ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		map |= COMBINER_INVERT;
127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1283ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	return map;
1293ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez}
130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1313ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerezstatic uint32_t
1323ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerezget_input_arg(struct combiner_state *rc, int arg, int flags)
1333ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez{
1343ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	int source = rc->source[arg];
1353ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	int operand = rc->operand[arg];
1363ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez
1373ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	/* Fake several unsupported texture formats. */
1383ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	if (is_texture_source(source)) {
1393ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		int i = (source == GL_TEXTURE ?
1403ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez			 rc->unit : source - GL_TEXTURE0);
1413ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		struct gl_texture_object *t = rc->ctx->Texture.Unit[i]._Current;
1423ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		gl_format format = t->Image[0][t->BaseLevel]->TexFormat;
1433ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez
1443ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		if (format == MESA_FORMAT_A8) {
1453ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez			/* Emulated using I8. */
1463ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez			if (is_color_operand(operand))
1473ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez				return COMBINER_SOURCE(ZERO) |
1483ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez					get_input_mapping(rc, operand, flags);
1493ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez
1503ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		} else if (format == MESA_FORMAT_L8) {
1513ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez			/* Emulated using I8. */
1523ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez			if (!is_color_operand(operand))
1533ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez				return COMBINER_SOURCE(ZERO) |
1543ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez					get_input_mapping(rc, operand,
1553ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez							  flags ^ INVERT);
1563ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		}
157bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
158bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1593ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	return get_input_source(rc, source) |
1603ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		get_input_mapping(rc, operand, flags);
161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
162bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
163bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Bind the combiner input <in> to the combiner source <src>,
164bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * possibly inverted. */
165bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define INPUT_SRC(rc, in, src, flags)					\
166bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	(rc)->hw |= ((flags & INVERT ? COMBINER_INVERT : 0) |		\
167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		   COMBINER_SOURCE(src)) << COMBINER_SHIFT(in)
168bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Bind the combiner input <in> to the EXT_texture_env_combine
170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * argument <arg>, possibly inverted. */
171bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define INPUT_ARG(rc, in, arg, flags)					\
1723ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez	(rc)->hw |= get_input_arg(rc, arg, flags) << COMBINER_SHIFT(in)
173bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
174bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define UNSIGNED_OP(rc)							\
175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	(rc)->hw |= ((rc)->logscale ?					\
176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_SCALE2 :	\
177bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_IDENTITY)
178bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define SIGNED_OP(rc)							\
179bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	(rc)->hw |= ((rc)->logscale ?					\
180bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS_SCALE2 : \
181bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS)
182bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
183bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
184bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezsetup_combiner(struct combiner_state *rc)
185bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
186bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (rc->mode) {
187bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_REPLACE:
188bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, 0, 0, 0);
189bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(rc, 1, ZERO, INVERT);
190bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(rc, 2, ZERO, 0);
191bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(rc, 3, ZERO, 0);
192bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		UNSIGNED_OP(rc);
193bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
194bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_MODULATE:
196bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, 0, 0, 0);
197bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, 1, 1, 0);
198bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(rc, 2, ZERO, 0);
199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(rc, 3, ZERO, 0);
200bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		UNSIGNED_OP(rc);
201bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
202bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
203bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_ADD:
204699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez	case GL_ADD_SIGNED:
205699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez		if (rc->premodulate) {
206699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			INPUT_ARG(rc, 0, 0, 0);
207699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			INPUT_ARG(rc, 1, 1, 0);
208699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			INPUT_ARG(rc, 2, 2, 0);
209699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			INPUT_ARG(rc, 3, 3, 0);
210699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez		} else {
211699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			INPUT_ARG(rc, 0, 0, 0);
212699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			INPUT_SRC(rc, 1, ZERO, INVERT);
213699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			INPUT_ARG(rc, 2, 1, 0);
214699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			INPUT_SRC(rc, 3, ZERO, INVERT);
215699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez		}
216699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez
217699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez		if (rc->mode == GL_ADD_SIGNED)
218699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			SIGNED_OP(rc);
219699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez		else
220699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez			UNSIGNED_OP(rc);
221699749cfeeea7d0a17ed5f94fd5fdbbe52f4ab2bFrancisco Jerez
222bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
224bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTERPOLATE:
225bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, 0, 0, 0);
226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, 1, 2, 0);
227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, 2, 1, 0);
228bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, 3, 2, INVERT);
229bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		UNSIGNED_OP(rc);
230bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
231bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
232bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
233bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
234bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
235bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
236bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
237f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggsstatic unsigned
238f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggsget_texenv_mode(unsigned mode)
239f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs{
240f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	switch (mode) {
241f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	case GL_REPLACE:
242f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs		return 0x1;
243f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	case GL_DECAL:
244f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs		return 0x3;
245f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	case GL_MODULATE:
246f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs		return 0x4;
247f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	default:
248f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs		assert(0);
249f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	}
250f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs}
251f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs
252bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
253f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv04_emit_tex_env(struct gl_context *ctx, int emit)
254bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
255f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	struct nv04_context *nv04 = to_nv04_context(ctx);
256bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	const int i = emit - NOUVEAU_STATE_TEX_ENV0;
257bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct combiner_state rc_a = {}, rc_c = {};
258bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
259bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Compute the new combiner state. */
260bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Texture.Unit[i]._ReallyEnabled) {
2613ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		INIT_COMBINER(A, ctx, &rc_a, i);
262bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		setup_combiner(&rc_a);
263bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
2643ccfce85e243e83afc1bb582d7424d9238a64f42Francisco Jerez		INIT_COMBINER(RGB, ctx, &rc_c, i);
265bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		setup_combiner(&rc_c);
266bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
267bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
268bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (i == 0) {
269bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			INPUT_SRC(&rc_a, 0, PRIMARY_COLOR, 0);
270bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			INPUT_SRC(&rc_c, 0, PRIMARY_COLOR, 0);
271bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		} else {
272bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			INPUT_SRC(&rc_a, 0, PREVIOUS, 0);
273bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			INPUT_SRC(&rc_c, 0, PREVIOUS, 0);
274bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
275bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
276bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc_a, 1, ZERO, INVERT);
277bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc_c, 1, ZERO, INVERT);
278bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc_a, 2, ZERO, 0);
279bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc_c, 2, ZERO, 0);
280bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc_a, 3, ZERO, 0);
281bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc_c, 3, ZERO, 0);
282bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
283bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		UNSIGNED_OP(&rc_a);
284bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		UNSIGNED_OP(&rc_c);
285bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
286bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
287f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	/* calculate non-multitex state */
288f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	nv04->blend &= ~NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP__MASK;
289f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	if (ctx->Texture._EnabledUnits)
290f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs		nv04->blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode);
291f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	else
292f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs		nv04->blend |= get_texenv_mode(GL_MODULATE);
293f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs
294f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	/* update calculated multitex state */
295f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	nv04->alpha[i] = rc_a.hw;
296f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	nv04->color[i] = rc_c.hw;
297f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs	nv04->factor   = pack_rgba_f(MESA_FORMAT_ARGB8888,
298f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652Ben Skeggs				     ctx->Texture.Unit[0].EnvColor);
299bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
300