docs: Update status of GL 3.x related extensions
[mesa.git] / src / gallium / drivers / nvfx / nvfx_resource.h
index a68c14cf3fbe9ae045a595d6420faf062a247a19..583be4de2ae2596bca94c091fd1163fd701254b3 100644 (file)
@@ -1,44 +1,82 @@
-
 #ifndef NVFX_RESOURCE_H
 #define NVFX_RESOURCE_H
 
 #include "util/u_transfer.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_double_list.h"
+#include "util/u_surfaces.h"
+#include "util/u_dirty_surfaces.h"
+#include <nouveau/nouveau_bo.h>
 
 struct pipe_resource;
-struct nouveau_bo;
-
+struct nv04_region;
 
-/* This gets further specialized into either buffer or texture
- * structures.  In the future we'll want to remove much of that
- * distinction, but for now try to keep as close to the existing code
- * as possible and use the vtbl struct to choose between the two
- * underlying implementations.
- */
 struct nvfx_resource {
        struct pipe_resource base;
-       struct u_resource_vtbl *vtbl;
        struct nouveau_bo *bo;
 };
 
+static INLINE
+struct nvfx_resource *nvfx_resource(struct pipe_resource *resource)
+{
+       return (struct nvfx_resource *)resource;
+}
+
+#define NVFX_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0)
+#define NVFX_RESOURCE_FLAG_USER (PIPE_RESOURCE_FLAG_DRV_PRIV << 1)
+
+/* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */
+static INLINE boolean
+nvfx_resource_mapped_by_gpu(struct pipe_resource *resource)
+{
+   return nvfx_resource(resource)->bo->handle;
+}
+
+/* is resource in VRAM? */
+static inline int
+nvfx_resource_on_gpu(struct pipe_resource* pr)
+{
+#if 0
+       // a compiler error here means you need to apply libdrm-nouveau-add-domain.patch to libdrm
+       // TODO: return FALSE if not VRAM and on a PCI-E system
+       return ((struct nvfx_resource*)pr)->bo->domain & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
+#else
+       return TRUE;
+#endif
+}
+
 #define NVFX_MAX_TEXTURE_LEVELS  16
 
+/* We have the following invariants for render temporaries
+ *
+ * 1. Render temporaries are always linear
+ * 2. Render temporaries are always up to date
+ * 3. Currently, render temporaries are destroyed when the resource is used for sampling, but kept for any other use
+ *
+ * Also, we do NOT flush temporaries on any pipe->flush().
+ * This is fine, as long as scanout targets and shared resources never need temps.
+ *
+ * TODO: we may want to also support swizzled temporaries to improve performance in some cases.
+ */
+
 struct nvfx_miptree {
-       struct nvfx_resource base;
-       uint total_size;
+        struct nvfx_resource base;
 
-       struct {
-               uint pitch;
-               uint *image_offset;
-       } level[NVFX_MAX_TEXTURE_LEVELS];
+        unsigned linear_pitch; /* for linear textures, 0 for swizzled and compressed textures with level-dependent minimal pitch */
+        unsigned face_size; /* 128-byte aligned face/total size */
+        unsigned level_offset[NVFX_MAX_TEXTURE_LEVELS];
 
-       unsigned image_nr;
+        struct util_surfaces surfaces;
+        struct util_dirty_surfaces dirty_surfaces;
 };
 
-static INLINE 
-struct nvfx_resource *nvfx_resource(struct pipe_resource *resource)
-{
-       return (struct nvfx_resource *)resource;
-}
+struct nvfx_surface {
+       struct util_dirty_surface base;
+       unsigned pitch;
+
+       struct nvfx_miptree* temp;
+};
 
 static INLINE struct nouveau_bo *
 nvfx_surface_buffer(struct pipe_surface *surf)
@@ -48,6 +86,12 @@ nvfx_surface_buffer(struct pipe_surface *surf)
        return mt->bo;
 }
 
+static INLINE struct util_dirty_surfaces*
+nvfx_surface_get_dirty_surfaces(struct pipe_surface* surf)
+{
+       struct nvfx_miptree *mt = (struct nvfx_miptree *)surf->texture;
+       return &mt->dirty_surfaces;
+}
 
 void
 nvfx_init_resource_functions(struct pipe_context *pipe);
