Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Copyright (C) 2009 Francisco Jerez.
3
 * All Rights Reserved.
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining
6
 * a copy of this software and associated documentation files (the
7
 * "Software"), to deal in the Software without restriction, including
8
 * without limitation the rights to use, copy, modify, merge, publish,
9
 * distribute, sublicense, and/or sell copies of the Software, and to
10
 * permit persons to whom the Software is furnished to do so, subject to
11
 * the following conditions:
12
 *
13
 * The above copyright notice and this permission notice (including the
14
 * next paragraph) shall be included in all copies or substantial
15
 * portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 *
25
 */
26
 
27
#include "nouveau_driver.h"
28
#include "nouveau_context.h"
29
#include "nouveau_gldefs.h"
30
#include "nouveau_texture.h"
31
#include "nv20_3d.xml.h"
32
#include "nouveau_util.h"
33
#include "nv20_driver.h"
34
#include "main/samplerobj.h"
35
 
36
void
37
nv20_emit_tex_gen(struct gl_context *ctx, int emit)
38
{
39
	const int i = emit - NOUVEAU_STATE_TEX_GEN0;
40
	struct nouveau_context *nctx = to_nouveau_context(ctx);
41
	struct nouveau_pushbuf *push = context_push(ctx);
42
	struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
43
	int j;
44
 
45
	for (j = 0; j < 4; j++) {
46
		if (nctx->fallback == HWTNL && (unit->TexGenEnabled & 1 << j)) {
47
			struct gl_texgen *coord = get_texgen_coord(unit, j);
48
			float *k = get_texgen_coeff(coord);
49
 
50
			if (k) {
51
				BEGIN_NV04(push, NV20_3D(TEX_GEN_COEFF(i, j)), 4);
52
				PUSH_DATAp(push, k, 4);
53
			}
54
 
55
			BEGIN_NV04(push, NV20_3D(TEX_GEN_MODE(i, j)), 1);
56
			PUSH_DATA (push, nvgl_texgen_mode(coord->Mode));
57
 
58
		} else {
59
			BEGIN_NV04(push, NV20_3D(TEX_GEN_MODE(i, j)), 1);
60
			PUSH_DATA (push, 0);
61
		}
62
	}
63
}
64
 
65
void
66
nv20_emit_tex_mat(struct gl_context *ctx, int emit)
67
{
68
	const int i = emit - NOUVEAU_STATE_TEX_MAT0;
69
	struct nouveau_context *nctx = to_nouveau_context(ctx);
70
	struct nouveau_pushbuf *push = context_push(ctx);
71
 
72
	if (nctx->fallback == HWTNL &&
73
	    (ctx->Texture._TexMatEnabled & 1 << i)) {
74
		BEGIN_NV04(push, NV20_3D(TEX_MATRIX_ENABLE(i)), 1);
75
		PUSH_DATA (push, 1);
76
 
77
		BEGIN_NV04(push, NV20_3D(TEX_MATRIX(i,0)), 16);
78
		PUSH_DATAm(push, ctx->TextureMatrixStack[i].Top->m);
79
 
80
	} else {
81
		BEGIN_NV04(push, NV20_3D(TEX_MATRIX_ENABLE(i)), 1);
82
		PUSH_DATA (push, 0);
83
	}
84
}
85
 
