1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2014, 2015 Red Hat.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub
8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom
9bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#ifndef VIRGL_RESOURCE_H
25bf215546Sopenharmony_ci#define VIRGL_RESOURCE_H
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#include "util/u_resource.h"
28bf215546Sopenharmony_ci#include "util/u_range.h"
29bf215546Sopenharmony_ci#include "util/list.h"
30bf215546Sopenharmony_ci#include "util/u_transfer.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "virtio-gpu/virgl_hw.h"
33bf215546Sopenharmony_ci#include "virgl_screen.h"
34bf215546Sopenharmony_ci#define VR_MAX_TEXTURE_2D_LEVELS 15
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci#define VIRGL_BLOB_MEM_GUEST 1
37bf215546Sopenharmony_ci#define VIRGL_BLOB_MEM_HOST3D 2
38bf215546Sopenharmony_ci#define VIRGL_BLOB_MEM_HOST3D_GUEST 3
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_cistruct winsys_handle;
41bf215546Sopenharmony_cistruct virgl_screen;
42bf215546Sopenharmony_cistruct virgl_context;
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_cistruct virgl_resource_metadata
45bf215546Sopenharmony_ci{
46bf215546Sopenharmony_ci   unsigned long level_offset[VR_MAX_TEXTURE_2D_LEVELS];
47bf215546Sopenharmony_ci   unsigned stride[VR_MAX_TEXTURE_2D_LEVELS];
48bf215546Sopenharmony_ci   unsigned layer_stride[VR_MAX_TEXTURE_2D_LEVELS];
49bf215546Sopenharmony_ci   uint32_t plane, plane_offset, total_size;
50bf215546Sopenharmony_ci   uint64_t modifier;
51bf215546Sopenharmony_ci};
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_cistruct virgl_resource {
54bf215546Sopenharmony_ci   struct pipe_resource b;
55bf215546Sopenharmony_ci   struct virgl_hw_res *hw_res;
56bf215546Sopenharmony_ci   struct virgl_resource_metadata metadata;
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci   /* For PIPE_BUFFER only.  Data outside of this range are uninitialized. */
59bf215546Sopenharmony_ci   struct util_range valid_buffer_range;
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci   /* This mask indicates where the resource has been bound to, excluding
62bf215546Sopenharmony_ci    * pipe_surface binds.
63bf215546Sopenharmony_ci    *
64bf215546Sopenharmony_ci    * This is more accurate than pipe_resource::bind.  Besides,
65bf215546Sopenharmony_ci    * pipe_resource::bind can be 0 with direct state access, and is not
66bf215546Sopenharmony_ci    * usable.
67bf215546Sopenharmony_ci    */
68bf215546Sopenharmony_ci   unsigned bind_history;
69bf215546Sopenharmony_ci   uint32_t blob_mem;
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_ci   uint16_t clean_mask;
72bf215546Sopenharmony_ci   uint16_t use_staging : 1;
73bf215546Sopenharmony_ci   uint16_t reserved : 15;
74bf215546Sopenharmony_ci};
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_cistruct virgl_transfer {
77bf215546Sopenharmony_ci   struct pipe_transfer base;
78bf215546Sopenharmony_ci   uint32_t offset, l_stride;
79bf215546Sopenharmony_ci   struct util_range range;
80bf215546Sopenharmony_ci   struct list_head queue_link;
81bf215546Sopenharmony_ci   struct pipe_transfer *resolve_transfer;
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci   struct virgl_hw_res *hw_res;
84bf215546Sopenharmony_ci   void *hw_res_map;
85bf215546Sopenharmony_ci   /* If not NULL, denotes that this is a copy transfer, i.e.,
86bf215546Sopenharmony_ci    * that the transfer source data should be taken from this
87bf215546Sopenharmony_ci    * resource instead of the original transfer resource.
88bf215546Sopenharmony_ci    */
89bf215546Sopenharmony_ci   struct virgl_hw_res *copy_src_hw_res;
90bf215546Sopenharmony_ci   /* The offset in the copy source resource to copy data from. */
91bf215546Sopenharmony_ci   uint32_t copy_src_offset;
92bf215546Sopenharmony_ci   /* copy transfers can be performed to and from host */
93bf215546Sopenharmony_ci   uint32_t direction;
94bf215546Sopenharmony_ci};
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_civoid virgl_resource_destroy(struct pipe_screen *screen,
97bf215546Sopenharmony_ci                            struct pipe_resource *resource);
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_civoid virgl_init_screen_resource_functions(struct pipe_screen *screen);
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_civoid virgl_init_context_resource_functions(struct pipe_context *ctx);
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_civoid virgl_texture_init(struct virgl_resource *res);
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_cistatic inline struct virgl_resource *virgl_resource(struct pipe_resource *r)
106bf215546Sopenharmony_ci{
107bf215546Sopenharmony_ci   return (struct virgl_resource *)r;
108bf215546Sopenharmony_ci}
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_cistatic inline struct virgl_transfer *virgl_transfer(struct pipe_transfer *trans)
111bf215546Sopenharmony_ci{
112bf215546Sopenharmony_ci   return (struct virgl_transfer *)trans;
113bf215546Sopenharmony_ci}
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_civoid virgl_buffer_transfer_flush_region(struct pipe_context *ctx,
116bf215546Sopenharmony_ci                                        struct pipe_transfer *transfer,
117bf215546Sopenharmony_ci                                        const struct pipe_box *box);
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_civoid virgl_buffer_transfer_unmap(struct pipe_context *ctx,
120bf215546Sopenharmony_ci                                 struct pipe_transfer *transfer);
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_civoid virgl_buffer_init(struct virgl_resource *res);
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_cistatic inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs,
125bf215546Sopenharmony_ci                                          unsigned pbind)
126bf215546Sopenharmony_ci{
127bf215546Sopenharmony_ci   unsigned outbind = 0;
128bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_DEPTH_STENCIL)
129bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_DEPTH_STENCIL;
130bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_RENDER_TARGET)
131bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_RENDER_TARGET;
132bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_SAMPLER_VIEW)
133bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_SAMPLER_VIEW;
134bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_VERTEX_BUFFER)
135bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_VERTEX_BUFFER;
136bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_INDEX_BUFFER)
137bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_INDEX_BUFFER;
138bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_CONSTANT_BUFFER)
139bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_CONSTANT_BUFFER;
140bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_DISPLAY_TARGET)
141bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_DISPLAY_TARGET;
142bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_STREAM_OUTPUT)
143bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_STREAM_OUTPUT;
144bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_CURSOR)
145bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_CURSOR;
146bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_CUSTOM)
147bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_CUSTOM;
148bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_SCANOUT)
149bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_SCANOUT;
150bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_SHARED)
151bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_SHARED;
152bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_SHADER_BUFFER)
153bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_SHADER_BUFFER;
154bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_QUERY_BUFFER)
155bf215546Sopenharmony_ci      outbind |= VIRGL_BIND_QUERY_BUFFER;
156bf215546Sopenharmony_ci   if (pbind & PIPE_BIND_COMMAND_ARGS_BUFFER)
157bf215546Sopenharmony_ci      if (vs->caps.caps.v2.capability_bits & VIRGL_CAP_BIND_COMMAND_ARGS)
158bf215546Sopenharmony_ci         outbind |= VIRGL_BIND_COMMAND_ARGS;
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_ci   /* Staging resources should only be created directly through the winsys,
161bf215546Sopenharmony_ci    * not using pipe_resources.
162bf215546Sopenharmony_ci    */
163bf215546Sopenharmony_ci   assert(!(outbind & VIRGL_BIND_STAGING));
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   return outbind;
166bf215546Sopenharmony_ci}
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_cistatic inline unsigned pipe_to_virgl_flags(const struct virgl_screen *vs,
169bf215546Sopenharmony_ci                                           unsigned pflags)
170bf215546Sopenharmony_ci{
171bf215546Sopenharmony_ci   unsigned out_flags = 0;
172bf215546Sopenharmony_ci   if (pflags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
173bf215546Sopenharmony_ci      out_flags |= VIRGL_RESOURCE_FLAG_MAP_PERSISTENT;
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_ci   if (pflags & PIPE_RESOURCE_FLAG_MAP_COHERENT)
176bf215546Sopenharmony_ci      out_flags |= VIRGL_RESOURCE_FLAG_MAP_COHERENT;
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci   return out_flags;
179bf215546Sopenharmony_ci}
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_civoid *
182bf215546Sopenharmony_civirgl_resource_transfer_map(struct pipe_context *ctx,
183bf215546Sopenharmony_ci                            struct pipe_resource *resource,
184bf215546Sopenharmony_ci                            unsigned level,
185bf215546Sopenharmony_ci                            unsigned usage,
186bf215546Sopenharmony_ci                            const struct pipe_box *box,
187bf215546Sopenharmony_ci                            struct pipe_transfer **transfer);
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_cistruct virgl_transfer *
190bf215546Sopenharmony_civirgl_resource_create_transfer(struct virgl_context *vctx,
191bf215546Sopenharmony_ci                               struct pipe_resource *pres,
192bf215546Sopenharmony_ci                               const struct virgl_resource_metadata *metadata,
193bf215546Sopenharmony_ci                               unsigned level, unsigned usage,
194bf215546Sopenharmony_ci                               const struct pipe_box *box);
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_civoid virgl_resource_destroy_transfer(struct virgl_context *vctx,
197bf215546Sopenharmony_ci                                     struct virgl_transfer *trans);
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_civoid virgl_resource_destroy(struct pipe_screen *screen,
200bf215546Sopenharmony_ci                            struct pipe_resource *resource);
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_cibool virgl_resource_get_handle(struct pipe_screen *screen,
203bf215546Sopenharmony_ci                               struct pipe_context *context,
204bf215546Sopenharmony_ci                               struct pipe_resource *resource,
205bf215546Sopenharmony_ci                               struct winsys_handle *whandle,
206bf215546Sopenharmony_ci                               unsigned usage);
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_civoid virgl_resource_dirty(struct virgl_resource *res, uint32_t level);
209bf215546Sopenharmony_ci
210bf215546Sopenharmony_civoid *virgl_texture_transfer_map(struct pipe_context *ctx,
211bf215546Sopenharmony_ci                                 struct pipe_resource *resource,
212bf215546Sopenharmony_ci                                 unsigned level,
213bf215546Sopenharmony_ci                                 unsigned usage,
214bf215546Sopenharmony_ci                                 const struct pipe_box *box,
215bf215546Sopenharmony_ci                                 struct pipe_transfer **transfer);
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_civoid virgl_texture_transfer_unmap(struct pipe_context *ctx,
218bf215546Sopenharmony_ci                                  struct pipe_transfer *transfer);
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci#endif
221