@@ -62,30 +106,118 @@ nvfx_screen_init_resource_functions(struct pipe_screen *pscreen);
 struct pipe_resource *
 nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt);
 
+void
+nvfx_miptree_destroy(struct pipe_screen *pscreen,
+                     struct pipe_resource *presource);
+
 struct pipe_resource *
 nvfx_miptree_from_handle(struct pipe_screen *pscreen,
                         const struct pipe_resource *template,
                         struct winsys_handle *whandle);
 
+void
+nvfx_miptree_surface_del(struct pipe_surface *ps);
+
+struct pipe_surface *
+nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
+                        unsigned face, unsigned level, unsigned zslice,
+                        unsigned flags);
+
+/* only for miptrees, don't use for buffers */
+
+/* NOTE: for swizzled 3D textures, this just returns the offset of the mipmap level */
+static inline unsigned
+nvfx_subresource_offset(struct pipe_resource* pt, unsigned face, unsigned level, unsigned zslice)
+{
+       if(pt->target == PIPE_BUFFER)
+               return 0;
+       else
+       {
+               struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
+
+               unsigned offset = mt->level_offset[level];
+               if (pt->target == PIPE_TEXTURE_CUBE)
+                       offset += mt->face_size * face;
+               else if (pt->target == PIPE_TEXTURE_3D && mt->linear_pitch)
+                       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));
+               return offset;
+       }
+}
+
+static inline unsigned
+nvfx_subresource_pitch(struct pipe_resource* pt, unsigned level)
+{
+       if(pt->target == PIPE_BUFFER)
+               return ((struct nvfx_resource*)pt)->bo->size;
+       else
+       {
+               struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
+
+               if(mt->linear_pitch)
+                       return mt->linear_pitch;
+               else
+                       return util_format_get_stride(pt->format, u_minify(pt->width0, level));
+       }
+}
+
+void
+nvfx_surface_create_temp(struct pipe_context* pipe, struct pipe_surface* surf);
+
+void
+nvfx_surface_flush(struct pipe_context* pipe, struct pipe_surface* surf);
+
+struct nvfx_buffer
+{
+       struct nvfx_resource base;
+       uint8_t* data;
+       unsigned size;
+
+       /* the range of data not yet uploaded to the GPU bo */
+       unsigned dirty_begin;
+       unsigned dirty_end;
+
+       /* whether all transfers were unsynchronized */
+       boolean dirty_unsynchronized;
+
+       /* whether it would have been profitable to upload
+        * the latest updated data to the GPU immediately */
+       boolean last_update_static;
+
+       /* how many bytes we need to draw before we deem
+        * the buffer to be static
+        */
+       long long bytes_to_draw_until_static;
+};
+
+static inline struct nvfx_buffer* nvfx_buffer(struct pipe_resource* pr)
+{
+       return (struct nvfx_buffer*)pr;
+}
+
+/* this is an heuristic to determine whether we are better off uploading the
+ * buffer to the GPU, or just continuing pushing it on the FIFO
+ */
+static inline boolean nvfx_buffer_seems_static(struct nvfx_buffer* buffer)
+{
+       return buffer->last_update_static
+               || buffer->bytes_to_draw_until_static < 0;
+}
+
 struct pipe_resource *
 nvfx_buffer_create(struct pipe_screen *pscreen,
                   const struct pipe_resource *template);
 
+void
+nvfx_buffer_destroy(struct pipe_screen *pscreen,
+                    struct pipe_resource *presource);
+
 struct pipe_resource *
 nvfx_user_buffer_create(struct pipe_screen *screen,
                        void *ptr,
                        unsigned bytes,
                        unsigned usage);
 
-
-
 void
-nvfx_miptree_surface_del(struct pipe_surface *ps);
-
-struct pipe_surface *
-nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
-                        unsigned face, unsigned level, unsigned zslice,
-                        unsigned flags);
-
+nvfx_buffer_upload(struct nvfx_buffer* buffer);
 
 #endif