Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / nvfx / nvfx_resource.h
1 #ifndef NVFX_RESOURCE_H
2 #define NVFX_RESOURCE_H
3
4 #include "util/u_transfer.h"
5 #include "util/u_format.h"
6 #include "util/u_math.h"
7 #include "util/u_double_list.h"
8 #include "util/u_surfaces.h"
9 #include "util/u_dirty_surfaces.h"
10 #include <nouveau/nouveau_bo.h>
11
12 struct pipe_resource;
13 struct nv04_region;
14
15 struct nvfx_resource {
16         struct pipe_resource base;
17         struct nouveau_bo *bo;
18 };
19
20 static INLINE
21 struct nvfx_resource *nvfx_resource(struct pipe_resource *resource)
22 {
23         return (struct nvfx_resource *)resource;
24 }
25
26 #define NVFX_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0)
27 #define NVFX_RESOURCE_FLAG_USER (PIPE_RESOURCE_FLAG_DRV_PRIV << 1)
28
29 /* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */
30 static INLINE boolean
31 nvfx_resource_mapped_by_gpu(struct pipe_resource *resource)
32 {
33    return nvfx_resource(resource)->bo->handle;
34 }
35
36 /* is resource in VRAM? */
37 static inline int
38 nvfx_resource_on_gpu(struct pipe_resource* pr)
39 {
40 #if 0
41         // a compiler error here means you need to apply libdrm-nouveau-add-domain.patch to libdrm
42         // TODO: return FALSE if not VRAM and on a PCI-E system
43         return ((struct nvfx_resource*)pr)->bo->domain & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
44 #else
45         return TRUE;
46 #endif
47 }
48
49 #define NVFX_MAX_TEXTURE_LEVELS  16
50
51 /* We have the following invariants for render temporaries
52  *
53  * 1. Render temporaries are always linear
54  * 2. Render temporaries are always up to date
55  * 3. Currently, render temporaries are destroyed when the resource is used for sampling, but kept for any other use
56  *
57  * Also, we do NOT flush temporaries on any pipe->flush().
58  * This is fine, as long as scanout targets and shared resources never need temps.
59  *
60  * TODO: we may want to also support swizzled temporaries to improve performance in some cases.
61  */
62
63 struct nvfx_miptree {
64         struct nvfx_resource base;
65
66         unsigned linear_pitch; /* for linear textures, 0 for swizzled and compressed textures with level-dependent minimal pitch */
67         unsigned face_size; /* 128-byte aligned face/total size */
68         unsigned level_offset[NVFX_MAX_TEXTURE_LEVELS];
69
70         struct util_surfaces surfaces;
71         struct util_dirty_surfaces dirty_surfaces;
72 };
73
74 struct nvfx_surface {
75         struct util_dirty_surface base;
76         unsigned pitch;
77         unsigned offset;
78
79         struct nvfx_miptree* temp;
80 };
81
82 static INLINE struct nouveau_bo *
83 nvfx_surface_buffer(struct pipe_surface *surf)
84 {
85         struct nvfx_resource *mt = nvfx_resource(surf->texture);
86
87         return mt->bo;
88 }
89
90 static INLINE struct util_dirty_surfaces*
91 nvfx_surface_get_dirty_surfaces(struct pipe_surface* surf)
92 {
93         struct nvfx_miptree *mt = (struct nvfx_miptree *)surf->texture;
94         return &mt->dirty_surfaces;
95 }
96
97 void
98 nvfx_init_resource_functions(struct pipe_context *pipe);
99
100 void
101 nvfx_screen_init_resource_functions(struct pipe_screen *pscreen);
102
103
104 /* Internal:
105  */
106
107 struct pipe_resource *
108 nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt);
109
110 void
111 nvfx_miptree_destroy(struct pipe_screen *pscreen,
112                      struct pipe_resource *presource);
113
114 struct pipe_resource *
115 nvfx_miptree_from_handle(struct pipe_screen *pscreen,
116                          const struct pipe_resource *template,
117                          struct winsys_handle *whandle);
118
119 void
120 nvfx_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps);
121
122 struct pipe_surface *
123 nvfx_miptree_surface_new(struct pipe_context *pipe, struct pipe_resource *pt,
124                          const struct pipe_surface *surf_tmpl);
125
126 /* only for miptrees, don't use for buffers */
127
128 /* NOTE: for swizzled 3D textures, this just returns the offset of the mipmap level */
129 static inline unsigned
130 nvfx_subresource_offset(struct pipe_resource* pt, unsigned face, unsigned level, unsigned zslice)
131 {
132         if(pt->target == PIPE_BUFFER)
133                 return 0;
134         else
135         {
136                 struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
137
138                 unsigned offset = mt->level_offset[level];
139                 if (pt->target == PIPE_TEXTURE_CUBE)
140                         offset += mt->face_size * face;
141                 else if (pt->target == PIPE_TEXTURE_3D && mt->linear_pitch)
142                         offset += zslice * util_format_get_2d_size(pt->format, (mt->linear_pitch ? mt->linear_pitch : util_format_get_stride(pt->format, u_minify(pt->width0, level))),  u_minify(pt->height0, level));
143                 return offset;
144         }
145 }
146
147 static inline unsigned
148 nvfx_subresource_pitch(struct pipe_resource* pt, unsigned level)
149 {
150         if(pt->target == PIPE_BUFFER)
151                 return ((struct nvfx_resource*)pt)->bo->size;
152         else
153         {
154                 struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
155
156                 if(mt->linear_pitch)
157                         return mt->linear_pitch;
158                 else
159                         return util_format_get_stride(pt->format, u_minify(pt->width0, level));
160         }
161 }
162
163 void
164 nvfx_surface_create_temp(struct pipe_context* pipe, struct pipe_surface* surf);
165
166 void
167 nvfx_surface_flush(struct pipe_context* pipe, struct pipe_surface* surf);
168
169 struct nvfx_buffer
170 {
171         struct nvfx_resource base;
172         uint8_t* data;
173         unsigned size;
174
175         /* the range of data not yet uploaded to the GPU bo */
176         unsigned dirty_begin;
177         unsigned dirty_end;
178
179         /* whether all transfers were unsynchronized */
180         boolean dirty_unsynchronized;
181
182         /* whether it would have been profitable to upload
183          * the latest updated data to the GPU immediately */
184         boolean last_update_static;
185
186         /* how many bytes we need to draw before we deem
187          * the buffer to be static
188          */
189         long long bytes_to_draw_until_static;
190 };
191
192 static inline struct nvfx_buffer* nvfx_buffer(struct pipe_resource* pr)
193 {
194         return (struct nvfx_buffer*)pr;
195 }
196
197 /* this is an heuristic to determine whether we are better off uploading the
198  * buffer to the GPU, or just continuing pushing it on the FIFO
199  */
200 static inline boolean nvfx_buffer_seems_static(struct nvfx_buffer* buffer)
201 {
202         return buffer->last_update_static
203                 || buffer->bytes_to_draw_until_static < 0;
204 }
205
206 struct pipe_resource *
207 nvfx_buffer_create(struct pipe_screen *pscreen,
208                    const struct pipe_resource *template);
209
210 void
211 nvfx_buffer_destroy(struct pipe_screen *pscreen,
212                     struct pipe_resource *presource);
213
214 struct pipe_resource *
215 nvfx_user_buffer_create(struct pipe_screen *screen,
216                         void *ptr,
217                         unsigned bytes,
218                         unsigned usage);
219
220 void
221 nvfx_buffer_upload(struct nvfx_buffer* buffer);
222
223 #endif