a8d1b253c7b93bb4a996734a6d66a2217f2d9b5d
[mesa.git] / src / mesa / drivers / dri / gamma / gamma_texstate.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_texstate.c,v 1.5 2002/11/05 17:46:07 tsi Exp $ */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5
6 #include "glheader.h"
7 #include "macros.h"
8 #include "mtypes.h"
9 #include "simple_list.h"
10 #include "enums.h"
11
12 #include "mm.h"
13 #include "gamma_context.h"
14
15 static void gammaSetTexImages( gammaContextPtr gmesa,
16 struct gl_texture_object *tObj )
17 {
18 GLuint height, width, pitch, i, log_pitch;
19 gammaTextureObjectPtr t = (gammaTextureObjectPtr) tObj->DriverData;
20 const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
21 GLint firstLevel, lastLevel, numLevels;
22 GLint log2Width, log2Height;
23
24 /* fprintf(stderr, "%s\n", __FUNCTION__); */
25
26 t->texelBytes = 2;
27
28 /* Compute which mipmap levels we really want to send to the hardware.
29 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
30 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
31 * Yes, this looks overly complicated, but it's all needed.
32 */
33 if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) {
34 firstLevel = lastLevel = tObj->BaseLevel;
35 }
36 else {
37 firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
38 firstLevel = MAX2(firstLevel, tObj->BaseLevel);
39 lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
40 lastLevel = MAX2(lastLevel, tObj->BaseLevel);
41 lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
42 lastLevel = MIN2(lastLevel, tObj->MaxLevel);
43 lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
44 }
45
46 /* save these values */
47 t->firstLevel = firstLevel;
48 t->lastLevel = lastLevel;
49
50 numLevels = lastLevel - firstLevel + 1;
51
52 log2Width = tObj->Image[0][firstLevel]->WidthLog2;
53 log2Height = tObj->Image[0][firstLevel]->HeightLog2;
54
55
56 /* Figure out the amount of memory required to hold all the mipmap
57 * levels. Choose the smallest pitch to accomodate the largest
58 * mipmap:
59 */
60 width = tObj->Image[0][firstLevel]->Width * t->texelBytes;
61 for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
62 log_pitch++;
63
64 /* All images must be loaded at this pitch. Count the number of
65 * lines required:
66 */
67 for ( height = i = 0 ; i < numLevels ; i++ ) {
68 t->image[i].image = tObj->Image[0][firstLevel + i];
69 t->image[i].offset = height * pitch;
70 t->image[i].internalFormat = baseImage->Format;
71 height += t->image[i].image->Height;
72 t->TextureBaseAddr[i] = /* ??? */
73 (unsigned long)(t->image[i].offset + t->BufAddr) << 5;
74
75 }
76
77 t->Pitch = pitch;
78 t->totalSize = height*pitch;
79 t->max_level = i-1;
80 gmesa->dirty |= GAMMA_UPLOAD_TEX0 /* | GAMMA_UPLOAD_TEX1*/;
81
82 gammaUploadTexImages( gmesa, t );
83 }
84
85 static void gammaUpdateTexEnv( GLcontext *ctx, GLuint unit )
86 {
87 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
88 const struct gl_texture_object *tObj = texUnit->_Current;
89 const GLuint format = tObj->Image[0][tObj->BaseLevel]->Format;
90 gammaTextureObjectPtr t = (gammaTextureObjectPtr)tObj->DriverData;
91 GLuint tc;
92
93 /* fprintf(stderr, "%s\n", __FUNCTION__); */
94
95 tc = t->TextureColorMode & ~(TCM_BaseFormatMask | TCM_ApplicationMask);
96
97 switch (format) {
98 case GL_RGB:
99 tc |= TCM_BaseFormat_RGB;
100 break;
101 case GL_LUMINANCE:
102 tc |= TCM_BaseFormat_Lum;
103 break;
104 case GL_ALPHA:
105 tc |= TCM_BaseFormat_Alpha;
106 break;
107 case GL_LUMINANCE_ALPHA:
108 tc |= TCM_BaseFormat_LumAlpha;
109 break;
110 case GL_INTENSITY:
111 tc |= TCM_BaseFormat_Intensity;
112 break;
113 case GL_RGBA:
114 tc |= TCM_BaseFormat_RGBA;
115 break;
116 case GL_COLOR_INDEX:
117 break;
118 }
119
120 switch (texUnit->EnvMode) {
121 case GL_REPLACE:
122 tc |= TCM_Replace;
123 break;
124 case GL_MODULATE:
125 tc |= TCM_Modulate;
126 break;
127 case GL_ADD:
128 /* do nothing ???*/
129 break;
130 case GL_DECAL:
131 tc |= TCM_Decal;
132 break;
133 case GL_BLEND:
134 tc |= TCM_Blend;
135 break;
136 default:
137 fprintf(stderr, "unknown tex env mode");
138 return;
139 }
140
141 t->TextureColorMode = tc;
142 }
143
144
145
146
147 static void gammaUpdateTexUnit( GLcontext *ctx, GLuint unit )
148 {
149 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
150 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
151
152 /* fprintf(stderr, "%s\n", __FUNCTION__); */
153
154 if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT)
155 {
156 struct gl_texture_object *tObj = texUnit->_Current;
157 gammaTextureObjectPtr t = (gammaTextureObjectPtr)tObj->DriverData;
158
159 /* Upload teximages (not pipelined)
160 */
161 if (t->dirty_images) {
162 gammaSetTexImages( gmesa, tObj );
163 if (!t->MemBlock) {
164 FALLBACK( gmesa, GAMMA_FALLBACK_TEXTURE, GL_TRUE );
165 return;
166 }
167 }
168
169 #if 0
170 if (tObj->Image[0][tObj->BaseLevel]->Border > 0) {
171 FALLBACK( gmesa, GAMMA_FALLBACK_TEXTURE, GL_TRUE );
172 return;
173 }
174 #endif
175
176 /* Update state if this is a different texture object to last
177 * time.
178 */
179 if (gmesa->CurrentTexObj[unit] != t) {
180 gmesa->dirty |= GAMMA_UPLOAD_TEX0 /* << unit */;
181 gmesa->CurrentTexObj[unit] = t;
182 gammaUpdateTexLRU( gmesa, t ); /* done too often */
183 }
184
185 /* Update texture environment if texture object image format or
186 * texture environment state has changed.
187 */
188 if (tObj->Image[0][tObj->BaseLevel]->Format != gmesa->TexEnvImageFmt[unit]) {
189 gmesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->Format;
190 gammaUpdateTexEnv( ctx, unit );
191 }
192 }
193 else if (texUnit->_ReallyEnabled) {
194 FALLBACK( gmesa, GAMMA_FALLBACK_TEXTURE, GL_TRUE );
195 }
196 else /*if (gmesa->CurrentTexObj[unit])*/ {
197 gmesa->CurrentTexObj[unit] = 0;
198 gmesa->TexEnvImageFmt[unit] = 0;
199 gmesa->dirty &= ~(GAMMA_UPLOAD_TEX0<<unit);
200 }
201 }
202
203
204 void gammaUpdateTextureState( GLcontext *ctx )
205 {
206 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
207 /* fprintf(stderr, "%s\n", __FUNCTION__); */
208 FALLBACK( gmesa, GAMMA_FALLBACK_TEXTURE, GL_FALSE );
209 gammaUpdateTexUnit( ctx, 0 );
210 #if 0
211 gammaUpdateTexUnit( ctx, 1 );
212 #endif
213 }
214
215
216