1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21bf215546Sopenharmony_ci * SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci * Authors:
24bf215546Sopenharmony_ci *    Rob Clark <robclark@freedesktop.org>
25bf215546Sopenharmony_ci */
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#ifndef FREEDRENO_RESOURCE_H_
28bf215546Sopenharmony_ci#define FREEDRENO_RESOURCE_H_
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include "util/list.h"
31bf215546Sopenharmony_ci#include "util/simple_mtx.h"
32bf215546Sopenharmony_ci#include "util/u_dump.h"
33bf215546Sopenharmony_ci#include "util/u_range.h"
34bf215546Sopenharmony_ci#include "util/u_transfer_helper.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci#include "freedreno/fdl/freedreno_layout.h"
37bf215546Sopenharmony_ci#include "freedreno_batch.h"
38bf215546Sopenharmony_ci#include "freedreno_util.h"
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci#define PRSC_FMT                                                               \
41bf215546Sopenharmony_ci   "p: target=%s, format=%s, %ux%ux%u, "                                       \
42bf215546Sopenharmony_ci   "array_size=%u, last_level=%u, "                                            \
43bf215546Sopenharmony_ci   "nr_samples=%u, usage=%u, bind=%x, flags=%x"
44bf215546Sopenharmony_ci#define PRSC_ARGS(p)                                                           \
45bf215546Sopenharmony_ci   (p), util_str_tex_target((p)->target, true),                                \
46bf215546Sopenharmony_ci      util_format_short_name((p)->format), (p)->width0, (p)->height0,          \
47bf215546Sopenharmony_ci      (p)->depth0, (p)->array_size, (p)->last_level, (p)->nr_samples,          \
48bf215546Sopenharmony_ci      (p)->usage, (p)->bind, (p)->flags
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_cienum fd_lrz_direction {
51bf215546Sopenharmony_ci   FD_LRZ_UNKNOWN,
52bf215546Sopenharmony_ci   /* Depth func less/less-than: */
53bf215546Sopenharmony_ci   FD_LRZ_LESS,
54bf215546Sopenharmony_ci   /* Depth func greater/greater-than: */
55bf215546Sopenharmony_ci   FD_LRZ_GREATER,
56bf215546Sopenharmony_ci};
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci/**
59bf215546Sopenharmony_ci * State related to batch/resource tracking.
60bf215546Sopenharmony_ci *
61bf215546Sopenharmony_ci * With threaded_context we need to support replace_buffer_storage, in
62bf215546Sopenharmony_ci * which case we can end up in transfer_map with tres->latest, but other
63bf215546Sopenharmony_ci * pipe_context APIs using the original prsc pointer.  This allows TC to
64bf215546Sopenharmony_ci * not have to synchronize the front-end thread with the buffer storage
65bf215546Sopenharmony_ci * replacement called on driver thread.  But it complicates the batch/
66bf215546Sopenharmony_ci * resource tracking.
67bf215546Sopenharmony_ci *
68bf215546Sopenharmony_ci * To handle this, we need to split the tracking out into it's own ref-
69bf215546Sopenharmony_ci * counted structure, so as needed both "versions" of the resource can
70bf215546Sopenharmony_ci * point to the same tracking.
71bf215546Sopenharmony_ci *
72bf215546Sopenharmony_ci * We could *almost* just push this down to fd_bo, except for a3xx/a4xx
73bf215546Sopenharmony_ci * hw queries, where we don't know up-front the size to allocate for
74bf215546Sopenharmony_ci * per-tile query results.
75bf215546Sopenharmony_ci */
76bf215546Sopenharmony_cistruct fd_resource_tracking {
77bf215546Sopenharmony_ci   struct pipe_reference reference;
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci   /* bitmask of in-flight batches which reference this resource.  Note
80bf215546Sopenharmony_ci    * that the batch doesn't hold reference to resources (but instead
81bf215546Sopenharmony_ci    * the fd_ringbuffer holds refs to the underlying fd_bo), but in case
82bf215546Sopenharmony_ci    * the resource is destroyed we need to clean up the batch's weak
83bf215546Sopenharmony_ci    * references to us.
84bf215546Sopenharmony_ci    */
85bf215546Sopenharmony_ci   uint32_t batch_mask;
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci   /* reference to batch that writes this resource: */
88bf215546Sopenharmony_ci   struct fd_batch *write_batch;
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci   /* Set of batches whose batch-cache key references this resource.
91bf215546Sopenharmony_ci    * We need to track this to know which batch-cache entries to
92bf215546Sopenharmony_ci    * invalidate if, for example, the resource is invalidated or
93bf215546Sopenharmony_ci    * shadowed.
94bf215546Sopenharmony_ci    */
95bf215546Sopenharmony_ci   uint32_t bc_batch_mask;
96bf215546Sopenharmony_ci};
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_civoid __fd_resource_tracking_destroy(struct fd_resource_tracking *track);
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_cistatic inline void
101bf215546Sopenharmony_cifd_resource_tracking_reference(struct fd_resource_tracking **ptr,
102bf215546Sopenharmony_ci                               struct fd_resource_tracking *track)
103bf215546Sopenharmony_ci{
104bf215546Sopenharmony_ci   struct fd_resource_tracking *old_track = *ptr;
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   if (pipe_reference(&(*ptr)->reference, &track->reference)) {
107bf215546Sopenharmony_ci      assert(!old_track->write_batch);
108bf215546Sopenharmony_ci      free(old_track);
109bf215546Sopenharmony_ci   }
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_ci   *ptr = track;
112bf215546Sopenharmony_ci}
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci/**
115bf215546Sopenharmony_ci * A resource (any buffer/texture/image/etc)
116bf215546Sopenharmony_ci */
117bf215546Sopenharmony_cistruct fd_resource {
118bf215546Sopenharmony_ci   struct threaded_resource b;
119bf215546Sopenharmony_ci   struct fd_bo *bo; /* use fd_resource_set_bo() to write */
120bf215546Sopenharmony_ci   enum pipe_format internal_format;
121bf215546Sopenharmony_ci   uint32_t hash; /* _mesa_hash_pointer() on this resource's address. */
122bf215546Sopenharmony_ci   struct fdl_layout layout;
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci   /* buffer range that has been initialized */
125bf215546Sopenharmony_ci   struct util_range valid_buffer_range;
126bf215546Sopenharmony_ci   bool valid;
127bf215546Sopenharmony_ci   struct renderonly_scanout *scanout;
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci   /* reference to the resource holding stencil data for a z32_s8 texture */
130bf215546Sopenharmony_ci   /* TODO rename to secondary or auxiliary? */
131bf215546Sopenharmony_ci   struct fd_resource *stencil;
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci   struct fd_resource_tracking *track;
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci   simple_mtx_t lock;
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci   /* bitmask of state this resource could potentially dirty when rebound,
138bf215546Sopenharmony_ci    * see rebind_resource()
139bf215546Sopenharmony_ci    */
140bf215546Sopenharmony_ci   enum fd_dirty_3d_state dirty;
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci   /* Sequence # incremented each time bo changes: */
143bf215546Sopenharmony_ci   uint16_t seqno;
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci   /* Is this buffer a replacement created by threaded_context to avoid
146bf215546Sopenharmony_ci    * a stall in PIPE_MAP_DISCARD_WHOLE_RESOURCE|PIPE_MAP_WRITE case?
147bf215546Sopenharmony_ci    * If so, it no longer "owns" it's rsc->track, and so should not
148bf215546Sopenharmony_ci    * invalidate when the rsc is destroyed.
149bf215546Sopenharmony_ci    */
150bf215546Sopenharmony_ci   bool is_replacement : 1;
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci   /* Uninitialized resources with UBWC format need their UBWC flag data
153bf215546Sopenharmony_ci    * cleared before writes, as the UBWC state is read and used during
154bf215546Sopenharmony_ci    * writes, so undefined UBWC flag data results in undefined results.
155bf215546Sopenharmony_ci    */
156bf215546Sopenharmony_ci   bool needs_ubwc_clear : 1;
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_ci   /*
159bf215546Sopenharmony_ci    * LRZ
160bf215546Sopenharmony_ci    *
161bf215546Sopenharmony_ci    * TODO lrz width/height/pitch should probably also move to
162bf215546Sopenharmony_ci    * fdl_layout
163bf215546Sopenharmony_ci    */
164bf215546Sopenharmony_ci   bool lrz_valid : 1;
165bf215546Sopenharmony_ci   enum fd_lrz_direction lrz_direction : 2;
166bf215546Sopenharmony_ci   uint16_t lrz_width; // for lrz clear, does this differ from lrz_pitch?
167bf215546Sopenharmony_ci   uint16_t lrz_height;
168bf215546Sopenharmony_ci   uint16_t lrz_pitch;
169bf215546Sopenharmony_ci   struct fd_bo *lrz;
170bf215546Sopenharmony_ci};
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_cistruct fd_memory_object {
173bf215546Sopenharmony_ci   struct pipe_memory_object b;
174bf215546Sopenharmony_ci   struct fd_bo *bo;
175bf215546Sopenharmony_ci};
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_cistatic inline struct fd_resource *
178bf215546Sopenharmony_cifd_resource(struct pipe_resource *ptex)
179bf215546Sopenharmony_ci{
180bf215546Sopenharmony_ci   return (struct fd_resource *)ptex;
181bf215546Sopenharmony_ci}
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_cistatic inline const struct fd_resource *
184bf215546Sopenharmony_cifd_resource_const(const struct pipe_resource *ptex)
185bf215546Sopenharmony_ci{
186bf215546Sopenharmony_ci   return (const struct fd_resource *)ptex;
187bf215546Sopenharmony_ci}
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_cistatic inline struct fd_memory_object *
190bf215546Sopenharmony_cifd_memory_object(struct pipe_memory_object *pmemobj)
191bf215546Sopenharmony_ci{
192bf215546Sopenharmony_ci   return (struct fd_memory_object *)pmemobj;
193bf215546Sopenharmony_ci}
194bf215546Sopenharmony_ci
195bf215546Sopenharmony_cistatic inline bool
196bf215546Sopenharmony_cipending(struct fd_resource *rsc, bool write)
197bf215546Sopenharmony_ci{
198bf215546Sopenharmony_ci   /* if we have a pending GPU write, we are busy in any case: */
199bf215546Sopenharmony_ci   if (rsc->track->write_batch)
200bf215546Sopenharmony_ci      return true;
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci   /* if CPU wants to write, but we are pending a GPU read, we are busy: */
203bf215546Sopenharmony_ci   if (write && rsc->track->batch_mask)
204bf215546Sopenharmony_ci      return true;
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ci   if (rsc->stencil && pending(rsc->stencil, write))
207bf215546Sopenharmony_ci      return true;
208bf215546Sopenharmony_ci
209bf215546Sopenharmony_ci   return false;
210bf215546Sopenharmony_ci}
211bf215546Sopenharmony_ci
212bf215546Sopenharmony_cistatic inline bool
213bf215546Sopenharmony_ciresource_busy(struct fd_resource *rsc, unsigned op)
214bf215546Sopenharmony_ci{
215bf215546Sopenharmony_ci   return fd_bo_cpu_prep(rsc->bo, NULL, op | FD_BO_PREP_NOSYNC) != 0;
216bf215546Sopenharmony_ci}
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_ciint __fd_resource_wait(struct fd_context *ctx, struct fd_resource *rsc,
219bf215546Sopenharmony_ci                       unsigned op, const char *func);
220bf215546Sopenharmony_ci#define fd_resource_wait(ctx, rsc, op)                                         \
221bf215546Sopenharmony_ci   __fd_resource_wait(ctx, rsc, op, __func__)
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_cistatic inline void
224bf215546Sopenharmony_cifd_resource_lock(struct fd_resource *rsc)
225bf215546Sopenharmony_ci{
226bf215546Sopenharmony_ci   simple_mtx_lock(&rsc->lock);
227bf215546Sopenharmony_ci}
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_cistatic inline void
230bf215546Sopenharmony_cifd_resource_unlock(struct fd_resource *rsc)
231bf215546Sopenharmony_ci{
232bf215546Sopenharmony_ci   simple_mtx_unlock(&rsc->lock);
233bf215546Sopenharmony_ci}
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_cistatic inline void
236bf215546Sopenharmony_cifd_resource_set_usage(struct pipe_resource *prsc, enum fd_dirty_3d_state usage)
237bf215546Sopenharmony_ci{
238bf215546Sopenharmony_ci   if (!prsc)
239bf215546Sopenharmony_ci      return;
240bf215546Sopenharmony_ci   struct fd_resource *rsc = fd_resource(prsc);
241bf215546Sopenharmony_ci   /* Bits are only ever ORed in, and we expect many set_usage() per
242bf215546Sopenharmony_ci    * resource, so do the quick check outside of the lock.
243bf215546Sopenharmony_ci    */
244bf215546Sopenharmony_ci   if (likely(rsc->dirty & usage))
245bf215546Sopenharmony_ci      return;
246bf215546Sopenharmony_ci   fd_resource_lock(rsc);
247bf215546Sopenharmony_ci   or_mask(rsc->dirty, usage);
248bf215546Sopenharmony_ci   fd_resource_unlock(rsc);
249bf215546Sopenharmony_ci}
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_cistatic inline bool
252bf215546Sopenharmony_cihas_depth(enum pipe_format format)
253bf215546Sopenharmony_ci{
254bf215546Sopenharmony_ci   const struct util_format_description *desc = util_format_description(format);
255bf215546Sopenharmony_ci   return util_format_has_depth(desc);
256bf215546Sopenharmony_ci}
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_cistruct fd_transfer {
259bf215546Sopenharmony_ci   struct threaded_transfer b;
260bf215546Sopenharmony_ci   struct pipe_resource *staging_prsc;
261bf215546Sopenharmony_ci   struct pipe_box staging_box;
262bf215546Sopenharmony_ci};
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_cistatic inline struct fd_transfer *
265bf215546Sopenharmony_cifd_transfer(struct pipe_transfer *ptrans)
266bf215546Sopenharmony_ci{
267bf215546Sopenharmony_ci   return (struct fd_transfer *)ptrans;
268bf215546Sopenharmony_ci}
269bf215546Sopenharmony_ci
270bf215546Sopenharmony_cistatic inline struct fdl_slice *
271bf215546Sopenharmony_cifd_resource_slice(struct fd_resource *rsc, unsigned level)
272bf215546Sopenharmony_ci{
273bf215546Sopenharmony_ci   assert(level <= rsc->b.b.last_level);
274bf215546Sopenharmony_ci   return &rsc->layout.slices[level];
275bf215546Sopenharmony_ci}
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_cistatic inline uint32_t
278bf215546Sopenharmony_cifd_resource_layer_stride(struct fd_resource *rsc, unsigned level)
279bf215546Sopenharmony_ci{
280bf215546Sopenharmony_ci   return fdl_layer_stride(&rsc->layout, level);
281bf215546Sopenharmony_ci}
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci/* get pitch (in bytes) for specified mipmap level */
284bf215546Sopenharmony_cistatic inline uint32_t
285bf215546Sopenharmony_cifd_resource_pitch(struct fd_resource *rsc, unsigned level)
286bf215546Sopenharmony_ci{
287bf215546Sopenharmony_ci   if (is_a2xx(fd_screen(rsc->b.b.screen)))
288bf215546Sopenharmony_ci      return fdl2_pitch(&rsc->layout, level);
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   return fdl_pitch(&rsc->layout, level);
291bf215546Sopenharmony_ci}
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci/* get offset for specified mipmap level and texture/array layer */
294bf215546Sopenharmony_cistatic inline uint32_t
295bf215546Sopenharmony_cifd_resource_offset(struct fd_resource *rsc, unsigned level, unsigned layer)
296bf215546Sopenharmony_ci{
297bf215546Sopenharmony_ci   uint32_t offset = fdl_surface_offset(&rsc->layout, level, layer);
298bf215546Sopenharmony_ci   assert(offset < fd_bo_size(rsc->bo));
299bf215546Sopenharmony_ci   return offset;
300bf215546Sopenharmony_ci}
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_cistatic inline uint32_t
303bf215546Sopenharmony_cifd_resource_ubwc_offset(struct fd_resource *rsc, unsigned level, unsigned layer)
304bf215546Sopenharmony_ci{
305bf215546Sopenharmony_ci   uint32_t offset = fdl_ubwc_offset(&rsc->layout, level, layer);
306bf215546Sopenharmony_ci   assert(offset < fd_bo_size(rsc->bo));
307bf215546Sopenharmony_ci   return offset;
308bf215546Sopenharmony_ci}
309bf215546Sopenharmony_ci
310bf215546Sopenharmony_ci/* This might be a5xx specific, but higher mipmap levels are always linear: */
311bf215546Sopenharmony_cistatic inline bool
312bf215546Sopenharmony_cifd_resource_level_linear(const struct pipe_resource *prsc, int level)
313bf215546Sopenharmony_ci{
314bf215546Sopenharmony_ci   struct fd_screen *screen = fd_screen(prsc->screen);
315bf215546Sopenharmony_ci   assert(!is_a3xx(screen));
316bf215546Sopenharmony_ci
317bf215546Sopenharmony_ci   return fdl_level_linear(&fd_resource_const(prsc)->layout, level);
318bf215546Sopenharmony_ci}
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_cistatic inline uint32_t
321bf215546Sopenharmony_cifd_resource_tile_mode(struct pipe_resource *prsc, int level)
322bf215546Sopenharmony_ci{
323bf215546Sopenharmony_ci   return fdl_tile_mode(&fd_resource(prsc)->layout, level);
324bf215546Sopenharmony_ci}
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_cistatic inline const char *
327bf215546Sopenharmony_cifd_resource_tile_mode_desc(const struct fd_resource *rsc, int level)
328bf215546Sopenharmony_ci{
329bf215546Sopenharmony_ci   return fdl_tile_mode_desc(&rsc->layout, level);
330bf215546Sopenharmony_ci}
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_cistatic inline bool
333bf215546Sopenharmony_cifd_resource_ubwc_enabled(struct fd_resource *rsc, int level)
334bf215546Sopenharmony_ci{
335bf215546Sopenharmony_ci   return fdl_ubwc_enabled(&rsc->layout, level);
336bf215546Sopenharmony_ci}
337bf215546Sopenharmony_ci
338bf215546Sopenharmony_ci/* access # of samples, with 0 normalized to 1 (which is what we care about
339bf215546Sopenharmony_ci * most of the time)
340bf215546Sopenharmony_ci */
341bf215546Sopenharmony_cistatic inline unsigned
342bf215546Sopenharmony_cifd_resource_nr_samples(struct pipe_resource *prsc)
343bf215546Sopenharmony_ci{
344bf215546Sopenharmony_ci   return MAX2(1, prsc->nr_samples);
345bf215546Sopenharmony_ci}
346bf215546Sopenharmony_ci
347bf215546Sopenharmony_civoid fd_resource_screen_init(struct pipe_screen *pscreen);
348bf215546Sopenharmony_civoid fd_resource_context_init(struct pipe_context *pctx);
349bf215546Sopenharmony_ci
350bf215546Sopenharmony_ciuint32_t fd_setup_slices(struct fd_resource *rsc);
351bf215546Sopenharmony_civoid fd_resource_resize(struct pipe_resource *prsc, uint32_t sz);
352bf215546Sopenharmony_civoid fd_replace_buffer_storage(struct pipe_context *ctx,
353bf215546Sopenharmony_ci                               struct pipe_resource *dst,
354bf215546Sopenharmony_ci                               struct pipe_resource *src,
355bf215546Sopenharmony_ci                               unsigned num_rebinds,
356bf215546Sopenharmony_ci                               uint32_t rebind_mask,
357bf215546Sopenharmony_ci                               uint32_t delete_buffer_id) in_dt;
358bf215546Sopenharmony_cibool fd_resource_busy(struct pipe_screen *pscreen, struct pipe_resource *prsc,
359bf215546Sopenharmony_ci                      unsigned usage);
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_civoid fd_resource_uncompress(struct fd_context *ctx,
362bf215546Sopenharmony_ci                            struct fd_resource *rsc,
363bf215546Sopenharmony_ci                            bool linear) assert_dt;
364bf215546Sopenharmony_civoid fd_resource_dump(struct fd_resource *rsc, const char *name);
365bf215546Sopenharmony_ci
366bf215546Sopenharmony_cibool fd_render_condition_check(struct pipe_context *pctx) assert_dt;
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_cistatic inline bool
369bf215546Sopenharmony_cifd_batch_references_resource(struct fd_batch *batch, struct fd_resource *rsc)
370bf215546Sopenharmony_ci{
371bf215546Sopenharmony_ci   return rsc->track->batch_mask & (1 << batch->idx);
372bf215546Sopenharmony_ci}
373bf215546Sopenharmony_ci
374bf215546Sopenharmony_cistatic inline void
375bf215546Sopenharmony_cifd_batch_write_prep(struct fd_batch *batch, struct fd_resource *rsc) assert_dt
376bf215546Sopenharmony_ci{
377bf215546Sopenharmony_ci   if (unlikely(rsc->needs_ubwc_clear)) {
378bf215546Sopenharmony_ci      batch->ctx->clear_ubwc(batch, rsc);
379bf215546Sopenharmony_ci      rsc->needs_ubwc_clear = false;
380bf215546Sopenharmony_ci   }
381bf215546Sopenharmony_ci}
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_cistatic inline void
384bf215546Sopenharmony_cifd_batch_resource_read(struct fd_batch *batch,
385bf215546Sopenharmony_ci                       struct fd_resource *rsc) assert_dt
386bf215546Sopenharmony_ci{
387bf215546Sopenharmony_ci   /* Fast path: if we hit this then we know we don't have anyone else
388bf215546Sopenharmony_ci    * writing to it (since both _write and _read flush other writers), and
389bf215546Sopenharmony_ci    * that we've already recursed for stencil.
390bf215546Sopenharmony_ci    */
391bf215546Sopenharmony_ci   if (unlikely(!fd_batch_references_resource(batch, rsc)))
392bf215546Sopenharmony_ci      fd_batch_resource_read_slowpath(batch, rsc);
393bf215546Sopenharmony_ci}
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_cistatic inline enum fdl_view_type
396bf215546Sopenharmony_cifdl_type_from_pipe_target(enum pipe_texture_target target) {
397bf215546Sopenharmony_ci   switch (target) {
398bf215546Sopenharmony_ci   case PIPE_TEXTURE_1D:
399bf215546Sopenharmony_ci   case PIPE_TEXTURE_1D_ARRAY:
400bf215546Sopenharmony_ci      return FDL_VIEW_TYPE_1D;
401bf215546Sopenharmony_ci   case PIPE_TEXTURE_2D:
402bf215546Sopenharmony_ci   case PIPE_TEXTURE_RECT:
403bf215546Sopenharmony_ci   case PIPE_TEXTURE_2D_ARRAY:
404bf215546Sopenharmony_ci      return FDL_VIEW_TYPE_2D;
405bf215546Sopenharmony_ci   case PIPE_TEXTURE_CUBE:
406bf215546Sopenharmony_ci   case PIPE_TEXTURE_CUBE_ARRAY:
407bf215546Sopenharmony_ci      return FDL_VIEW_TYPE_CUBE;
408bf215546Sopenharmony_ci   case PIPE_TEXTURE_3D:
409bf215546Sopenharmony_ci      return FDL_VIEW_TYPE_3D;
410bf215546Sopenharmony_ci   case PIPE_MAX_TEXTURE_TYPES:
411bf215546Sopenharmony_ci   default:
412bf215546Sopenharmony_ci      unreachable("bad texture type");
413bf215546Sopenharmony_ci   }
414bf215546Sopenharmony_ci}
415bf215546Sopenharmony_ci
416bf215546Sopenharmony_ci#endif /* FREEDRENO_RESOURCE_H_ */
417