86
static uint32_t
87
get_tex_format_pot(struct gl_texture_image *ti)
88
{
89
	switch (ti->TexFormat) {
90
	case MESA_FORMAT_ARGB8888:
91
		return NV20_3D_TEX_FORMAT_FORMAT_A8R8G8B8;
92
 
93
	case MESA_FORMAT_ARGB1555:
94
		return NV20_3D_TEX_FORMAT_FORMAT_A1R5G5B5;
95
 
96
	case MESA_FORMAT_ARGB4444:
97
		return NV20_3D_TEX_FORMAT_FORMAT_A4R4G4B4;
98
 
99
	case MESA_FORMAT_XRGB8888:
100
		return NV20_3D_TEX_FORMAT_FORMAT_X8R8G8B8;
101
 
102
	case MESA_FORMAT_RGB565:
103
		return NV20_3D_TEX_FORMAT_FORMAT_R5G6B5;
104
 
105
	case MESA_FORMAT_A8:
106
	case MESA_FORMAT_I8:
107
		return NV20_3D_TEX_FORMAT_FORMAT_I8;
108
 
109
	case MESA_FORMAT_L8:
110
		return NV20_3D_TEX_FORMAT_FORMAT_L8;
111
 
112
	case MESA_FORMAT_RGB_DXT1:
113
	case MESA_FORMAT_RGBA_DXT1:
114
		return NV20_3D_TEX_FORMAT_FORMAT_DXT1;
115
 
116
	case MESA_FORMAT_RGBA_DXT3:
117
		return NV20_3D_TEX_FORMAT_FORMAT_DXT3;
118
 
119
	case MESA_FORMAT_RGBA_DXT5:
120
		return NV20_3D_TEX_FORMAT_FORMAT_DXT5;
121
 
122
	default:
123
		assert(0);
124
	}
125
}
126
 
127
static uint32_t
128
get_tex_format_rect(struct gl_texture_image *ti)
129
{
130
	switch (ti->TexFormat) {
131
	case MESA_FORMAT_ARGB8888:
132
		return NV20_3D_TEX_FORMAT_FORMAT_A8R8G8B8_RECT;
133
 
134
	case MESA_FORMAT_ARGB1555:
135
		return NV20_3D_TEX_FORMAT_FORMAT_A1R5G5B5_RECT;
136
 
137
	case MESA_FORMAT_ARGB4444:
138
		return NV20_3D_TEX_FORMAT_FORMAT_A4R4G4B4_RECT;
139
 
140
	case MESA_FORMAT_XRGB8888:
141
		return NV20_3D_TEX_FORMAT_FORMAT_R8G8B8_RECT;
142
 
143
	case MESA_FORMAT_RGB565:
144
		return NV20_3D_TEX_FORMAT_FORMAT_R5G6B5_RECT;
145
 
146
	case MESA_FORMAT_L8:
147
		return NV20_3D_TEX_FORMAT_FORMAT_L8_RECT;
148
 
149
	case MESA_FORMAT_A8:
150
	case MESA_FORMAT_I8:
151
		return NV20_3D_TEX_FORMAT_FORMAT_I8_RECT;
152
 
153
	default:
154
		assert(0);
155
	}
156
}
157
 
