v3d: add new flag dirty TMU cache at v3d_compiler
[mesa.git] / src / gallium / drivers / virgl / virgl_resource.h
index 297bc72e19869c16d78b34cb5fa52e5f30e4deff..f17dac72a0eba27f21e222871077123e67924ae4 100644 (file)
 #include "util/u_transfer.h"
 
 #include "virgl_hw.h"
+#include "virgl_screen.h"
 #define VR_MAX_TEXTURE_2D_LEVELS 15
 
 struct winsys_handle;
 struct virgl_screen;
 struct virgl_context;
 
+struct virgl_resource_metadata
+{
+   unsigned long level_offset[VR_MAX_TEXTURE_2D_LEVELS];
+   unsigned stride[VR_MAX_TEXTURE_2D_LEVELS];
+   unsigned layer_stride[VR_MAX_TEXTURE_2D_LEVELS];
+   uint32_t plane, plane_offset, total_size;
+   uint64_t modifier;
+};
+
 struct virgl_resource {
    struct u_resource u;
+   uint16_t clean_mask;
    struct virgl_hw_res *hw_res;
-   boolean clean;
-};
-
-struct virgl_buffer {
-   struct virgl_resource base;
+   struct virgl_resource_metadata metadata;
 
-   struct list_head flush_list;
-   boolean on_list;
+   /* For PIPE_BUFFER only.  Data outside of this range are uninitialized. */
+   struct util_range valid_buffer_range;
 
-   /* The buffer range which is initialized (with a write transfer,
-    * streamout, DMA, or as a random access target). The rest of
-    * the buffer is considered invalid and can be mapped unsynchronized.
+   /* This mask indicates where the resource has been bound to, excluding
+    * pipe_surface binds.
     *
-    * This allows unsychronized mapping of a buffer range which hasn't
-    * been used yet. It's for applications which forget to use
-    * the unsynchronized map flag and expect the driver to figure it out.
+    * This is more accurate than pipe_resource::bind.  Besides,
+    * pipe_resource::bind can be 0 with direct state access, and is not
+    * usable.
     */
-   struct util_range valid_buffer_range;
-};
-
-struct virgl_texture {
-   struct virgl_resource base;
-
-   unsigned long level_offset[VR_MAX_TEXTURE_2D_LEVELS];
-   unsigned stride[VR_MAX_TEXTURE_2D_LEVELS];
+   unsigned bind_history;
 };
 
 struct virgl_transfer {
    struct pipe_transfer base;
-   uint32_t offset;
-   struct virgl_resource *resolve_tmp;
+   uint32_t offset, l_stride;
+   struct util_range range;
+   struct list_head queue_link;
+   struct pipe_transfer *resolve_transfer;
+
+   struct virgl_hw_res *hw_res;
+   void *hw_res_map;
+   /* If not NULL, denotes that this is a copy transfer, i.e.,
+    * that the transfer source data should be taken from this
+    * resource instead of the original transfer resource.
+    */
+   struct virgl_hw_res *copy_src_hw_res;
+   /* The offset in the copy source resource to copy data from. */
+   uint32_t copy_src_offset;
 };
 
 void virgl_resource_destroy(struct pipe_screen *screen,
@@ -79,37 +90,22 @@ void virgl_init_screen_resource_functions(struct pipe_screen *screen);
 
 void virgl_init_context_resource_functions(struct pipe_context *ctx);
 
-struct pipe_resource *virgl_texture_create(struct virgl_screen *vs,
-                                           const struct pipe_resource *templ);
-
-struct pipe_resource *virgl_texture_from_handle(struct virgl_screen *vs,
-                                                const struct pipe_resource *templ,
-                                                struct winsys_handle *whandle);
+void virgl_texture_init(struct virgl_resource *res);
 
 static inline struct virgl_resource *virgl_resource(struct pipe_resource *r)
 {
    return (struct virgl_resource *)r;
 }
 
-static inline struct virgl_buffer *virgl_buffer(struct pipe_resource *r)
-{
-   return (struct virgl_buffer *)r;
-}
-
-static inline struct virgl_texture *virgl_texture(struct pipe_resource *r)
-{
-   return (struct virgl_texture *)r;
-}
-
 static inline struct virgl_transfer *virgl_transfer(struct pipe_transfer *trans)
 {
    return (struct virgl_transfer *)trans;
 }
 
-struct pipe_resource *virgl_buffer_create(struct virgl_screen *vs,
-                                          const struct pipe_resource *templ);
+void virgl_buffer_init(struct virgl_resource *res);
 
-static inline unsigned pipe_to_virgl_bind(unsigned pbind)
+static inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs,
+                                          unsigned pbind, unsigned flags)
 {
    unsigned outbind = 0;
    if (pbind & PIPE_BIND_DEPTH_STENCIL)
@@ -134,15 +130,49 @@ static inline unsigned pipe_to_virgl_bind(unsigned pbind)
       outbind |= VIRGL_BIND_CUSTOM;
    if (pbind & PIPE_BIND_SCANOUT)
       outbind |= VIRGL_BIND_SCANOUT;
+   if (pbind & PIPE_BIND_SHARED)
+      outbind |= VIRGL_BIND_SHARED;
    if (pbind & PIPE_BIND_SHADER_BUFFER)
       outbind |= VIRGL_BIND_SHADER_BUFFER;
+   if (pbind & PIPE_BIND_QUERY_BUFFER)
+      outbind |= VIRGL_BIND_QUERY_BUFFER;
+   if (pbind & PIPE_BIND_COMMAND_ARGS_BUFFER)
+      if (vs->caps.caps.v2.capability_bits & VIRGL_CAP_BIND_COMMAND_ARGS)
+         outbind |= VIRGL_BIND_COMMAND_ARGS;
+
+   /* Staging resources should only be created directly through the winsys,
+    * not using pipe_resources.
+    */
+   assert(!(outbind & VIRGL_BIND_STAGING));
+
    return outbind;
 }
 
-bool virgl_res_needs_flush_wait(struct virgl_context *vctx,
-                                struct virgl_resource *res,
-                                unsigned usage);
-bool virgl_res_needs_readback(struct virgl_context *vctx,
-                              struct virgl_resource *res,
-                              unsigned usage);
+void *
+virgl_resource_transfer_map(struct pipe_context *ctx,
+                            struct pipe_resource *resource,
+                            unsigned level,
+                            unsigned usage,
+                            const struct pipe_box *box,
+                            struct pipe_transfer **transfer);
+
+struct virgl_transfer *
+virgl_resource_create_transfer(struct virgl_context *vctx,
+                               struct pipe_resource *pres,
+                               const struct virgl_resource_metadata *metadata,
+                               unsigned level, unsigned usage,
+                               const struct pipe_box *box);
+
+void virgl_resource_destroy_transfer(struct virgl_context *vctx,
+                                     struct virgl_transfer *trans);
+
+void virgl_resource_destroy(struct pipe_screen *screen,
+                            struct pipe_resource *resource);
+
+bool virgl_resource_get_handle(struct pipe_screen *screen,
+                               struct pipe_resource *resource,
+                               struct winsys_handle *whandle);
+
+void virgl_resource_dirty(struct virgl_resource *res, uint32_t level);
+
 #endif