xref: /aosp_15_r20/external/virglrenderer/src/gallium/auxiliary/util/u_inlines.h (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1 /**************************************************************************
2  *
3  * Copyright 2007 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #ifndef U_INLINES_H
29 #define U_INLINES_H
30 
31 #include "pipe/p_defines.h"
32 #include "pipe/p_shader_tokens.h"
33 #include "pipe/p_state.h"
34 #include "util/u_debug.h"
35 #include "util/u_debug_describe.h"
36 #include "util/u_debug_refcnt.h"
37 #include "util/u_atomic.h"
38 #include "util/u_math.h"
39 
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 
46 /*
47  * Reference counting helper functions.
48  */
49 
50 
51 static inline void
pipe_reference_init(struct pipe_reference * reference,unsigned count)52 pipe_reference_init(struct pipe_reference *reference, unsigned count)
53 {
54    p_atomic_set(&reference->count, count);
55 }
56 
57 static inline boolean
pipe_is_referenced(struct pipe_reference * reference)58 pipe_is_referenced(struct pipe_reference *reference)
59 {
60    return p_atomic_read(&reference->count) != 0;
61 }
62 
63 /**
64  * Update reference counting.
65  * The old thing pointed to, if any, will be unreferenced.
66  * Both 'ptr' and 'reference' may be NULL.
67  * \return TRUE if the object's refcount hits zero and should be destroyed.
68  */
69 static inline boolean
pipe_reference_described(struct pipe_reference * ptr,struct pipe_reference * reference,debug_reference_descriptor get_desc)70 pipe_reference_described(struct pipe_reference *ptr,
71                          struct pipe_reference *reference,
72                          debug_reference_descriptor get_desc)
73 {
74    boolean destroy = FALSE;
75 
76    if(ptr != reference) {
77       /* bump the reference.count first */
78       if (reference) {
79          assert(pipe_is_referenced(reference));
80          p_atomic_inc(&reference->count);
81          debug_reference(reference, get_desc, 1);
82       }
83 
84       if (ptr) {
85          assert(pipe_is_referenced(ptr));
86          if (p_atomic_dec_zero(&ptr->count)) {
87             destroy = TRUE;
88          }
89          debug_reference(ptr, get_desc, -1);
90       }
91    }
92 
93    return destroy;
94 }
95 
96 static inline boolean
pipe_reference(struct pipe_reference * ptr,struct pipe_reference * reference)97 pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
98 {
99    return pipe_reference_described(ptr, reference,
100                                    (debug_reference_descriptor)debug_describe_reference);
101 }
102 
103 /* Return true if the surfaces are equal. */
104 static inline boolean
pipe_surface_equal(struct pipe_surface * s1,struct pipe_surface * s2)105 pipe_surface_equal(struct pipe_surface *s1, struct pipe_surface *s2)
106 {
107    return s1->texture == s2->texture &&
108           s1->format == s2->format &&
109           (s1->texture->target != PIPE_BUFFER ||
110            (s1->u.buf.first_element == s2->u.buf.first_element &&
111             s1->u.buf.last_element == s2->u.buf.last_element)) &&
112           (s1->texture->target == PIPE_BUFFER ||
113            (s1->u.tex.level == s2->u.tex.level &&
114             s1->u.tex.first_layer == s2->u.tex.first_layer &&
115             s1->u.tex.last_layer == s2->u.tex.last_layer));
116 }
117 
118 /**
119  * Get the polygon offset enable/disable flag for the given polygon fill mode.
120  * \param fill_mode  one of PIPE_POLYGON_MODE_POINT/LINE/FILL
121  */
122 static inline boolean
util_get_offset(const struct pipe_rasterizer_state * templ,unsigned fill_mode)123 util_get_offset(const struct pipe_rasterizer_state *templ,
124                 unsigned fill_mode)
125 {
126    switch(fill_mode) {
127    case PIPE_POLYGON_MODE_POINT:
128       return templ->offset_point;
129    case PIPE_POLYGON_MODE_LINE:
130       return templ->offset_line;
131    case PIPE_POLYGON_MODE_FILL:
132       return templ->offset_tri;
133    default:
134       assert(0);
135       return FALSE;
136    }
137 }
138 
139 static inline float
util_get_min_point_size(const struct pipe_rasterizer_state * state)140 util_get_min_point_size(const struct pipe_rasterizer_state *state)
141 {
142    /* The point size should be clamped to this value at the rasterizer stage.
143     */
144    return !state->point_quad_rasterization &&
145           !state->point_smooth &&
146           !state->multisample ? 1.0f : 0.0f;
147 }
148 
149 static inline void
util_query_clear_result(union pipe_query_result * result,unsigned type)150 util_query_clear_result(union pipe_query_result *result, unsigned type)
151 {
152    switch (type) {
153    case PIPE_QUERY_OCCLUSION_PREDICATE:
154    case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
155    case PIPE_QUERY_GPU_FINISHED:
156       result->b = FALSE;
157       break;
158    case PIPE_QUERY_OCCLUSION_COUNTER:
159    case PIPE_QUERY_TIMESTAMP:
160    case PIPE_QUERY_TIME_ELAPSED:
161    case PIPE_QUERY_PRIMITIVES_GENERATED:
162    case PIPE_QUERY_PRIMITIVES_EMITTED:
163       result->u64 = 0;
164       break;
165    case PIPE_QUERY_SO_STATISTICS:
166       memset(&result->so_statistics, 0, sizeof(result->so_statistics));
167       break;
168    case PIPE_QUERY_TIMESTAMP_DISJOINT:
169       memset(&result->timestamp_disjoint, 0, sizeof(result->timestamp_disjoint));
170       break;
171    case PIPE_QUERY_PIPELINE_STATISTICS:
172       memset(&result->pipeline_statistics, 0, sizeof(result->pipeline_statistics));
173       break;
174    default:
175       memset(result, 0, sizeof(*result));
176    }
177 }
178 
179 /** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */
180 static inline unsigned
util_pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target,unsigned nr_samples)181 util_pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target,
182                           unsigned nr_samples)
183 {
184    switch (pipe_tex_target) {
185    case PIPE_TEXTURE_1D:
186       assert(nr_samples <= 1);
187       return TGSI_TEXTURE_1D;
188 
189    case PIPE_TEXTURE_2D:
190       return nr_samples > 1 ? TGSI_TEXTURE_2D_MSAA : TGSI_TEXTURE_2D;
191 
192    case PIPE_TEXTURE_RECT:
193       assert(nr_samples <= 1);
194       return TGSI_TEXTURE_RECT;
195 
196    case PIPE_TEXTURE_3D:
197       assert(nr_samples <= 1);
198       return TGSI_TEXTURE_3D;
199 
200    case PIPE_TEXTURE_CUBE:
201       assert(nr_samples <= 1);
202       return TGSI_TEXTURE_CUBE;
203 
204    case PIPE_TEXTURE_1D_ARRAY:
205       assert(nr_samples <= 1);
206       return TGSI_TEXTURE_1D_ARRAY;
207 
208    case PIPE_TEXTURE_2D_ARRAY:
209       return nr_samples > 1 ? TGSI_TEXTURE_2D_ARRAY_MSAA :
210                               TGSI_TEXTURE_2D_ARRAY;
211 
212    case PIPE_TEXTURE_CUBE_ARRAY:
213       return TGSI_TEXTURE_CUBE_ARRAY;
214 
215    default:
216       assert(0 && "unexpected texture target");
217       return TGSI_TEXTURE_UNKNOWN;
218    }
219 }
220 
221 
222 static inline unsigned
util_max_layer(const struct pipe_resource * r,unsigned level)223 util_max_layer(const struct pipe_resource *r, unsigned level)
224 {
225    switch (r->target) {
226    case PIPE_TEXTURE_CUBE:
227       return 6 - 1;
228    case PIPE_TEXTURE_3D:
229       return u_minify(r->depth0, level) - 1;
230    case PIPE_TEXTURE_1D_ARRAY:
231    case PIPE_TEXTURE_2D_ARRAY:
232    case PIPE_TEXTURE_CUBE_ARRAY:
233       return r->array_size - 1;
234    default:
235       return 0;
236    }
237 }
238 
239 #ifdef __cplusplus
240 }
241 #endif
242 
243 #endif /* U_INLINES_H */
244