xref: /aosp_15_r20/external/mesa3d/src/mesa/main/glthread_marshal.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2012 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 /** \file glthread_marshal.h
25  *
26  * Declarations of functions related to marshalling GL calls from a client
27  * thread to a server thread.
28  */
29 
30 #ifndef MARSHAL_H
31 #define MARSHAL_H
32 
33 #include "main/glthread.h"
34 #include "main/context.h"
35 #include "main/macros.h"
36 #include "main/matrix.h"
37 
38 /* 32-bit signed integer clamped to 0..UINT16_MAX to compress parameters
39  * for glthread. All values < 0 and >= UINT16_MAX are expected to throw
40  * GL_INVALID_VALUE. Negative values are mapped to UINT16_MAX.
41  */
42 typedef uint16_t GLpacked16i;
43 
44 /* 32-bit signed integer clamped to 16 bits. */
45 typedef int16_t GLclamped16i;
46 
47 struct marshal_cmd_base
48 {
49    /**
50     * Type of command.  See enum marshal_dispatch_cmd_id.
51     */
52    uint16_t cmd_id;
53 };
54 
55 /* This must be included after "struct marshal_cmd_base" because it uses it. */
56 #include "marshal_generated.h"
57 
58 typedef uint32_t (*_mesa_unmarshal_func)(struct gl_context *ctx,
59                                          const void *restrict cmd);
60 extern const _mesa_unmarshal_func _mesa_unmarshal_dispatch[NUM_DISPATCH_CMD];
61 extern const char *_mesa_unmarshal_func_name[NUM_DISPATCH_CMD];
62 
63 struct marshal_cmd_DrawElementsUserBuf
64 {
65    struct marshal_cmd_base cmd_base;
66    GLenum8 mode;
67    GLindextype type;
68    uint16_t num_slots;
69    GLsizei count;
70    GLsizei instance_count;
71    GLint basevertex;
72    GLuint baseinstance;
73    GLuint drawid;
74    GLuint user_buffer_mask;
75    const GLvoid *indices;
76    struct gl_buffer_object *index_buffer;
77 };
78 
79 struct marshal_cmd_DrawElementsUserBufPacked
80 {
81    struct marshal_cmd_base cmd_base;
82    GLenum8 mode;
83    GLindextype type;
84    uint16_t num_slots;
85    GLushort count;
86    GLuint user_buffer_mask;
87    GLuint indices;
88    struct gl_buffer_object *index_buffer;
89 };
90 
91 static inline void *
_mesa_glthread_allocate_command(struct gl_context * ctx,uint16_t cmd_id,unsigned size)92 _mesa_glthread_allocate_command(struct gl_context *ctx,
93                                 uint16_t cmd_id,
94                                 unsigned size)
95 {
96    struct glthread_state *glthread = &ctx->GLThread;
97    const unsigned num_elements = align(size, 8) / 8;
98 
99    assert (num_elements <= MARSHAL_MAX_CMD_SIZE / 8);
100 
101    if (unlikely(glthread->used + num_elements > MARSHAL_MAX_CMD_SIZE / 8))
102       _mesa_glthread_flush_batch(ctx);
103 
104    struct glthread_batch *next = glthread->next_batch;
105    struct marshal_cmd_base *cmd_base =
106       (struct marshal_cmd_base *)&next->buffer[glthread->used];
107    glthread->used += num_elements;
108    cmd_base->cmd_id = cmd_id;
109    return cmd_base;
110 }
111 
112 static inline GLenum
_mesa_decode_index_type(GLindextype type)113 _mesa_decode_index_type(GLindextype type)
114 {
115    return (GLenum)type.value + GL_UNSIGNED_BYTE - 1;
116 }
117 
118 static inline struct marshal_cmd_base *
_mesa_glthread_get_cmd(uint64_t * opaque_cmd)119 _mesa_glthread_get_cmd(uint64_t *opaque_cmd)
120 {
121    return (struct marshal_cmd_base*)opaque_cmd;
122 }
123 
124 static inline uint64_t *
_mesa_glthread_next_cmd(uint64_t * opaque_cmd,unsigned cmd_size)125 _mesa_glthread_next_cmd(uint64_t *opaque_cmd, unsigned cmd_size)
126 {
127    return opaque_cmd + cmd_size;
128 }
129 
130 static inline bool
_mesa_glthread_call_is_last(struct glthread_state * glthread,struct marshal_cmd_base * last,uint16_t num_slots)131 _mesa_glthread_call_is_last(struct glthread_state *glthread,
132                             struct marshal_cmd_base *last, uint16_t num_slots)
133 {
134    return last &&
135           (uint64_t*)last + num_slots ==
136           &glthread->next_batch->buffer[glthread->used];
137 }
138 
139 static inline bool
_mesa_glthread_has_pack_buffer(const struct gl_context * ctx)140 _mesa_glthread_has_pack_buffer(const struct gl_context *ctx)
141 {
142    return ctx->GLThread.CurrentPixelPackBufferName != 0;
143 }
144 
145 static inline bool
_mesa_glthread_has_unpack_buffer(const struct gl_context * ctx)146 _mesa_glthread_has_unpack_buffer(const struct gl_context *ctx)
147 {
148    return ctx->GLThread.CurrentPixelUnpackBufferName != 0;
149 }
150 
151 static inline unsigned
_mesa_buffer_enum_to_count(GLenum buffer)152 _mesa_buffer_enum_to_count(GLenum buffer)
153 {
154    switch (buffer) {
155    case GL_COLOR:
156       return 4;
157    case GL_DEPTH_STENCIL:
158       return 2;
159    case GL_STENCIL:
160    case GL_DEPTH:
161       return 1;
162    default:
163       return 0;
164    }
165 }
166 
167 static inline unsigned
_mesa_tex_param_enum_to_count(GLenum pname)168 _mesa_tex_param_enum_to_count(GLenum pname)
169 {
170    switch (pname) {
171    case GL_TEXTURE_MIN_FILTER:
172    case GL_TEXTURE_MAG_FILTER:
173    case GL_TEXTURE_WRAP_S:
174    case GL_TEXTURE_WRAP_T:
175    case GL_TEXTURE_WRAP_R:
176    case GL_TEXTURE_BASE_LEVEL:
177    case GL_TEXTURE_MAX_LEVEL:
178    case GL_GENERATE_MIPMAP_SGIS:
179    case GL_TEXTURE_COMPARE_MODE_ARB:
180    case GL_TEXTURE_COMPARE_FUNC_ARB:
181    case GL_DEPTH_TEXTURE_MODE_ARB:
182    case GL_DEPTH_STENCIL_TEXTURE_MODE:
183    case GL_TEXTURE_SRGB_DECODE_EXT:
184    case GL_TEXTURE_REDUCTION_MODE_EXT:
185    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
186    case GL_TEXTURE_SWIZZLE_R:
187    case GL_TEXTURE_SWIZZLE_G:
188    case GL_TEXTURE_SWIZZLE_B:
189    case GL_TEXTURE_SWIZZLE_A:
190    case GL_TEXTURE_MIN_LOD:
191    case GL_TEXTURE_MAX_LOD:
192    case GL_TEXTURE_PRIORITY:
193    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
194    case GL_TEXTURE_LOD_BIAS:
195    case GL_TEXTURE_TILING_EXT:
196    case GL_TEXTURE_SPARSE_ARB:
197    case GL_VIRTUAL_PAGE_SIZE_INDEX_ARB:
198    case GL_NUM_SPARSE_LEVELS_ARB:
199       return 1;
200    case GL_TEXTURE_CROP_RECT_OES:
201    case GL_TEXTURE_SWIZZLE_RGBA:
202    case GL_TEXTURE_BORDER_COLOR:
203       return 4;
204    default:
205       return 0;
206    }
207 }
208 
209 static inline unsigned
_mesa_fog_enum_to_count(GLenum pname)210 _mesa_fog_enum_to_count(GLenum pname)
211 {
212    switch (pname) {
213    case GL_FOG_MODE:
214    case GL_FOG_DENSITY:
215    case GL_FOG_START:
216    case GL_FOG_END:
217    case GL_FOG_INDEX:
218    case GL_FOG_COORDINATE_SOURCE_EXT:
219    case GL_FOG_DISTANCE_MODE_NV:
220       return 1;
221    case GL_FOG_COLOR:
222       return 4;
223    default:
224       return 0;
225    }
226 }
227 
228 static inline unsigned
_mesa_light_enum_to_count(GLenum pname)229 _mesa_light_enum_to_count(GLenum pname)
230 {
231    switch (pname) {
232    case GL_AMBIENT:
233    case GL_DIFFUSE:
234    case GL_SPECULAR:
235    case GL_POSITION:
236       return 4;
237    case GL_SPOT_DIRECTION:
238       return 3;
239    case GL_SPOT_EXPONENT:
240    case GL_SPOT_CUTOFF:
241    case GL_CONSTANT_ATTENUATION:
242    case GL_LINEAR_ATTENUATION:
243    case GL_QUADRATIC_ATTENUATION:
244       return 1;
245    default:
246       return 0;
247    }
248 }
249 
250 static inline unsigned
_mesa_light_model_enum_to_count(GLenum pname)251 _mesa_light_model_enum_to_count(GLenum pname)
252 {
253    switch (pname) {
254    case GL_LIGHT_MODEL_AMBIENT:
255       return 4;
256    case GL_LIGHT_MODEL_LOCAL_VIEWER:
257    case GL_LIGHT_MODEL_TWO_SIDE:
258    case GL_LIGHT_MODEL_COLOR_CONTROL:
259       return 1;
260    default:
261       return 0;
262    }
263 }
264 
265 static inline unsigned
_mesa_texenv_enum_to_count(GLenum pname)266 _mesa_texenv_enum_to_count(GLenum pname)
267 {
268    switch (pname) {
269    case GL_TEXTURE_ENV_MODE:
270    case GL_COMBINE_RGB:
271    case GL_COMBINE_ALPHA:
272    case GL_SOURCE0_RGB:
273    case GL_SOURCE1_RGB:
274    case GL_SOURCE2_RGB:
275    case GL_SOURCE3_RGB_NV:
276    case GL_SOURCE0_ALPHA:
277    case GL_SOURCE1_ALPHA:
278    case GL_SOURCE2_ALPHA:
279    case GL_SOURCE3_ALPHA_NV:
280    case GL_OPERAND0_RGB:
281    case GL_OPERAND1_RGB:
282    case GL_OPERAND2_RGB:
283    case GL_OPERAND3_RGB_NV:
284    case GL_OPERAND0_ALPHA:
285    case GL_OPERAND1_ALPHA:
286    case GL_OPERAND2_ALPHA:
287    case GL_OPERAND3_ALPHA_NV:
288    case GL_RGB_SCALE:
289    case GL_ALPHA_SCALE:
290    case GL_TEXTURE_LOD_BIAS_EXT:
291    case GL_COORD_REPLACE:
292       return 1;
293    case GL_TEXTURE_ENV_COLOR:
294       return 4;
295    default:
296       return 0;
297    }
298 }
299 
300 static inline unsigned
_mesa_texgen_enum_to_count(GLenum pname)301 _mesa_texgen_enum_to_count(GLenum pname)
302 {
303    switch (pname) {
304    case GL_TEXTURE_GEN_MODE:
305       return 1;
306    case GL_OBJECT_PLANE:
307    case GL_EYE_PLANE:
308       return 4;
309    default:
310       return 0;
311    }
312 }
313 
314 static inline unsigned
_mesa_material_enum_to_count(GLenum pname)315 _mesa_material_enum_to_count(GLenum pname)
316 {
317    switch (pname) {
318    case GL_EMISSION:
319    case GL_AMBIENT:
320    case GL_DIFFUSE:
321    case GL_SPECULAR:
322    case GL_AMBIENT_AND_DIFFUSE:
323       return 4;
324    case GL_COLOR_INDEXES:
325       return 3;
326    case GL_SHININESS:
327       return 1;
328    default:
329       return 0;
330    }
331 }
332 
333 static inline unsigned
_mesa_point_param_enum_to_count(GLenum pname)334 _mesa_point_param_enum_to_count(GLenum pname)
335 {
336    switch (pname) {
337    case GL_DISTANCE_ATTENUATION_EXT:
338       return 3;
339    case GL_POINT_SIZE_MIN_EXT:
340    case GL_POINT_SIZE_MAX_EXT:
341    case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
342    case GL_POINT_SPRITE_COORD_ORIGIN:
343       return 1;
344    default:
345       return 0;
346    }
347 }
348 
349 static inline unsigned
_mesa_calllists_enum_to_count(GLenum type)350 _mesa_calllists_enum_to_count(GLenum type)
351 {
352    switch (type) {
353    case GL_BYTE:
354    case GL_UNSIGNED_BYTE:
355       return 1;
356    case GL_SHORT:
357    case GL_UNSIGNED_SHORT:
358    case GL_2_BYTES:
359       return 2;
360    case GL_3_BYTES:
361       return 3;
362    case GL_INT:
363    case GL_UNSIGNED_INT:
364    case GL_FLOAT:
365    case GL_4_BYTES:
366       return 4;
367    default:
368       return 0;
369    }
370 }
371 
372 static inline unsigned
_mesa_patch_param_enum_to_count(GLenum pname)373 _mesa_patch_param_enum_to_count(GLenum pname)
374 {
375    switch (pname) {
376    case GL_PATCH_DEFAULT_OUTER_LEVEL:
377       return 4;
378    case GL_PATCH_DEFAULT_INNER_LEVEL:
379       return 2;
380    default:
381       return 0;
382    }
383 }
384 
385 static inline unsigned
_mesa_memobj_enum_to_count(GLenum pname)386 _mesa_memobj_enum_to_count(GLenum pname)
387 {
388    switch (pname) {
389    case GL_DEDICATED_MEMORY_OBJECT_EXT:
390       return 1;
391    default:
392       return 0;
393    }
394 }
395 
396 static inline unsigned
_mesa_semaphore_enum_to_count(GLenum pname)397 _mesa_semaphore_enum_to_count(GLenum pname)
398 {
399    switch (pname) {
400    /* EXT_semaphore and EXT_semaphore_fd define no parameters */
401    default:
402       return 0;
403    }
404 }
405 
406 static inline gl_vert_attrib
_mesa_array_to_attrib(struct gl_context * ctx,GLenum array)407 _mesa_array_to_attrib(struct gl_context *ctx, GLenum array)
408 {
409    switch (array) {
410    case GL_VERTEX_ARRAY:
411       return VERT_ATTRIB_POS;
412    case GL_NORMAL_ARRAY:
413       return VERT_ATTRIB_NORMAL;
414    case GL_COLOR_ARRAY:
415       return VERT_ATTRIB_COLOR0;
416    case GL_INDEX_ARRAY:
417       return VERT_ATTRIB_COLOR_INDEX;
418    case GL_TEXTURE_COORD_ARRAY:
419       return VERT_ATTRIB_TEX(ctx->GLThread.ClientActiveTexture);
420    case GL_EDGE_FLAG_ARRAY:
421       return VERT_ATTRIB_EDGEFLAG;
422    case GL_FOG_COORDINATE_ARRAY:
423       return VERT_ATTRIB_FOG;
424    case GL_SECONDARY_COLOR_ARRAY:
425       return VERT_ATTRIB_COLOR1;
426    case GL_POINT_SIZE_ARRAY_OES:
427       return VERT_ATTRIB_POINT_SIZE;
428    case GL_PRIMITIVE_RESTART_NV:
429       return VERT_ATTRIB_PRIMITIVE_RESTART_NV;
430    default:
431       if (array >= GL_TEXTURE0 && array <= GL_TEXTURE7)
432          return VERT_ATTRIB_TEX(array - GL_TEXTURE0);
433       return VERT_ATTRIB_MAX;
434    }
435 }
436 
437 static inline gl_matrix_index
_mesa_get_matrix_index(struct gl_context * ctx,GLenum mode)438 _mesa_get_matrix_index(struct gl_context *ctx, GLenum mode)
439 {
440    if (mode == GL_MODELVIEW || mode == GL_PROJECTION)
441       return M_MODELVIEW + (mode - GL_MODELVIEW);
442 
443    if (mode == GL_TEXTURE)
444       return M_TEXTURE0 + ctx->GLThread.ActiveTexture;
445 
446    if (mode >= GL_TEXTURE0 && mode <= GL_TEXTURE0 + MAX_TEXTURE_UNITS - 1)
447       return M_TEXTURE0 + (mode - GL_TEXTURE0);
448 
449    if (mode >= GL_MATRIX0_ARB && mode <= GL_MATRIX0_ARB + MAX_PROGRAM_MATRICES - 1)
450       return M_PROGRAM0 + (mode - GL_MATRIX0_ARB);
451 
452    return M_DUMMY;
453 }
454 
455 static inline void
_mesa_glthread_Enable(struct gl_context * ctx,GLenum cap)456 _mesa_glthread_Enable(struct gl_context *ctx, GLenum cap)
457 {
458    if (ctx->GLThread.ListMode == GL_COMPILE)
459       return;
460 
461    switch (cap) {
462    case GL_PRIMITIVE_RESTART:
463    case GL_PRIMITIVE_RESTART_FIXED_INDEX:
464       _mesa_glthread_set_prim_restart(ctx, cap, true);
465       break;
466    case GL_BLEND:
467       ctx->GLThread.Blend = true;
468       break;
469    case GL_DEBUG_OUTPUT_SYNCHRONOUS:
470       _mesa_glthread_disable(ctx);
471       ctx->GLThread.DebugOutputSynchronous = true;
472       break;
473    case GL_DEPTH_TEST:
474       ctx->GLThread.DepthTest = true;
475       break;
476    case GL_CULL_FACE:
477       ctx->GLThread.CullFace = true;
478       break;
479    case GL_LIGHTING:
480       ctx->GLThread.Lighting = true;
481       break;
482    case GL_POLYGON_STIPPLE:
483       ctx->GLThread.PolygonStipple = true;
484       break;
485    case GL_VERTEX_ARRAY:
486    case GL_NORMAL_ARRAY:
487    case GL_COLOR_ARRAY:
488    case GL_TEXTURE_COORD_ARRAY:
489    case GL_INDEX_ARRAY:
490    case GL_EDGE_FLAG_ARRAY:
491    case GL_FOG_COORDINATE_ARRAY:
492    case GL_SECONDARY_COLOR_ARRAY:
493    case GL_POINT_SIZE_ARRAY_OES:
494       _mesa_glthread_ClientState(ctx, NULL, _mesa_array_to_attrib(ctx, cap),
495                                  true);
496       break;
497    }
498 }
499 
500 static inline void
_mesa_glthread_Disable(struct gl_context * ctx,GLenum cap)501 _mesa_glthread_Disable(struct gl_context *ctx, GLenum cap)
502 {
503    if (ctx->GLThread.ListMode == GL_COMPILE)
504       return;
505 
506    switch (cap) {
507    case GL_PRIMITIVE_RESTART:
508    case GL_PRIMITIVE_RESTART_FIXED_INDEX:
509       _mesa_glthread_set_prim_restart(ctx, cap, false);
510       break;
511    case GL_BLEND:
512       ctx->GLThread.Blend = false;
513       break;
514    case GL_CULL_FACE:
515       ctx->GLThread.CullFace = false;
516       break;
517    case GL_DEBUG_OUTPUT_SYNCHRONOUS:
518       ctx->GLThread.DebugOutputSynchronous = false;
519       _mesa_glthread_enable(ctx);
520       break;
521    case GL_DEPTH_TEST:
522       ctx->GLThread.DepthTest = false;
523       break;
524    case GL_LIGHTING:
525       ctx->GLThread.Lighting = false;
526       break;
527    case GL_POLYGON_STIPPLE:
528       ctx->GLThread.PolygonStipple = false;
529       break;
530    case GL_VERTEX_ARRAY:
531    case GL_NORMAL_ARRAY:
532    case GL_COLOR_ARRAY:
533    case GL_TEXTURE_COORD_ARRAY:
534    case GL_INDEX_ARRAY:
535    case GL_EDGE_FLAG_ARRAY:
536    case GL_FOG_COORDINATE_ARRAY:
537    case GL_SECONDARY_COLOR_ARRAY:
538    case GL_POINT_SIZE_ARRAY_OES:
539       _mesa_glthread_ClientState(ctx, NULL, _mesa_array_to_attrib(ctx, cap),
540                                  false);
541       break;
542    }
543 }
544 
545 static inline int
_mesa_glthread_IsEnabled(struct gl_context * ctx,GLenum cap)546 _mesa_glthread_IsEnabled(struct gl_context *ctx, GLenum cap)
547 {
548    /* This will generate GL_INVALID_OPERATION, as it should. */
549    if (ctx->GLThread.inside_begin_end)
550       return -1;
551 
552    switch (cap) {
553    case GL_BLEND:
554       return ctx->GLThread.Blend;
555    case GL_CULL_FACE:
556       return ctx->GLThread.CullFace;
557    case GL_DEBUG_OUTPUT_SYNCHRONOUS:
558       return ctx->GLThread.DebugOutputSynchronous;
559    case GL_DEPTH_TEST:
560       return ctx->GLThread.DepthTest;
561    case GL_LIGHTING:
562       return ctx->GLThread.Lighting;
563    case GL_POLYGON_STIPPLE:
564       return ctx->GLThread.PolygonStipple;
565    case GL_VERTEX_ARRAY:
566       return !!(ctx->GLThread.CurrentVAO->UserEnabled & VERT_BIT_POS);
567    case GL_NORMAL_ARRAY:
568       return !!(ctx->GLThread.CurrentVAO->UserEnabled & VERT_BIT_NORMAL);
569    case GL_COLOR_ARRAY:
570       return !!(ctx->GLThread.CurrentVAO->UserEnabled & VERT_BIT_COLOR0);
571    case GL_TEXTURE_COORD_ARRAY:
572       return !!(ctx->GLThread.CurrentVAO->UserEnabled &
573                 (1 << VERT_ATTRIB_TEX(ctx->GLThread.ClientActiveTexture)));
574    default:
575       return -1; /* sync and call _mesa_IsEnabled. */
576    }
577 }
578 
579 static inline void
_mesa_glthread_PushAttrib(struct gl_context * ctx,GLbitfield mask)580 _mesa_glthread_PushAttrib(struct gl_context *ctx, GLbitfield mask)
581 {
582    if (ctx->GLThread.ListMode == GL_COMPILE)
583       return;
584 
585    if (ctx->GLThread.AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH)
586       return;
587 
588    struct glthread_attrib_node *attr =
589       &ctx->GLThread.AttribStack[ctx->GLThread.AttribStackDepth++];
590 
591    attr->Mask = mask;
592 
593    if (mask & GL_ENABLE_BIT)
594       attr->Blend = ctx->GLThread.Blend;
595 
596    if (mask & (GL_POLYGON_BIT | GL_ENABLE_BIT)) {
597       attr->CullFace = ctx->GLThread.CullFace;
598       attr->PolygonStipple = ctx->GLThread.PolygonStipple;
599    }
600 
601    if (mask & (GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT))
602       attr->DepthTest = ctx->GLThread.DepthTest;
603 
604    if (mask & (GL_LIGHTING_BIT | GL_ENABLE_BIT))
605       attr->Lighting = ctx->GLThread.Lighting;
606 
607    if (mask & GL_TEXTURE_BIT)
608       attr->ActiveTexture = ctx->GLThread.ActiveTexture;
609 
610    if (mask & GL_TRANSFORM_BIT)
611       attr->MatrixMode = ctx->GLThread.MatrixMode;
612 }
613 
614 static inline void
_mesa_glthread_PopAttrib(struct gl_context * ctx)615 _mesa_glthread_PopAttrib(struct gl_context *ctx)
616 {
617    if (ctx->GLThread.ListMode == GL_COMPILE)
618       return;
619 
620    if (ctx->GLThread.AttribStackDepth == 0)
621       return;
622 
623    struct glthread_attrib_node *attr =
624       &ctx->GLThread.AttribStack[--ctx->GLThread.AttribStackDepth];
625    unsigned mask = attr->Mask;
626 
627    if (mask & GL_ENABLE_BIT)
628       ctx->GLThread.Blend = attr->Blend;
629 
630    if (mask & (GL_POLYGON_BIT | GL_ENABLE_BIT)) {
631       ctx->GLThread.CullFace = attr->CullFace;
632       ctx->GLThread.PolygonStipple = attr->PolygonStipple;
633    }
634 
635    if (mask & (GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT))
636       ctx->GLThread.DepthTest = attr->DepthTest;
637 
638    if (mask & (GL_LIGHTING_BIT | GL_ENABLE_BIT))
639       ctx->GLThread.Lighting = attr->Lighting;
640 
641    if (mask & GL_TEXTURE_BIT)
642       ctx->GLThread.ActiveTexture = attr->ActiveTexture;
643 
644    if (mask & GL_TRANSFORM_BIT) {
645       ctx->GLThread.MatrixMode = attr->MatrixMode;
646       ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, attr->MatrixMode);
647    }
648 }
649 
650 static bool
is_matrix_stack_full(struct gl_context * ctx,gl_matrix_index idx)651 is_matrix_stack_full(struct gl_context *ctx, gl_matrix_index idx)
652 {
653    int max_stack_depth = 0;
654    if (M_MODELVIEW == ctx->GLThread.MatrixIndex) {
655       max_stack_depth = MAX_MODELVIEW_STACK_DEPTH;
656    } else if (M_PROJECTION == ctx->GLThread.MatrixIndex) {
657       max_stack_depth = MAX_PROJECTION_STACK_DEPTH;
658    } else if (M_PROGRAM_LAST >= ctx->GLThread.MatrixIndex) {
659       max_stack_depth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
660    } else if (M_TEXTURE_LAST >= ctx->GLThread.MatrixIndex) {
661       max_stack_depth = MAX_TEXTURE_STACK_DEPTH;
662    }
663    assert(max_stack_depth);
664 
665    if (ctx->GLThread.MatrixStackDepth[idx] + 1 >= max_stack_depth)
666       return true;
667 
668    return false;
669 }
670 
671 static inline void
_mesa_glthread_MatrixPushEXT(struct gl_context * ctx,GLenum matrixMode)672 _mesa_glthread_MatrixPushEXT(struct gl_context *ctx, GLenum matrixMode)
673 {
674    if (ctx->GLThread.ListMode == GL_COMPILE)
675       return;
676 
677    if (is_matrix_stack_full(ctx, _mesa_get_matrix_index(ctx, matrixMode)))
678       return;
679 
680    ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)]++;
681 }
682 
683 static inline void
_mesa_glthread_MatrixPopEXT(struct gl_context * ctx,GLenum matrixMode)684 _mesa_glthread_MatrixPopEXT(struct gl_context *ctx, GLenum matrixMode)
685 {
686    if (ctx->GLThread.ListMode == GL_COMPILE)
687       return;
688 
689    if (ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)] == 0)
690       return;
691 
692    ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)]--;
693 }
694 
695 static inline void
_mesa_glthread_ActiveTexture(struct gl_context * ctx,GLenum texture)696 _mesa_glthread_ActiveTexture(struct gl_context *ctx, GLenum texture)
697 {
698    if (ctx->GLThread.ListMode == GL_COMPILE)
699       return;
700 
701    ctx->GLThread.ActiveTexture = texture - GL_TEXTURE0;
702    if (ctx->GLThread.MatrixMode == GL_TEXTURE)
703       ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, texture);
704 }
705 
706 static inline void
_mesa_glthread_PushMatrix(struct gl_context * ctx)707 _mesa_glthread_PushMatrix(struct gl_context *ctx)
708 {
709    if (ctx->GLThread.ListMode == GL_COMPILE)
710       return;
711 
712    if (is_matrix_stack_full(ctx, ctx->GLThread.MatrixIndex))
713       return;
714 
715    ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex]++;
716 }
717 
718 static inline void
_mesa_glthread_PopMatrix(struct gl_context * ctx)719 _mesa_glthread_PopMatrix(struct gl_context *ctx)
720 {
721    if (ctx->GLThread.ListMode == GL_COMPILE)
722       return;
723 
724    if (ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex] == 0)
725       return;
726 
727    ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex]--;
728 }
729 
730 static inline void
_mesa_glthread_MatrixMode(struct gl_context * ctx,GLenum mode)731 _mesa_glthread_MatrixMode(struct gl_context *ctx, GLenum mode)
732 {
733    if (ctx->GLThread.ListMode == GL_COMPILE)
734       return;
735 
736    ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, mode);
737    ctx->GLThread.MatrixMode = MIN2(mode, 0xffff);
738 }
739 
740 static inline void
_mesa_glthread_ListBase(struct gl_context * ctx,GLuint base)741 _mesa_glthread_ListBase(struct gl_context *ctx, GLuint base)
742 {
743    if (ctx->GLThread.ListMode == GL_COMPILE)
744       return;
745 
746    ctx->GLThread.ListBase = base;
747 }
748 
749 static inline void
_mesa_glthread_init_call_fence(int * last_batch_index_where_called)750 _mesa_glthread_init_call_fence(int *last_batch_index_where_called)
751 {
752    *last_batch_index_where_called = -1;
753 }
754 
755 static inline void
_mesa_glthread_fence_call(struct gl_context * ctx,int * last_batch_index_where_called)756 _mesa_glthread_fence_call(struct gl_context *ctx,
757                           int *last_batch_index_where_called)
758 {
759    p_atomic_set(last_batch_index_where_called, ctx->GLThread.next);
760    /* Flush, so that the fenced call is last in the batch. */
761    _mesa_glthread_flush_batch(ctx);
762 }
763 
764 static inline void
_mesa_glthread_signal_call(int * last_batch_index_where_called,int batch_index)765 _mesa_glthread_signal_call(int *last_batch_index_where_called, int batch_index)
766 {
767    /* Atomically set this to -1 if it's equal to batch_index. */
768    p_atomic_cmpxchg(last_batch_index_where_called, batch_index, -1);
769 }
770 
771 static inline void
_mesa_glthread_wait_for_call(struct gl_context * ctx,int * last_batch_index_where_called)772 _mesa_glthread_wait_for_call(struct gl_context *ctx,
773                              int *last_batch_index_where_called)
774 {
775    int batch = p_atomic_read(last_batch_index_where_called);
776    if (batch != -1) {
777       util_queue_fence_wait(&ctx->GLThread.batches[batch].fence);
778       assert(p_atomic_read(last_batch_index_where_called) == -1);
779    }
780 }
781 
782 static inline void
_mesa_glthread_CallList(struct gl_context * ctx,GLuint list)783 _mesa_glthread_CallList(struct gl_context *ctx, GLuint list)
784 {
785    if (ctx->GLThread.ListMode == GL_COMPILE)
786       return;
787 
788    /* Wait for all glEndList and glDeleteLists calls to finish to ensure that
789     * all display lists are up to date and the driver thread is not
790     * modifiying them. We will be executing them in the application thread.
791     */
792    _mesa_glthread_wait_for_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex);
793 
794    if (!ctx->Shared->DisplayListsAffectGLThread)
795       return;
796 
797    /* Clear GL_COMPILE_AND_EXECUTE if needed. We only execute here. */
798    unsigned saved_mode = ctx->GLThread.ListMode;
799    ctx->GLThread.ListMode = 0;
800 
801    _mesa_glthread_execute_list(ctx, list);
802 
803    ctx->GLThread.ListMode = saved_mode;
804 }
805 
806 static inline void
_mesa_glthread_CallLists(struct gl_context * ctx,GLsizei n,GLenum type,const GLvoid * lists)807 _mesa_glthread_CallLists(struct gl_context *ctx, GLsizei n, GLenum type,
808                          const GLvoid *lists)
809 {
810    if (ctx->GLThread.ListMode == GL_COMPILE)
811       return;
812 
813    if (n <= 0 || !lists)
814       return;
815 
816    /* Wait for all glEndList and glDeleteLists calls to finish to ensure that
817     * all display lists are up to date and the driver thread is not
818     * modifiying them. We will be executing them in the application thread.
819     */
820    _mesa_glthread_wait_for_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex);
821 
822    /* Clear GL_COMPILE_AND_EXECUTE if needed. We only execute here. */
823    unsigned saved_mode = ctx->GLThread.ListMode;
824    ctx->GLThread.ListMode = 0;
825 
826    unsigned base = ctx->GLThread.ListBase;
827 
828    GLbyte *bptr;
829    GLubyte *ubptr;
830    GLshort *sptr;
831    GLushort *usptr;
832    GLint *iptr;
833    GLuint *uiptr;
834    GLfloat *fptr;
835 
836    switch (type) {
837    case GL_BYTE:
838       bptr = (GLbyte *) lists;
839       for (unsigned i = 0; i < n; i++)
840          _mesa_glthread_CallList(ctx, base + bptr[i]);
841       break;
842    case GL_UNSIGNED_BYTE:
843       ubptr = (GLubyte *) lists;
844       for (unsigned i = 0; i < n; i++)
845          _mesa_glthread_CallList(ctx, base + ubptr[i]);
846       break;
847    case GL_SHORT:
848       sptr = (GLshort *) lists;
849       for (unsigned i = 0; i < n; i++)
850          _mesa_glthread_CallList(ctx, base + sptr[i]);
851       break;
852    case GL_UNSIGNED_SHORT:
853       usptr = (GLushort *) lists;
854       for (unsigned i = 0; i < n; i++)
855          _mesa_glthread_CallList(ctx, base + usptr[i]);
856       break;
857    case GL_INT:
858       iptr = (GLint *) lists;
859       for (unsigned i = 0; i < n; i++)
860          _mesa_glthread_CallList(ctx, base + iptr[i]);
861       break;
862    case GL_UNSIGNED_INT:
863       uiptr = (GLuint *) lists;
864       for (unsigned i = 0; i < n; i++)
865          _mesa_glthread_CallList(ctx, base + uiptr[i]);
866       break;
867    case GL_FLOAT:
868       fptr = (GLfloat *) lists;
869       for (unsigned i = 0; i < n; i++)
870          _mesa_glthread_CallList(ctx, base + fptr[i]);
871       break;
872    case GL_2_BYTES:
873       ubptr = (GLubyte *) lists;
874       for (unsigned i = 0; i < n; i++) {
875          _mesa_glthread_CallList(ctx, base +
876                                  (GLint)ubptr[2 * i] * 256 +
877                                  (GLint)ubptr[2 * i + 1]);
878       }
879       break;
880    case GL_3_BYTES:
881       ubptr = (GLubyte *) lists;
882       for (unsigned i = 0; i < n; i++) {
883          _mesa_glthread_CallList(ctx, base +
884                                  (GLint)ubptr[3 * i] * 65536 +
885                                  (GLint)ubptr[3 * i + 1] * 256 +
886                                  (GLint)ubptr[3 * i + 2]);
887       }
888       break;
889    case GL_4_BYTES:
890       ubptr = (GLubyte *) lists;
891       for (unsigned i = 0; i < n; i++) {
892          _mesa_glthread_CallList(ctx, base +
893                                  (GLint)ubptr[4 * i] * 16777216 +
894                                  (GLint)ubptr[4 * i + 1] * 65536 +
895                                  (GLint)ubptr[4 * i + 2] * 256 +
896                                  (GLint)ubptr[4 * i + 3]);
897       }
898       break;
899    }
900 
901    ctx->GLThread.ListMode = saved_mode;
902 }
903 
904 static inline void
_mesa_glthread_NewList(struct gl_context * ctx,GLuint list,GLenum mode)905 _mesa_glthread_NewList(struct gl_context *ctx, GLuint list, GLenum mode)
906 {
907    if (!ctx->GLThread.ListMode)
908       ctx->GLThread.ListMode = MIN2(mode, 0xffff);
909 }
910 
911 static inline void
_mesa_glthread_EndList(struct gl_context * ctx)912 _mesa_glthread_EndList(struct gl_context *ctx)
913 {
914    if (!ctx->GLThread.ListMode)
915       return;
916 
917    ctx->GLThread.ListMode = 0;
918 
919    /* Track the last display list change. */
920    _mesa_glthread_fence_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex);
921 }
922 
923 static inline void
_mesa_glthread_DeleteLists(struct gl_context * ctx,GLsizei range)924 _mesa_glthread_DeleteLists(struct gl_context *ctx, GLsizei range)
925 {
926    if (range < 0)
927       return;
928 
929    /* Track the last display list change. */
930    _mesa_glthread_fence_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex);
931 }
932 
933 static inline void
_mesa_glthread_BindFramebuffer(struct gl_context * ctx,GLenum target,GLuint id)934 _mesa_glthread_BindFramebuffer(struct gl_context *ctx, GLenum target, GLuint id)
935 {
936    switch (target) {
937    case GL_FRAMEBUFFER:
938       ctx->GLThread.CurrentDrawFramebuffer = id;
939       ctx->GLThread.CurrentReadFramebuffer = id;
940       break;
941    case GL_DRAW_FRAMEBUFFER:
942       ctx->GLThread.CurrentDrawFramebuffer = id;
943       break;
944    case GL_READ_FRAMEBUFFER:
945       ctx->GLThread.CurrentReadFramebuffer = id;
946       break;
947    }
948 }
949 
950 static inline void
_mesa_glthread_DeleteFramebuffers(struct gl_context * ctx,GLsizei n,const GLuint * ids)951 _mesa_glthread_DeleteFramebuffers(struct gl_context *ctx, GLsizei n,
952                                   const GLuint *ids)
953 {
954    if (ctx->GLThread.CurrentDrawFramebuffer) {
955       for (int i = 0; i < n; i++) {
956          if (ctx->GLThread.CurrentDrawFramebuffer == ids[i])
957             ctx->GLThread.CurrentDrawFramebuffer = 0;
958          if (ctx->GLThread.CurrentReadFramebuffer == ids[i])
959             ctx->GLThread.CurrentReadFramebuffer = 0;
960       }
961    }
962 }
963 
964 #endif /* MARSHAL_H */
965