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