1bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/*
27269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco 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"
30f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný#include "nv10_3d.xml.h"
31bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_util.h"
32bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nv10_driver.h"
33bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nv20_driver.h"
34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
35bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_SHIFT_A	24
36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_SHIFT_B	16
37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_SHIFT_C	8
38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_SHIFT_D	0
39bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_SHIFT_E	56
40bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_SHIFT_F	48
41bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_SHIFT_G	40
42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_SOURCE(source)				\
44f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný	((uint64_t)NV10_3D_RC_IN_RGB_D_INPUT_##source)
45bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_USAGE(usage)					\
46f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný	((uint64_t)NV10_3D_RC_IN_RGB_D_COMPONENT_USAGE_##usage)
47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define RC_IN_MAPPING(mapping)					\
48f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný	((uint64_t)NV10_3D_RC_IN_RGB_D_MAPPING_##mapping)
49bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
50f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný#define RC_OUT_BIAS	NV10_3D_RC_OUT_RGB_BIAS_BIAS_BY_NEGATIVE_ONE_HALF
51f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný#define RC_OUT_SCALE_1	NV10_3D_RC_OUT_RGB_SCALE_NONE
52f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný#define RC_OUT_SCALE_2	NV10_3D_RC_OUT_RGB_SCALE_SCALE_BY_TWO
53f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný#define RC_OUT_SCALE_4	NV10_3D_RC_OUT_RGB_SCALE_SCALE_BY_FOUR
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Make the combiner do: spare0_i = A_i * B_i */
56f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný#define RC_OUT_AB	NV10_3D_RC_OUT_RGB_AB_OUTPUT_SPARE0
57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* spare0_i = dot3(A, B) */
58f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný#define RC_OUT_DOT_AB	(NV10_3D_RC_OUT_RGB_AB_OUTPUT_SPARE0 |	\
59f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný			 NV10_3D_RC_OUT_RGB_AB_DOT_PRODUCT)
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* spare0_i = A_i * B_i + C_i * D_i */
61f4efc256fd90beaff86321e4c6ce00f9be55092dViktor Novotný#define RC_OUT_SUM	NV10_3D_RC_OUT_RGB_SUM_OUTPUT_SPARE0
62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstruct combiner_state {
64f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg	struct gl_context *ctx;
65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int unit;
663bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez	GLboolean premodulate;
67bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* GL state */
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLenum mode;
70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLenum *source;
71bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLenum *operand;
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	GLuint logscale;
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Derived HW state */
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	uint64_t in;
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	uint32_t out;
77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez};
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Initialize a combiner_state struct from the texture unit
80bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * context. */
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define INIT_COMBINER(chan, ctx, rc, i) do {			\
82bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		struct gl_tex_env_combine_state *c =		\
83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			ctx->Texture.Unit[i]._CurrentCombine;	\
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->ctx = ctx;				\
85bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->unit = i;					\
863bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez		(rc)->premodulate = c->_NumArgs##chan == 4;	\
87bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->mode = c->Mode##chan;			\
88bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->source = c->Source##chan;			\
89bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->operand = c->Operand##chan;		\
90bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->logscale = c->ScaleShift##chan;		\
91bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		(rc)->in = (rc)->out = 0;			\
92bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} while (0)
93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Get the RC input source for the specified EXT_texture_env_combine
957269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez * source. */
96bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic uint32_t
977269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerezget_input_source(struct combiner_state *rc, int source)
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
997269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	switch (source) {
1003bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez	case GL_ZERO:
1013bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez		return RC_IN_SOURCE(ZERO);
1023bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_TEXTURE:
104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return RC_IN_SOURCE(TEXTURE0) + rc->unit;
105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_TEXTURE0:
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return RC_IN_SOURCE(TEXTURE0);
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_TEXTURE1:
110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return RC_IN_SOURCE(TEXTURE1);
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_TEXTURE2:
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return RC_IN_SOURCE(TEXTURE2);
114bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_TEXTURE3:
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return RC_IN_SOURCE(TEXTURE3);
117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
118bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_CONSTANT:
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return context_chipset(rc->ctx) >= 0x20 ?
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			RC_IN_SOURCE(CONSTANT_COLOR0) :
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			RC_IN_SOURCE(CONSTANT_COLOR0) + rc->unit;
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_PRIMARY_COLOR:
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return RC_IN_SOURCE(PRIMARY_COLOR);
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_PREVIOUS:
127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return rc->unit ? RC_IN_SOURCE(SPARE0)
128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			: RC_IN_SOURCE(PRIMARY_COLOR);
129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
131bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
132bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
133bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
134bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1357269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez/* Get the RC input mapping for the specified texture_env_combine
1367269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez * operand, possibly inverted or biased. */
137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define INVERT 0x1
138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define HALF_BIAS 0x2
139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic uint32_t
1417269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerezget_input_mapping(struct combiner_state *rc, int operand, int flags)
142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int map = 0;
144bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1457269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	if (is_color_operand(operand))
146bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		map |= RC_IN_USAGE(RGB);
1477269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	else
148bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		map |= RC_IN_USAGE(ALPHA);
149bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1507269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	if (is_negative_operand(operand) == !(flags & INVERT))
1517269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		map |= flags & HALF_BIAS ?
1527269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			RC_IN_MAPPING(HALF_BIAS_NEGATE) :
1537269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			RC_IN_MAPPING(UNSIGNED_INVERT);
1547269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	else
1557269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		map |= flags & HALF_BIAS ?
1567269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			RC_IN_MAPPING(HALF_BIAS_NORMAL) :
1577269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			RC_IN_MAPPING(UNSIGNED_IDENTITY);
158bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1597269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	return map;
1607269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez}
1617269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
1627269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerezstatic uint32_t
1637269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerezget_input_arg(struct combiner_state *rc, int arg, int flags)
1647269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez{
1657269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	int source = rc->source[arg];
1667269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	int operand = rc->operand[arg];
1677269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
1687269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	/* Fake several unsupported texture formats. */
1697269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	if (is_texture_source(source)) {
1707269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		int i = (source == GL_TEXTURE ?
1717269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			 rc->unit : source - GL_TEXTURE0);
1727269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		struct gl_texture_object *t = rc->ctx->Texture.Unit[i]._Current;
1737269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		gl_format format = t->Image[0][t->BaseLevel]->TexFormat;
1747269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
1757269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		if (format == MESA_FORMAT_A8) {
1767269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			/* Emulated using I8. */
1777269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			if (is_color_operand(operand))
1787269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez				return RC_IN_SOURCE(ZERO) |
1797269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez					get_input_mapping(rc, operand, flags);
1807269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
1817269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		} else if (format == MESA_FORMAT_L8) {
1827269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			/* Sometimes emulated using I8. */
1837269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			if (!is_color_operand(operand))
1847269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez				return RC_IN_SOURCE(ZERO) |
1857269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez					get_input_mapping(rc, operand,
1867269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez							  flags ^ INVERT);
18751e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez
18851e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez		} else if (format == MESA_FORMAT_XRGB8888) {
18951e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez			/* Sometimes emulated using ARGB8888. */
19051e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez			if (!is_color_operand(operand))
19151e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez				return RC_IN_SOURCE(ZERO) |
19251e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez					get_input_mapping(rc, operand,
19351e8a66fa197de7e17fb94d901a4cf26f0812670Francisco Jerez							  flags ^ INVERT);
1947269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		}
195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
196bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1977269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	return get_input_source(rc, source) |
1987269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		get_input_mapping(rc, operand, flags);
199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
200bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
201bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Bind the RC input variable <var> to the EXT_texture_env_combine
202bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * argument <arg>, possibly inverted or biased. */
203bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define INPUT_ARG(rc, var, arg, flags)					\
2047269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	(rc)->in |= get_input_arg(rc, arg, flags) << RC_IN_SHIFT_##var
205bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
206bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Bind the RC input variable <var> to the RC source <src>. */
207bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define INPUT_SRC(rc, var, src, chan)					\
208bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	(rc)->in |= (RC_IN_SOURCE(src) |				\
209bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     RC_IN_USAGE(chan)) << RC_IN_SHIFT_##var
210bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
211bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Bind the RC input variable <var> to a constant +/-1 */
212bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define INPUT_ONE(rc, var, flags)					\
213bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	(rc)->in |= (RC_IN_SOURCE(ZERO) |				\
214bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		     (flags & INVERT ? RC_IN_MAPPING(EXPAND_NORMAL) :	\
215bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      RC_IN_MAPPING(UNSIGNED_INVERT))) << RC_IN_SHIFT_##var
216bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
217bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
218bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezsetup_combiner(struct combiner_state *rc)
219bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
220bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (rc->mode) {
221bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_REPLACE:
222bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, A, 0, 0);
223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ONE(rc, B, 0);
224bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
225bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rc->out = RC_OUT_AB;
226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
228bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_MODULATE:
229bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, A, 0, 0);
230bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, B, 1, 0);
231bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
232bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rc->out = RC_OUT_AB;
233bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
234bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
235bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_ADD:
236bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_ADD_SIGNED:
2373bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez		if (rc->premodulate) {
2383bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez			INPUT_ARG(rc, A, 0, 0);
2393bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez			INPUT_ARG(rc, B, 1, 0);
2403bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez			INPUT_ARG(rc, C, 2, 0);
2413bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez			INPUT_ARG(rc, D, 3, 0);
2423bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez		} else {
2433bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez			INPUT_ARG(rc, A, 0, 0);
2443bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez			INPUT_ONE(rc, B, 0);
2453bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez			INPUT_ARG(rc, C, 1, 0);
2463bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez			INPUT_ONE(rc, D, 0);
2473bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez		}
248bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
2493bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez		rc->out = RC_OUT_SUM |
2503bbad7f1084c3d6259dfa23fd60f654c949f7408Francisco Jerez			(rc->mode == GL_ADD_SIGNED ? RC_OUT_BIAS : 0);
251bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
252bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
253bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_INTERPOLATE:
254bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, A, 0, 0);
255bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, B, 2, 0);
256bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, C, 1, 0);
257bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, D, 2, INVERT);
258bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
259bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rc->out = RC_OUT_SUM;
260bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
261bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
262bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_SUBTRACT:
263bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, A, 0, 0);
264bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ONE(rc, B, 0);
265bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, C, 1, 0);
266bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ONE(rc, D, INVERT);
267bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
268bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rc->out = RC_OUT_SUM;
269bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
270bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
271bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_DOT3_RGB:
272bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_DOT3_RGBA:
273bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, A, 0, HALF_BIAS);
274bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ARG(rc, B, 1, HALF_BIAS);
275bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
276bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rc->out = RC_OUT_DOT_AB | RC_OUT_SCALE_4;
277bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
278bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(!rc->logscale);
279bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
280bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
281bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
282bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
283bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
284bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
285bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (rc->logscale) {
286bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case 0:
287bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rc->out |= RC_OUT_SCALE_1;
288bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
289bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case 1:
290bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rc->out |= RC_OUT_SCALE_2;
291bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
292bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case 2:
293bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rc->out |= RC_OUT_SCALE_4;
294bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
295bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
296bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
297bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
298bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
299bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
300bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
301f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_get_general_combiner(struct gl_context *ctx, int i,
3027269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			  uint32_t *a_in, uint32_t *a_out,
3037269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			  uint32_t *c_in, uint32_t *c_out, uint32_t *k)
304bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
305bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct combiner_state rc_a, rc_c;
306bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
307bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Texture.Unit[i]._ReallyEnabled) {
308bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INIT_COMBINER(RGB, ctx, &rc_c, i);
309bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
310bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (rc_c.mode == GL_DOT3_RGBA)
311bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			rc_a = rc_c;
312bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		else
313bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			INIT_COMBINER(A, ctx, &rc_a, i);
314bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
315bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		setup_combiner(&rc_c);
316bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		setup_combiner(&rc_a);
317bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
318bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
3197269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		rc_a.in = rc_a.out = rc_c.in = rc_c.out = 0;
320bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
321bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3227269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	*k = pack_rgba_f(MESA_FORMAT_ARGB8888,
3237269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			 ctx->Texture.Unit[i].EnvColor);
3247269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	*a_in = rc_a.in;
3257269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	*a_out = rc_a.out;
3267269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	*c_in = rc_c.in;
3277269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	*c_out = rc_c.out;
328bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
329bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
330bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
331f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_get_final_combiner(struct gl_context *ctx, uint64_t *in, int *n)
332bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
333bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct combiner_state rc = {};
334bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
335bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/*
336bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 * The final fragment value equation is something like:
337bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 *	x_i = A_i * B_i + (1 - A_i) * C_i + D_i
338bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 *	x_alpha = G_alpha
339bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 * where D_i = E_i * F_i, i one of {red, green, blue}.
340bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 */
341bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Fog.ColorSumEnabled || ctx->Light.Enabled) {
342bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc, D, E_TIMES_F, RGB);
343bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc, F, SECONDARY_COLOR, RGB);
344bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
345bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
346bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Fog.Enabled) {
347bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc, A, FOG, ALPHA);
348bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc, C, FOG, RGB);
349bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc, E, FOG, ALPHA);
350bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
351bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ONE(&rc, A, 0);
352bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ONE(&rc, C, 0);
353bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_ONE(&rc, E, 0);
354bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
355bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
356bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Texture._EnabledUnits) {
357bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc, B, SPARE0, RGB);
358bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc, G, SPARE0, ALPHA);
359bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
360bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc, B, PRIMARY_COLOR, RGB);
361bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		INPUT_SRC(&rc, G, PRIMARY_COLOR, ALPHA);
362bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
363bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3647269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	*in = rc.in;
3657269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	*n = log2i(ctx->Texture._EnabledUnits) + 1;
3667269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez}
3677269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
3687269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerezvoid
369f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_tex_env(struct gl_context *ctx, int emit)
3707269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez{
3717269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	const int i = emit - NOUVEAU_STATE_TEX_ENV0;
3722e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
3737269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	uint32_t a_in, a_out, c_in, c_out, k;
3747269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
3757269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	nv10_get_general_combiner(ctx, i, &a_in, &a_out, &c_in, &c_out, &k);
3767269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
3777269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	/* Enable the combiners we're going to need. */
3787269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	if (i == 1) {
3797269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		if (c_out || a_out)
3807269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			c_out |= 0x5 << 27;
3817269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez		else
3827269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez			c_out |= 0x3 << 27;
3837269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	}
3847269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
3852e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(RC_IN_ALPHA(i)), 1);
3862e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, a_in);
3872e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(RC_IN_RGB(i)), 1);
3882e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, c_in);
3892e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(RC_COLOR(i)), 1);
3902e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, k);
3912e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(RC_OUT_ALPHA(i)), 1);
3922e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, a_out);
3932e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(RC_OUT_RGB(i)), 1);
3942e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, c_out);
3957269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
3967269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	context_dirty(ctx, FRAG);
3977269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez}
3987269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
3997269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerezvoid
400f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnv10_emit_frag(struct gl_context *ctx, int emit)
4017269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez{
4022e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
4037269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	uint64_t in;
4047269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	int n;
4057269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
4067269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez	nv10_get_final_combiner(ctx, &in, &n);
4077269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez
4082e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	BEGIN_NV04(push, NV10_3D(RC_FINAL0), 2);
4092e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, in);
4102e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_DATA (push, in >> 32);
411bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
412