Remove test for defined(DRM_USE_MALLOC) around definition of
[mesa.git] / src / mesa / drivers / dri / unichrome / via_texmem.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #include <stdlib.h>
27 #include <stdio.h>
28
29 #include "glheader.h"
30 #include "macros.h"
31 #include "mtypes.h"
32 #include "simple_list.h"
33 #include "enums.h"
34 #include "texformat.h"
35
36 #include "mm.h"
37 #include "via_context.h"
38 #include "via_tex.h"
39 #include "via_state.h"
40 #include "via_ioctl.h"
41 #include "via_fb.h"
42 /*=* John Sheng [2003.5.31] agp tex *=*/
43
44 void viaDestroyTexObj(viaContextPtr vmesa, viaTextureObjectPtr t)
45 {
46 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
47 if (!t)
48 return;
49
50 /* This is sad - need to sync *in case* we upload a texture
51 * to this newly free memory...
52 */
53 if (t->bufAddr) {
54 via_free_texture(vmesa, t);
55
56 if (vmesa && t->age > vmesa->dirtyAge)
57 vmesa->dirtyAge = t->age;
58 }
59
60 if (t->globj)
61 t->globj->DriverData = 0;
62
63 if (vmesa) {
64 if (vmesa->CurrentTexObj[0] == t) {
65 vmesa->CurrentTexObj[0] = 0;
66 }
67
68 if (vmesa->CurrentTexObj[1] == t) {
69 vmesa->CurrentTexObj[1] = 0;
70 }
71 }
72
73 remove_from_list(t);
74 free(t);
75 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
76 }
77
78 void viaSwapOutTexObj(viaContextPtr vmesa, viaTextureObjectPtr t)
79 {
80 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
81 if (t->bufAddr) {
82 via_free_texture(vmesa, t);
83
84 if (t->age > vmesa->dirtyAge)
85 vmesa->dirtyAge = t->age;
86 }
87
88 t->dirtyImages = ~0;
89 move_to_tail(&(vmesa->SwappedOut), t);
90 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
91 }
92
93 /* Upload an image from mesa's internal copy.
94 */
95 static void viaUploadTexLevel(viaTextureObjectPtr t, int level)
96 {
97 const struct gl_texture_image *image = t->image[level].image;
98 int i, j;
99 if (VIA_DEBUG) {
100 fprintf(stderr, "%s - in\n", __FUNCTION__);
101 fprintf(stderr, "width = %d, height = %d \n", image->Width, image->Height);
102 }
103 switch (t->image[level].internalFormat) {
104 case GL_RGB:
105 {
106 if (image->TexFormat->MesaFormat == MESA_FORMAT_ARGB8888) {
107 GLuint *dst = (GLuint *)(t->bufAddr + t->image[level].offset);
108 GLuint *src = (GLuint *)image->Data;
109 if (VIA_DEBUG) fprintf(stderr, "GL_RGB MESA_FORMAT_ARGB8888\n");
110 if (image->Width < 8) {
111 for (i = 0; i < image->Height ; i++) {
112 for (j = 0; j < image->Width ; j++) {
113 dst[j] = *src;
114 src++;
115 }
116 dst += 8;
117 }
118 }
119 else {
120 for (j = 0; j < image->Height * image->Width; j++) {
121 *dst = *src;
122 dst++;
123 src++;
124 }
125 }
126 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
127 }
128 else {
129 GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
130 GLushort *src = (GLushort *)image->Data;
131 if (VIA_DEBUG) fprintf(stderr, "GL_RGB !MESA_FORMAT_ARGB8888\n");
132 if (image->Width < 16) {
133 for (i = 0; i < image->Height ; i++) {
134 for (j = 0; j < image->Width ; j++) {
135 dst[j] = *src;
136 src++;
137 }
138 dst += 16;
139 }
140 }
141 else {
142 for (j = 0; j < image->Height * image->Width; j++) {
143 *dst = *src;
144 dst++;
145 src++;
146 }
147 }
148 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
149 }
150 }
151 break;
152
153 case GL_RGBA:
154 {
155 if (image->TexFormat->MesaFormat == MESA_FORMAT_ARGB4444) {
156
157 GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
158 GLushort *src = (GLushort *)image->Data;
159 if (image->Width < 16) {
160 for (i = 0; i < image->Height ; i++) {
161 for (j = 0; j < image->Width ; j++) {
162 dst[j] = *src;
163 src++;
164 }
165 dst += 16;
166 }
167 }
168 else {
169 for (j = 0; j < image->Height * image->Width; j++) {
170 *dst = *src;
171 src++;
172 dst++;
173 }
174 }
175 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
176 if (VIA_DEBUG) fprintf(stderr, "GL_RGBA MESA_FORMAT_ARGB4444\n");
177 }
178 else if(image->TexFormat->MesaFormat == MESA_FORMAT_ARGB8888) {
179 GLuint *dst = (GLuint *)(t->bufAddr + t->image[level].offset);
180 GLuint *src = (GLuint *)image->Data;
181 if (VIA_DEBUG) fprintf(stderr, "GL_RGBA !MESA_FORMAT_ARGB4444\n");
182 if (image->Width < 8) {
183 for (i = 0; i < image->Height ; i++) {
184 for (j = 0; j < image->Width ; j++) {
185 dst[j] = *src;
186 src++;
187 }
188 dst += 8;
189 }
190 }
191 else {
192 for (j = 0; j < image->Height * image->Width; j++) {
193 *dst = *src;
194 dst++;
195 src++;
196 }
197 }
198 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
199 }
200 else if(image->TexFormat->MesaFormat == MESA_FORMAT_ARGB1555) {
201 GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
202 GLushort *src = (GLushort *)image->Data;
203 if (image->Width < 16) {
204 for (i = 0; i < image->Height ; i++) {
205 for (j = 0; j < image->Width ; j++) {
206 dst[j] = *src;
207 src++;
208 }
209 dst += 16;
210 }
211 }
212 else {
213 for (j = 0; j < image->Height * image->Width; j++) {
214 *dst = *src;
215 src++;
216 dst++;
217 }
218 }
219 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
220 if (VIA_DEBUG) fprintf(stderr, "GL_RGBA MESA_FORMAT_ARGB1555\n");
221 }
222 }
223 break;
224
225 case GL_LUMINANCE:
226 {
227 GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
228 GLubyte *src = (GLubyte *)image->Data;
229
230 for (j = 0; j < image->Height * image->Width; j++) {
231 *dst = *src;
232 dst++;
233 src++;
234 }
235 }
236 break;
237
238 case GL_INTENSITY:
239 {
240 GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
241 GLubyte *src = (GLubyte *)image->Data;
242
243 for (j = 0; j < image->Height * image->Width; j++) {
244 *dst = *src;
245 dst++;
246 src++;
247 }
248 }
249 break;
250
251 case GL_LUMINANCE_ALPHA:
252 {
253 GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
254 GLushort *src = (GLushort *)image->Data;
255
256 for (j = 0; j < image->Height * image->Width; j++) {
257 *dst = *src;
258 dst++;
259 src++;
260 }
261 }
262 break;
263
264 case GL_ALPHA:
265 {
266 GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
267 GLubyte *src = (GLubyte *)image->Data;
268
269 for (j = 0; j < image->Height * image->Width; j++) {
270 *dst = *src;
271 dst++;
272 src++;
273 }
274 }
275 break;
276
277 /* TODO: Translate color indices *now*:
278 */
279 case GL_COLOR_INDEX:
280 {
281 GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
282 GLubyte *src = (GLubyte *)image->Data;
283
284 for (j = 0; j < image->Height * image->Width; j++) {
285 *dst = *src;
286 dst++;
287 src++;
288 }
289 }
290 break;
291
292 default:;
293 if (VIA_DEBUG) fprintf(stderr, "Not supported texture format %s\n",
294 _mesa_lookup_enum_by_nr(image->Format));
295 }
296 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
297 }
298
299 void viaPrintLocalLRU(viaContextPtr vmesa)
300 {
301 viaTextureObjectPtr t;
302
303 foreach (t, &vmesa->TexObjList) {
304 if (!t->globj) {
305 if (VIA_DEBUG) {
306 fprintf(stderr, "offset = %x, index = %x, size = %x\n",
307 t->texMem.offset,
308 t->texMem.index,
309 t->texMem.size);
310 }
311 else {
312 if (VIA_DEBUG) {
313 fprintf(stderr, "offset = %x, siez = %x\n",
314 t->texMem.offset,
315 t->texMem.size);
316 }
317 }
318 }
319 }
320 }
321
322 void viaPrintGlobalLRU(viaContextPtr vmesa)
323 {
324 int i, j;
325 drm_via_tex_region_t *list = vmesa->sarea->texList;
326
327 for (i = 0, j = VIA_NR_TEX_REGIONS; i < VIA_NR_TEX_REGIONS; i++) {
328 if (VIA_DEBUG) fprintf(stderr, "list[%d] age %d next %d prev %d\n",
329 j, list[j].age, list[j].next, list[j].prev);
330 j = list[j].next;
331 if (j == VIA_NR_TEX_REGIONS) break;
332 }
333 if (j != VIA_NR_TEX_REGIONS)
334 if (VIA_DEBUG) fprintf(stderr, "Loop detected in global LRU\n");
335 }
336
337 void viaResetGlobalLRU(viaContextPtr vmesa)
338 {
339 drm_via_tex_region_t *list = vmesa->sarea->texList;
340 int sz = 1 << vmesa->viaScreen->logTextureGranularity;
341 int i;
342
343 /* (Re)initialize the global circular LRU list. The last element
344 * in the array (VIA_NR_TEX_REGIONS) is the sentinal. Keeping it
345 * at the end of the array allows it to be addressed rationally
346 * when looking up objects at a particular location in texture
347 * memory.
348 */
349 for (i = 0; (i + 1) * sz <= vmesa->viaScreen->textureSize; i++) {
350 list[i].prev = i - 1;
351 list[i].next = i + 1;
352 list[i].age = 0;
353 }
354
355 i--;
356 list[0].prev = VIA_NR_TEX_REGIONS;
357 list[i].prev = i - 1;
358 list[i].next = VIA_NR_TEX_REGIONS;
359 list[VIA_NR_TEX_REGIONS].prev = i;
360 list[VIA_NR_TEX_REGIONS].next = 0;
361 vmesa->sarea->texAge = 0;
362 }
363
364 void viaUpdateTexLRU(viaContextPtr vmesa, viaTextureObjectPtr t)
365 {
366 vmesa->texAge = ++vmesa->sarea->texAge;
367 move_to_head(&(vmesa->TexObjList), t);
368 }
369
370 /* Called for every shared texture region which has increased in age
371 * since we last held the lock.
372 *
373 * Figures out which of our textures have been ejected by other clients,
374 * and pushes a placeholder texture onto the LRU list to represent
375 * the other client's textures.
376 */
377 void viaTexturesGone(viaContextPtr vmesa,
378 GLuint offset,
379 GLuint size,
380 GLuint inUse)
381 {
382 viaTextureObjectPtr t, tmp;
383 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
384 foreach_s (t, tmp, &vmesa->TexObjList) {
385 viaSwapOutTexObj(vmesa, t);
386 }
387 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
388 }
389
390 /* This is called with the lock held. May have to eject our own and/or
391 * other client's texture objects to make room for the upload.
392 */
393 void viaUploadTexImages(viaContextPtr vmesa, viaTextureObjectPtr t)
394 {
395 int i, j;
396 int numLevels;
397 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
398 LOCK_HARDWARE(vmesa);
399
400 j = 0;
401 if (!t->bufAddr) {
402 while (1) {
403
404 /*=* John Sheng [2003.5.31] agp tex *=*/
405 if (via_alloc_texture_agp(vmesa, t))
406 break;
407 if (via_alloc_texture(vmesa, t))
408 break;
409
410 vmesa->agpFullCount++;
411 if (vmesa->TexObjList.prev == vmesa->CurrentTexObj[0] ||
412 vmesa->TexObjList.prev == vmesa->CurrentTexObj[1]) {
413 if (VIA_DEBUG) fprintf(stderr, "Hit bound texture in upload\n");
414 viaPrintLocalLRU(vmesa);
415 UNLOCK_HARDWARE(vmesa);
416 return;
417 }
418
419 if (vmesa->TexObjList.prev == &(vmesa->TexObjList)) {
420 if (VIA_DEBUG) fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
421 mmDumpMemInfo(vmesa->texHeap);
422 UNLOCK_HARDWARE(vmesa);
423 return;
424 }
425
426 viaSwapOutTexObj(vmesa, vmesa->TexObjList.prev);
427 }
428 /*=* John Sheng [2003.5.31] agp tex *=*/
429 /*t->bufAddr = (char *)((GLuint)vmesa->driScreen->pFB + t->texMem.offset);*/
430
431 if (t == vmesa->CurrentTexObj[0])
432 VIA_FLUSH_DMA(vmesa);
433
434 if (t == vmesa->CurrentTexObj[1])
435 VIA_FLUSH_DMA(vmesa);
436
437 viaUpdateTexLRU(vmesa, t);
438
439 j++;
440 }
441
442 numLevels = t->lastLevel - t->firstLevel + 1;
443
444 for (i = 0; i < numLevels; i++)
445 if (t->dirtyImages & (1 << i))
446 viaUploadTexLevel(t, i);
447
448 t->dirtyImages = 0;
449 vmesa->clearTexCache = 1;
450
451 UNLOCK_HARDWARE(vmesa);
452 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
453 }