#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,
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)
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