158
void
159
nv20_emit_tex_obj(struct gl_context *ctx, int emit)
160
{
161
	const int i = emit - NOUVEAU_STATE_TEX_OBJ0;
162
	struct nouveau_pushbuf *push = context_push(ctx);
163
	const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM;
164
	struct gl_texture_object *t;
165
	struct nouveau_surface *s;
166
	struct gl_texture_image *ti;
167
	const struct gl_sampler_object *sa;
168
	uint32_t tx_format, tx_filter, tx_wrap, tx_enable;
169
 
170
	PUSH_RESET(push, BUFCTX_TEX(i));
171
 
172
	if (!ctx->Texture.Unit[i]._ReallyEnabled) {
173
		BEGIN_NV04(push, NV20_3D(TEX_ENABLE(i)), 1);
174
		PUSH_DATA (push, 0);
175
 
176
		context_dirty(ctx, TEX_SHADER);
177
		return;
178
	}
179
 
180
	t = ctx->Texture.Unit[i]._Current;
181
	s = &to_nouveau_texture(t)->surfaces[t->BaseLevel];
182
	ti = t->Image[0][t->BaseLevel];
183
	sa = _mesa_get_samplerobj(ctx, i);
184
 
185
	if (!nouveau_texture_validate(ctx, t))
186
		return;
187
 
188
	/* Recompute the texturing registers. */
189
	tx_format = ti->DepthLog2 << 28
190
		| ti->HeightLog2 << 24
191
		| ti->WidthLog2 << 20
192
		| NV20_3D_TEX_FORMAT_DIMS_2D
193
		| NV20_3D_TEX_FORMAT_NO_BORDER
194
		| 1 << 16;
195
 
196
	tx_wrap = nvgl_wrap_mode(sa->WrapR) << 16
197
		| nvgl_wrap_mode(sa->WrapT) << 8
198
		| nvgl_wrap_mode(sa->WrapS) << 0;
199
 
200
	tx_filter = nvgl_filter_mode(sa->MagFilter) << 24
201
		| nvgl_filter_mode(sa->MinFilter) << 16
202
		| 2 << 12;
203
 
204
	tx_enable = NV20_3D_TEX_ENABLE_ENABLE
205
		| log2i(sa->MaxAnisotropy) << 4;
206
 
207
	if (t->Target == GL_TEXTURE_RECTANGLE) {
208
		BEGIN_NV04(push, NV20_3D(TEX_NPOT_PITCH(i)), 1);
209
		PUSH_DATA (push, s->pitch << 16);
210
		BEGIN_NV04(push, NV20_3D(TEX_NPOT_SIZE(i)), 1);
211
		PUSH_DATA (push, s->width << 16 | s->height);
212
 
213
		tx_format |= get_tex_format_rect(ti);
214
	} else {
215
		tx_format |= get_tex_format_pot(ti);
216
	}
217
 
218
	if (sa->MinFilter != GL_NEAREST &&
219
	    sa->MinFilter != GL_LINEAR) {
220
		int lod_min = sa->MinLod;
221
		int lod_max = MIN2(sa->MaxLod, t->_MaxLambda);
222
		int lod_bias = sa->LodBias
223
			+ ctx->Texture.Unit[i].LodBias;
224
 
225
		lod_max = CLAMP(lod_max, 0, 15);
226
		lod_min = CLAMP(lod_min, 0, 15);
227
		lod_bias = CLAMP(lod_bias, 0, 15);
228
 
229
		tx_format |= NV20_3D_TEX_FORMAT_MIPMAP;
230
		tx_filter |= lod_bias << 8;
231
		tx_enable |= lod_min << 26
232
			| lod_max << 14;
233
	}
234
 
235
	/* Write it to the hardware. */
236
	BEGIN_NV04(push, NV20_3D(TEX_FORMAT(i)), 1);
237
	PUSH_MTHD (push, NV20_3D(TEX_FORMAT(i)), BUFCTX_TEX(i),
238
			 s->bo, tx_format, bo_flags | NOUVEAU_BO_OR,
239
			 NV20_3D_TEX_FORMAT_DMA0,
240
			 NV20_3D_TEX_FORMAT_DMA1);
241
 
242
	BEGIN_NV04(push, NV20_3D(TEX_OFFSET(i)), 1);
243
	PUSH_MTHDl(push, NV20_3D(TEX_OFFSET(i)), BUFCTX_TEX(i),
244
			 s->bo, s->offset, bo_flags);
245
 
246
	BEGIN_NV04(push, NV20_3D(TEX_WRAP(i)), 1);
247
	PUSH_DATA (push, tx_wrap);
248
 
249
	BEGIN_NV04(push, NV20_3D(TEX_FILTER(i)), 1);
250
	PUSH_DATA (push, tx_filter);
251
 
252
	BEGIN_NV04(push, NV20_3D(TEX_ENABLE(i)), 1);
253
	PUSH_DATA (push, tx_enable);
254
 
255
	context_dirty(ctx, TEX_SHADER);
256
}
257
 
258
void
259
nv20_emit_tex_shader(struct gl_context *ctx, int emit)
260
{
261
	struct nouveau_pushbuf *push = context_push(ctx);
262
	uint32_t tx_shader_op = 0;
263
	int i;
264
 
265
	for (i = 0; i < NV20_TEXTURE_UNITS; i++) {
266
		if (!ctx->Texture.Unit[i]._ReallyEnabled)
267
			continue;
268
 
269
		tx_shader_op |= NV20_3D_TEX_SHADER_OP_TX0_TEXTURE_2D << 5 * i;
270
	}
271
 
272
	BEGIN_NV04(push, NV20_3D(TEX_SHADER_OP), 1);
273
	PUSH_DATA (push, tx_shader_op);
274
}