1 /**************************************************************************
2 *
3 * Copyright 2019 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
29 /*
30 * Miscellantous state tracker utility functions, macros.
31 */
32
33
34 #ifndef ST_UTIL
35 #define ST_UTIL
36
37
38 #include "state_tracker/st_context.h"
39 #include "main/context.h"
40
41
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45
46
47 /** For drawing quads for glClear, glDraw/CopyPixels, glBitmap, etc. */
48 struct st_util_vertex
49 {
50 float x, y, z;
51 float r, g, b, a;
52 float s, t;
53 };
54
55
56
57 /* Invalidate the readpixels cache to ensure we don't read stale data.
58 */
59 static inline void
st_invalidate_readpix_cache(struct st_context * st)60 st_invalidate_readpix_cache(struct st_context *st)
61 {
62 if (unlikely(st->readpix_cache.src)) {
63 pipe_resource_reference(&st->readpix_cache.src, NULL);
64 pipe_resource_reference(&st->readpix_cache.cache, NULL);
65 }
66 }
67
68 static inline bool
st_user_clip_planes_enabled(struct gl_context * ctx)69 st_user_clip_planes_enabled(struct gl_context *ctx)
70 {
71 return (_mesa_is_desktop_gl_compat(ctx) ||
72 _mesa_is_gles1(ctx)) && /* only ES 1.x */
73 ctx->Transform.ClipPlanesEnabled;
74 }
75
76 static inline bool
st_point_size_per_vertex(struct gl_context * ctx)77 st_point_size_per_vertex(struct gl_context *ctx)
78 {
79 const struct gl_program *vertProg = ctx->VertexProgram._Current;
80 if (vertProg) {
81 if (vertProg->Id == 0) {
82 if (vertProg->info.outputs_written &
83 BITFIELD64_BIT(VARYING_SLOT_PSIZ)) {
84 /* generated program which emits point size */
85 return true;
86 }
87 }
88 else if (ctx->API != API_OPENGLES2) {
89 /* PointSizeEnabled is always set in ES2 contexts */
90 return ctx->VertexProgram.PointSizeEnabled;
91 }
92 else {
93 /* ST_NEW_TESSEVAL_PROGRAM | ST_NEW_GEOMETRY_PROGRAM */
94 /* We have to check the last bound stage and see if it writes psize */
95 struct gl_program *last = NULL;
96 if (ctx->GeometryProgram._Current)
97 last = ctx->GeometryProgram._Current;
98 else if (ctx->TessEvalProgram._Current)
99 last = ctx->TessEvalProgram._Current;
100 else if (ctx->VertexProgram._Current)
101 last = ctx->VertexProgram._Current;
102 if (last)
103 return !!(last->info.outputs_written &
104 BITFIELD64_BIT(VARYING_SLOT_PSIZ));
105 }
106 }
107 return false;
108 }
109
110 static inline void
st_validate_state(struct st_context * st,uint64_t pipeline_state_mask)111 st_validate_state(struct st_context *st, uint64_t pipeline_state_mask)
112 {
113 struct gl_context *ctx = st->ctx;
114
115 /* Inactive states are shader states not used by shaders at the moment. */
116 uint64_t dirty = ctx->NewDriverState & st->active_states & pipeline_state_mask;
117
118 if (dirty) {
119 ctx->NewDriverState &= ~dirty;
120
121 /* Execute functions that set states that have been changed since
122 * the last draw.
123 *
124 * x86_64: u_bit_scan64 is negligibly faster than u_bit_scan
125 * i386: u_bit_scan64 is noticably slower than u_bit_scan
126 */
127 st_update_func_t *update_state = st->update_functions;
128
129 if (sizeof(void*) == 8) {
130 while (dirty)
131 update_state[u_bit_scan64(&dirty)](st);
132 } else {
133 /* Split u_bit_scan64 into 2x u_bit_scan32 for i386. */
134 uint32_t dirty_lo = dirty;
135 uint32_t dirty_hi = dirty >> 32;
136
137 while (dirty_lo)
138 update_state[u_bit_scan(&dirty_lo)](st);
139 while (dirty_hi)
140 update_state[32 + u_bit_scan(&dirty_hi)](st);
141 }
142 }
143 }
144
145 #ifdef __cplusplus
146 }
147 #endif
148
149
150 #endif /* ST_UTIL */
151