Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / unichrome / via_fb.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 #include <assert.h>
26
27 #include "via_context.h"
28 #include "via_ioctl.h"
29 #include "via_fb.h"
30 #include "xf86drm.h"
31 #include "main/imports.h"
32 #include "main/simple_list.h"
33 #include <sys/ioctl.h>
34
35 GLboolean
36 via_alloc_draw_buffer(struct via_context *vmesa, struct via_renderbuffer *buf)
37 {
38    drm_via_mem_t mem;
39    mem.context = vmesa->hHWContext;
40    mem.size = buf->size;
41    mem.type = VIA_MEM_VIDEO;
42    mem.offset = 0;
43    mem.index = 0;
44
45    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &mem)) 
46       return GL_FALSE;
47     
48     
49    buf->offset = mem.offset;
50    buf->map = (char *)vmesa->driScreen->pFB + mem.offset;
51    buf->index = mem.index;
52    return GL_TRUE;
53 }
54
55 void
56 via_free_draw_buffer(struct via_context *vmesa, struct via_renderbuffer *buf)
57 {
58    drm_via_mem_t mem;
59
60    if (!vmesa) return;
61
62    mem.context = vmesa->hHWContext;
63    mem.index = buf->index;
64    mem.type = VIA_MEM_VIDEO;
65    mem.offset = buf->offset;
66    mem.size = buf->size;
67
68    ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &mem);
69    buf->map = NULL;
70 }
71
72
73 GLboolean
74 via_alloc_dma_buffer(struct via_context *vmesa)
75 {
76    drm_via_dma_init_t init;
77
78    vmesa->dma = (GLubyte *) malloc(VIA_DMA_BUFSIZ);
79     
80    /*
81     * Check whether AGP DMA has been initialized.
82     */
83    memset(&init, 0, sizeof(init));
84    init.func = VIA_DMA_INITIALIZED;
85
86    vmesa->useAgp = 
87      ( 0 == drmCommandWrite(vmesa->driFd, DRM_VIA_DMA_INIT, 
88                              &init, sizeof(init)));
89    if (VIA_DEBUG & DEBUG_DMA) {
90       if (vmesa->useAgp) 
91          fprintf(stderr, "unichrome_dri.so: Using AGP.\n");
92       else
93          fprintf(stderr, "unichrome_dri.so: Using PCI.\n");
94    }
95       
96    return ((vmesa->dma) ? GL_TRUE : GL_FALSE);
97 }
98
99 void
100 via_free_dma_buffer(struct via_context *vmesa)
101 {
102     if (!vmesa) return;
103     free(vmesa->dma);
104     vmesa->dma = 0;
105
106
107
108 /* These functions now allocate and free the via_tex_buffer struct as well:
109  */
110 struct via_tex_buffer *
111 via_alloc_texture(struct via_context *vmesa,
112                   GLuint size,
113                   GLuint memType)
114 {
115    struct via_tex_buffer *t = CALLOC_STRUCT(via_tex_buffer);
116    
117    if (!t)
118       goto cleanup;
119
120    t->size = size;
121    t->memType = memType;
122    insert_at_tail(&vmesa->tex_image_list[memType], t);
123
124    if (t->memType == VIA_MEM_AGP || 
125        t->memType == VIA_MEM_VIDEO) {
126       drm_via_mem_t fb;
127
128       fb.context = vmesa->hHWContext;
129       fb.size = t->size;
130       fb.type = t->memType;
131       fb.offset = 0;
132       fb.index = 0;
133
134       if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb) != 0 || 
135           fb.index == 0) 
136          goto cleanup;
137
138       if (0)
139          fprintf(stderr, "offset %lx index %lx\n", fb.offset, fb.index);
140
141       t->offset = fb.offset;
142       t->index = fb.index;
143       
144       if (t->memType == VIA_MEM_AGP) {
145          t->bufAddr = (GLubyte *)((unsigned long)vmesa->viaScreen->agpLinearStart +
146                                   fb.offset);   
147          t->texBase = vmesa->agpBase + fb.offset;
148       }
149       else {
150          t->bufAddr = (GLubyte *)((unsigned long)vmesa->driScreen->pFB + fb.offset);
151          t->texBase = fb.offset;
152       }
153
154       vmesa->total_alloc[t->memType] += t->size;
155       return t;
156    }
157    else if (t->memType == VIA_MEM_SYSTEM) {
158       
159       t->bufAddr = malloc(t->size);      
160       if (!t->bufAddr)
161          goto cleanup;
162
163       vmesa->total_alloc[t->memType] += t->size;
164       return t;
165    }
166
167  cleanup:
168    if (t) {
169       remove_from_list(t);
170       FREE(t);
171    }
172
173    return NULL;
174 }
175
176
177 static void
178 via_do_free_texture(struct via_context *vmesa, struct via_tex_buffer *t)
179 {
180    drm_via_mem_t fb;
181
182    remove_from_list( t );
183
184    vmesa->total_alloc[t->memType] -= t->size;
185
186    fb.context = vmesa->hHWContext;
187    fb.index = t->index;
188    fb.offset = t->offset;
189    fb.type = t->memType;
190    fb.size = t->size;
191
192    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
193       fprintf(stderr, "via_free_texture fail\n");
194    }
195
196    FREE(t);
197 }
198
199
200 /* Release textures which were potentially still being referenced by
201  * hardware at the time when they were originally freed.
202  */
203 void 
204 via_release_pending_textures( struct via_context *vmesa )
205 {
206    struct via_tex_buffer *s, *tmp;
207    
208    foreach_s( s, tmp, &vmesa->freed_tex_buffers ) {
209       if (!VIA_GEQ_WRAP(s->lastUsed, vmesa->lastBreadcrumbRead)) {
210          if (VIA_DEBUG & DEBUG_TEXTURE)
211             fprintf(stderr, "%s: release tex sz %d lastUsed %x\n",
212                     __FUNCTION__, s->size, s->lastUsed); 
213          via_do_free_texture(vmesa, s);
214       }
215    }
216 }
217       
218
219
220 void
221 via_free_texture(struct via_context *vmesa, struct via_tex_buffer *t)
222 {
223    if (!t) {
224       return;
225    }
226    else if (t->memType == VIA_MEM_SYSTEM) {
227       remove_from_list(t);
228       vmesa->total_alloc[t->memType] -= t->size;
229       free(t->bufAddr);
230       free(t);
231    }
232    else if (t->index && viaCheckBreadcrumb(vmesa, t->lastUsed)) {
233       via_do_free_texture( vmesa, t );
234    }
235    else {
236       /* Close current breadcrumb so that we can free this eventually:
237        */
238       if (t->lastUsed == vmesa->lastBreadcrumbWrite) 
239          viaEmitBreadcrumb(vmesa);
240
241       move_to_tail( &vmesa->freed_tex_buffers, t );
242    }
243 }