Merge branch 'glsl2'
[mesa.git] / src / gallium / auxiliary / util / u_surfaces.c
1 #include "u_surfaces.h"
2 #include "util/u_hash_table.h"
3 #include "util/u_inlines.h"
4 #include "util/u_memory.h"
5
6 struct pipe_surface *
7 util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags)
8 {
9 struct pipe_surface *ps;
10
11 if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
12 { /* or 2D array */
13 if(!us->u.hash)
14 us->u.hash = cso_hash_create();
15
16 ps = cso_hash_iter_data(cso_hash_find(us->u.hash, ((zslice + face) << 8) | level));
17 }
18 else
19 {
20 if(!us->u.array)
21 us->u.array = CALLOC(pt->last_level + 1, sizeof(struct pipe_surface *));
22 ps = us->u.array[level];
23 }
24
25 if(ps)
26 {
27 p_atomic_inc(&ps->reference.count);
28 return ps;
29 }
30
31 ps = (struct pipe_surface *)CALLOC(1, surface_struct_size);
32 if(!ps)
33 return NULL;
34
35 pipe_surface_init(ps, pt, face, level, zslice, flags);
36 ps->offset = ~0;
37
38 if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
39 cso_hash_insert(us->u.hash, ((zslice + face) << 8) | level, ps);
40 else
41 us->u.array[level] = ps;
42
43 return ps;
44 }
45
46 void
47 util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps)
48 {
49 struct pipe_resource *pt = ps->texture;
50 if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
51 { /* or 2D array */
52 cso_hash_erase(us->u.hash, cso_hash_find(us->u.hash, ((ps->zslice + ps->face) << 8) | ps->level));
53 }
54 else
55 us->u.array[ps->level] = 0;
56 }
57
58 void
59 util_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (*destroy_surface) (struct pipe_surface *))
60 {
61 if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
62 { /* or 2D array */
63 if(us->u.hash)
64 {
65 struct cso_hash_iter iter;
66 iter = cso_hash_first_node(us->u.hash);
67 while (!cso_hash_iter_is_null(iter)) {
68 destroy_surface(cso_hash_iter_data(iter));
69 iter = cso_hash_iter_next(iter);
70 }
71
72 cso_hash_delete(us->u.hash);
73 us->u.hash = NULL;
74 }
75 }
76 else
77 {
78 if(us->u.array)
79 {
80 unsigned i;
81 for(i = 0; i <= pt->last_level; ++i)
82 {
83 struct pipe_surface *ps = us->u.array[i];
84 if(ps)
85 destroy_surface(ps);
86 }
87 FREE(us->u.array);
88 us->u.array = NULL;
89 }
90 }
91 }