Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / winsys / i965 / xlib / xlib_i965.c
1 /**************************************************************************
2  * 
3  * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  * 
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
19  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * The above copyright notice and this permission notice (including the
23  * next paragraph) shall be included in all copies or substantial portions
24  * of the Software.
25  * 
26  * 
27  **************************************************************************/
28
29 /*
30  * Authors:
31  *   Keith Whitwell
32  *   Brian Paul
33  */
34
35
36 #include "util/u_memory.h"
37 #include "util/u_math.h"
38 #include "pipe/p_error.h"
39 #include "pipe/p_context.h"
40
41 #include "xm_public.h"
42
43 #include "i965/brw_winsys.h"
44 #include "i965/brw_screen.h"
45 #include "i965/brw_resource.h"
46 #include "i965/brw_reg.h"
47 #include "i965/brw_structs_dump.h"
48
49 #define MAX_VRAM (128*1024*1024)
50
51
52
53 extern int brw_disasm (FILE *file, 
54                        const struct brw_instruction *inst,
55                        unsigned count );
56
57 extern int intel_decode(const uint32_t *data, 
58                         int count,
59                         uint32_t hw_offset,
60                         uint32_t devid);
61
62 struct xlib_brw_buffer
63 {
64    struct brw_winsys_buffer base;
65    char *virtual;
66    unsigned offset;
67    unsigned type;
68    int map_count;
69    boolean modified;
70 };
71
72
73 /**
74  * Subclass of brw_winsys_screen for Xlib winsys
75  */
76 struct xlib_brw_winsys
77 {
78    struct brw_winsys_screen base;
79    struct brw_chipset chipset;
80
81    unsigned size;
82    unsigned used;
83 };
84
85 static struct xlib_brw_winsys *
86 xlib_brw_winsys( struct brw_winsys_screen *screen )
87 {
88    return (struct xlib_brw_winsys *)screen;
89 }
90
91
92 static struct xlib_brw_buffer *
93 xlib_brw_buffer( struct brw_winsys_buffer *buffer )
94 {
95    return (struct xlib_brw_buffer *)buffer;
96 }
97
98
99
100 const char *names[BRW_BUFFER_TYPE_MAX] = {
101    "TEXTURE",
102    "SCANOUT",
103    "VERTEX",
104    "CURBE",
105    "QUERY",
106    "SHADER_CONSTANTS",
107    "WM_SCRATCH",
108    "BATCH",
109    "GENERAL_STATE",
110    "SURFACE_STATE",
111    "PIXEL",
112    "GENERIC",
113 };
114
115 const char *usages[BRW_USAGE_MAX] = {
116    "STATE",
117    "QUERY_RESULT",
118    "RENDER_TARGET",
119    "DEPTH_BUFFER",
120    "BLIT_SOURCE",
121    "BLIT_DEST",
122    "SAMPLER",
123    "VERTEX",
124    "SCRATCH"
125 };
126
127
128 const char *data_types[BRW_DATA_MAX] =
129 {
130    "GS: CC_VP",
131    "GS: CC_UNIT",
132    "GS: WM_PROG",
133    "GS: SAMPLER_DEFAULT_COLOR",
134    "GS: SAMPLER",
135    "GS: WM_UNIT",
136    "GS: SF_PROG",
137    "GS: SF_VP",
138    "GS: SF_UNIT",
139    "GS: VS_UNIT",
140    "GS: VS_PROG",
141    "GS: GS_UNIT",
142    "GS: GS_PROG",
143    "GS: CLIP_VP",
144    "GS: CLIP_UNIT",
145    "GS: CLIP_PROG",
146    "SS: SURFACE",
147    "SS: SURF_BIND",
148    "CONSTANT DATA",
149    "BATCH DATA",
150    "(untyped)"
151 };
152
153
154 static enum pipe_error
155 xlib_brw_bo_alloc( struct brw_winsys_screen *sws,
156                    enum brw_buffer_type type,
157                    unsigned size,
158                    unsigned alignment,
159                    struct brw_winsys_buffer **bo_out )
160 {
161    struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
162    struct xlib_brw_buffer *buf;
163
164    if (BRW_DEBUG & DEBUG_WINSYS)
165       debug_printf("%s type %s sz %d align %d\n",
166                    __FUNCTION__, names[type], size, alignment );
167
168    buf = CALLOC_STRUCT(xlib_brw_buffer);
169    if (!buf)
170       return PIPE_ERROR_OUT_OF_MEMORY;
171
172    pipe_reference_init(&buf->base.reference, 1);
173
174    buf->offset = align(xbw->used, alignment);
175    buf->type = type;
176    buf->virtual = MALLOC(size);
177    buf->base.size = size;
178    buf->base.sws = sws;
179
180    xbw->used = align(xbw->used, alignment) + size;
181    if (xbw->used > MAX_VRAM)
182       goto err;
183
184    /* XXX: possibly rentrant call to bo_destroy:
185     */
186    bo_reference(bo_out, &buf->base);
187    return PIPE_OK;
188
189 err:
190    assert(0);
191    FREE(buf->virtual);
192    FREE(buf);
193    return PIPE_ERROR_OUT_OF_MEMORY;
194 }
195
196 static void 
197 xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer )
198 {
199    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
200
201    FREE(buf);
202 }
203
204 static int 
205 xlib_brw_bo_emit_reloc( struct brw_winsys_buffer *buffer,
206                         enum brw_buffer_usage usage,
207                         unsigned delta,
208                         unsigned offset,
209                         struct brw_winsys_buffer *buffer2)
210 {
211    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
212    struct xlib_brw_buffer *buf2 = xlib_brw_buffer(buffer2);
213
214    if (BRW_DEBUG & DEBUG_WINSYS)
215       debug_printf("%s buf %p offset %x val %x + %x buf2 %p/%s/%s\n",
216                    __FUNCTION__, (void *)buffer, offset,
217                    buf2->offset, delta,
218                    (void *)buffer2, names[buf2->type], usages[usage]);
219
220    *(uint32_t *)(buf->virtual + offset) = buf2->offset + delta;
221
222    return 0;
223 }
224
225 static int 
226 xlib_brw_bo_exec( struct brw_winsys_buffer *buffer,
227                      unsigned bytes_used )
228 {
229    if (BRW_DEBUG & DEBUG_WINSYS)
230       debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
231
232    return 0;
233 }
234
235
236
237
238 static int
239 xlib_brw_bo_subdata(struct brw_winsys_buffer *buffer,
240                     enum brw_buffer_data_type data_type,
241                     size_t offset,
242                     size_t size,
243                     const void *data,
244                     const struct brw_winsys_reloc *reloc,
245                     unsigned nr_relocs)
246 {
247    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
248    struct xlib_brw_winsys *xbw = xlib_brw_winsys(buffer->sws);
249    unsigned i;
250
251    if (BRW_DEBUG & DEBUG_WINSYS)
252       debug_printf("%s buf %p off %d sz %d %s relocs: %d\n", 
253                    __FUNCTION__, 
254                    (void *)buffer, offset, size, 
255                    data_types[data_type],
256                    nr_relocs);
257
258    assert(buf->base.size >= offset + size);
259    memcpy(buf->virtual + offset, data, size);
260
261    /* Apply the relocations:
262     */
263    for (i = 0; i < nr_relocs; i++) {
264       if (BRW_DEBUG & DEBUG_WINSYS)
265          debug_printf("\treloc[%d] usage %s off %d value %x+%x\n", 
266                       i, usages[reloc[i].usage], reloc[i].offset,
267                       xlib_brw_buffer(reloc[i].bo)->offset, reloc[i].delta);
268
269       *(unsigned *)(buf->virtual + offset + reloc[i].offset) = 
270          xlib_brw_buffer(reloc[i].bo)->offset + reloc[i].delta;
271    }
272
273    if (BRW_DUMP)
274       brw_dump_data( xbw->chipset.pci_id,
275                      data_type,
276                      buf->offset + offset, 
277                      buf->virtual + offset, size );
278
279
280    return 0;
281 }
282
283
284 static boolean 
285 xlib_brw_bo_is_busy(struct brw_winsys_buffer *buffer)
286 {
287    if (BRW_DEBUG & DEBUG_WINSYS)
288       debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
289    return TRUE;
290 }
291
292 static boolean 
293 xlib_brw_bo_references(struct brw_winsys_buffer *a,
294                           struct brw_winsys_buffer *b)
295 {
296    if (BRW_DEBUG & DEBUG_WINSYS)
297       debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
298    return TRUE;
299 }
300
301 static enum pipe_error
302 xlib_brw_check_aperture_space( struct brw_winsys_screen *iws,
303                                 struct brw_winsys_buffer **buffers,
304                                 unsigned count )
305 {
306    unsigned tot_size = 0;
307    unsigned i;
308
309    for (i = 0; i < count; i++)
310       tot_size += buffers[i]->size;
311
312    if (BRW_DEBUG & DEBUG_WINSYS)
313       debug_printf("%s %d bufs, tot_size: %d kb\n", 
314                    __FUNCTION__, count, 
315                    (tot_size + 1023) / 1024);
316
317    return PIPE_OK;
318 }
319
320 static void *
321 xlib_brw_bo_map(struct brw_winsys_buffer *buffer,
322                 enum brw_buffer_data_type data_type,
323                 unsigned offset,
324                 unsigned length,
325                 boolean write,
326                 boolean discard,
327                 boolean explicit)
328 {
329    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
330
331    if (BRW_DEBUG & DEBUG_WINSYS)
332       debug_printf("%s %p %s %s\n", __FUNCTION__, (void *)buffer, 
333                    write ? "read/write" : "read",
334                    write ? data_types[data_type] : "");
335
336    if (write)
337       buf->modified = 1;
338
339    buf->map_count++;
340    return buf->virtual;
341 }
342
343
344 static void
345 xlib_brw_bo_flush_range( struct brw_winsys_buffer *buffer,
346                          unsigned offset,
347                          unsigned length )
348 {
349 }
350
351
352 static void 
353 xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer)
354 {
355    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
356
357    if (BRW_DEBUG & DEBUG_WINSYS)
358       debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
359
360    --buf->map_count;
361    assert(buf->map_count >= 0);
362
363    if (buf->map_count == 0 &&
364        buf->modified) {
365
366       buf->modified = 0;
367       
368       /* Consider dumping new buffer contents here, using the
369        * flush-range info to minimize verbosity.
370        */
371    }
372 }
373
374
375 static void
376 xlib_brw_bo_wait_idle( struct brw_winsys_buffer *buffer )
377 {
378 }
379
380
381 static void
382 xlib_brw_winsys_destroy( struct brw_winsys_screen *sws )
383 {
384    struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
385
386    FREE(xbw);
387 }
388
389 static struct brw_winsys_screen *
390 xlib_create_brw_winsys_screen( void )
391 {
392    struct xlib_brw_winsys *ws;
393
394    ws = CALLOC_STRUCT(xlib_brw_winsys);
395    if (!ws)
396       return NULL;
397
398    ws->used = 0;
399    ws->base.pci_id = PCI_CHIP_GM45_GM;
400
401    ws->base.destroy              = xlib_brw_winsys_destroy;
402    ws->base.bo_alloc             = xlib_brw_bo_alloc;
403    ws->base.bo_destroy           = xlib_brw_bo_destroy;
404    ws->base.bo_emit_reloc        = xlib_brw_bo_emit_reloc;
405    ws->base.bo_exec              = xlib_brw_bo_exec;
406    ws->base.bo_subdata           = xlib_brw_bo_subdata;
407    ws->base.bo_is_busy           = xlib_brw_bo_is_busy;
408    ws->base.bo_references        = xlib_brw_bo_references;
409    ws->base.check_aperture_space = xlib_brw_check_aperture_space;
410    ws->base.bo_map               = xlib_brw_bo_map;
411    ws->base.bo_flush_range       = xlib_brw_bo_flush_range;
412    ws->base.bo_unmap             = xlib_brw_bo_unmap;
413    ws->base.bo_wait_idle         = xlib_brw_bo_wait_idle;
414
415    return &ws->base;
416 }
417
418
419 /***********************************************************************
420  * Implementation of Xlib co-state-tracker's winsys interface
421  */
422
423 static void
424 xlib_i965_display_surface(struct xmesa_buffer *xm_buffer,
425                           struct pipe_resource *resource,
426                           unsigned level, unsigned layer)
427 {
428    struct brw_texture *tex = brw_texture(resource);
429    struct xlib_brw_buffer *bo = xlib_brw_buffer(tex->bo);
430    /* not sure if the resource is really useful here but
431       since it was never implemented anyway... */
432    if (BRW_DEBUG & DEBUG_WINSYS)
433       debug_printf("%s level %u layer %u offset %x base sz %dx%d\n", __FUNCTION__,
434                    level, layer,
435                    bo->offset,
436                    resource->width0,
437                    resource->height0);
438 }
439
440 static void
441 xlib_i965_flush_frontbuffer(struct pipe_screen *screen,
442                             struct pipe_resource *resource,
443                             unsigned level, unsigned layer,
444                             void *context_private)
445 {
446    xlib_i965_display_surface(NULL, resource, level, layer);
447 }
448
449
450 static struct pipe_screen *
451 xlib_create_i965_screen( void )
452 {
453    struct brw_winsys_screen *winsys;
454    struct pipe_screen *screen;
455
456    winsys = xlib_create_brw_winsys_screen();
457    if (winsys == NULL)
458       return NULL;
459
460    screen = brw_create_screen(winsys);
461    if (screen == NULL)
462       goto fail;
463
464    xlib_brw_winsys(winsys)->chipset = brw_screen(screen)->chipset;
465
466    screen->flush_frontbuffer = xlib_i965_flush_frontbuffer;
467    return screen;
468
469 fail:
470    if (winsys)
471       winsys->destroy( winsys );
472
473    return NULL;
474 }
475
476
477
478
479
480 struct xm_driver xlib_i965_driver = 
481 {
482    .create_pipe_screen = xlib_create_i965_screen,
483    .display_surface = xlib_i965_display_surface
484 };
485
486
487 /* Register this driver at library load: 
488  */
489 static void _init( void ) __attribute__((constructor));
490 static void _init( void )
491 {
492    xmesa_set_driver( &xlib_i965_driver );
493 }
494
495
496
497 /***********************************************************************
498  *
499  * Butt-ugly hack to convince the linker not to throw away public GL
500  * symbols (they are all referenced from getprocaddress, I guess).
501  */
502 extern void (*linker_foo(const unsigned char *procName))();
503 extern void (*glXGetProcAddress(const unsigned char *procName))();
504
505 extern void (*linker_foo(const unsigned char *procName))()
506 {
507    return glXGetProcAddress(procName);
508 }