17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2012 Intel Corporation
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
217ec681f3Smrg * IN THE SOFTWARE.
227ec681f3Smrg */
237ec681f3Smrg
247ec681f3Smrg/** \file glthread_marshal.h
257ec681f3Smrg *
267ec681f3Smrg * Declarations of functions related to marshalling GL calls from a client
277ec681f3Smrg * thread to a server thread.
287ec681f3Smrg */
297ec681f3Smrg
307ec681f3Smrg#ifndef MARSHAL_H
317ec681f3Smrg#define MARSHAL_H
327ec681f3Smrg
337ec681f3Smrg#include "main/glthread.h"
347ec681f3Smrg#include "main/context.h"
357ec681f3Smrg#include "main/macros.h"
367ec681f3Smrg#include "marshal_generated.h"
377ec681f3Smrg
387ec681f3Smrgstruct marshal_cmd_base
397ec681f3Smrg{
407ec681f3Smrg   /**
417ec681f3Smrg    * Type of command.  See enum marshal_dispatch_cmd_id.
427ec681f3Smrg    */
437ec681f3Smrg   uint16_t cmd_id;
447ec681f3Smrg
457ec681f3Smrg   /**
467ec681f3Smrg    * Number of uint64_t elements used by the command.
477ec681f3Smrg    */
487ec681f3Smrg   uint16_t cmd_size;
497ec681f3Smrg};
507ec681f3Smrg
517ec681f3Smrgtypedef uint32_t (*_mesa_unmarshal_func)(struct gl_context *ctx, const void *cmd, const uint64_t *last);
527ec681f3Smrgextern const _mesa_unmarshal_func _mesa_unmarshal_dispatch[NUM_DISPATCH_CMD];
537ec681f3Smrg
547ec681f3Smrgstatic inline void *
557ec681f3Smrg_mesa_glthread_allocate_command(struct gl_context *ctx,
567ec681f3Smrg                                uint16_t cmd_id,
577ec681f3Smrg                                unsigned size)
587ec681f3Smrg{
597ec681f3Smrg   struct glthread_state *glthread = &ctx->GLThread;
607ec681f3Smrg   const unsigned num_elements = align(size, 8) / 8;
617ec681f3Smrg
627ec681f3Smrg   if (unlikely(glthread->used + num_elements > MARSHAL_MAX_CMD_SIZE / 8))
637ec681f3Smrg      _mesa_glthread_flush_batch(ctx);
647ec681f3Smrg
657ec681f3Smrg   struct glthread_batch *next = glthread->next_batch;
667ec681f3Smrg   struct marshal_cmd_base *cmd_base =
677ec681f3Smrg      (struct marshal_cmd_base *)&next->buffer[glthread->used];
687ec681f3Smrg   glthread->used += num_elements;
697ec681f3Smrg   cmd_base->cmd_id = cmd_id;
707ec681f3Smrg   cmd_base->cmd_size = num_elements;
717ec681f3Smrg   return cmd_base;
727ec681f3Smrg}
737ec681f3Smrg
747ec681f3Smrgstatic inline bool
757ec681f3Smrg_mesa_glthread_has_no_pack_buffer(const struct gl_context *ctx)
767ec681f3Smrg{
777ec681f3Smrg   return ctx->GLThread.CurrentPixelPackBufferName == 0;
787ec681f3Smrg}
797ec681f3Smrg
807ec681f3Smrgstatic inline bool
817ec681f3Smrg_mesa_glthread_has_no_unpack_buffer(const struct gl_context *ctx)
827ec681f3Smrg{
837ec681f3Smrg   return ctx->GLThread.CurrentPixelUnpackBufferName == 0;
847ec681f3Smrg}
857ec681f3Smrg
867ec681f3Smrg/**
877ec681f3Smrg * Instead of conditionally handling marshaling immediate index data in draw
887ec681f3Smrg * calls (deprecated and removed in GL core), we just disable threading.
897ec681f3Smrg */
907ec681f3Smrgstatic inline bool
917ec681f3Smrg_mesa_glthread_has_non_vbo_vertices_or_indices(const struct gl_context *ctx)
927ec681f3Smrg{
937ec681f3Smrg   const struct glthread_state *glthread = &ctx->GLThread;
947ec681f3Smrg   struct glthread_vao *vao = glthread->CurrentVAO;
957ec681f3Smrg
967ec681f3Smrg   return ctx->API != API_OPENGL_CORE &&
977ec681f3Smrg          (vao->CurrentElementBufferName == 0 ||
987ec681f3Smrg           (vao->UserPointerMask & vao->BufferEnabled));
997ec681f3Smrg}
1007ec681f3Smrg
1017ec681f3Smrgstatic inline bool
1027ec681f3Smrg_mesa_glthread_has_non_vbo_vertices(const struct gl_context *ctx)
1037ec681f3Smrg{
1047ec681f3Smrg   const struct glthread_state *glthread = &ctx->GLThread;
1057ec681f3Smrg   const struct glthread_vao *vao = glthread->CurrentVAO;
1067ec681f3Smrg
1077ec681f3Smrg   return ctx->API != API_OPENGL_CORE &&
1087ec681f3Smrg          (vao->UserPointerMask & vao->BufferEnabled);
1097ec681f3Smrg}
1107ec681f3Smrg
1117ec681f3Smrgstatic inline bool
1127ec681f3Smrg_mesa_glthread_has_non_vbo_vertices_or_indirect(const struct gl_context *ctx)
1137ec681f3Smrg{
1147ec681f3Smrg   const struct glthread_state *glthread = &ctx->GLThread;
1157ec681f3Smrg   const struct glthread_vao *vao = glthread->CurrentVAO;
1167ec681f3Smrg
1177ec681f3Smrg   return ctx->API != API_OPENGL_CORE &&
1187ec681f3Smrg          (glthread->CurrentDrawIndirectBufferName == 0 ||
1197ec681f3Smrg           (vao->UserPointerMask & vao->BufferEnabled));
1207ec681f3Smrg}
1217ec681f3Smrg
1227ec681f3Smrgstatic inline bool
1237ec681f3Smrg_mesa_glthread_has_non_vbo_vertices_or_indices_or_indirect(const struct gl_context *ctx)
1247ec681f3Smrg{
1257ec681f3Smrg   const struct glthread_state *glthread = &ctx->GLThread;
1267ec681f3Smrg   struct glthread_vao *vao = glthread->CurrentVAO;
1277ec681f3Smrg
1287ec681f3Smrg   return ctx->API != API_OPENGL_CORE &&
1297ec681f3Smrg          (glthread->CurrentDrawIndirectBufferName == 0 ||
1307ec681f3Smrg           vao->CurrentElementBufferName == 0 ||
1317ec681f3Smrg           (vao->UserPointerMask & vao->BufferEnabled));
1327ec681f3Smrg}
1337ec681f3Smrg
1347ec681f3Smrg
1357ec681f3Smrgstruct _glapi_table *
1367ec681f3Smrg_mesa_create_marshal_table(const struct gl_context *ctx);
1377ec681f3Smrg
1387ec681f3Smrgstatic inline unsigned
1397ec681f3Smrg_mesa_buffer_enum_to_count(GLenum buffer)
1407ec681f3Smrg{
1417ec681f3Smrg   switch (buffer) {
1427ec681f3Smrg   case GL_COLOR:
1437ec681f3Smrg      return 4;
1447ec681f3Smrg   case GL_DEPTH_STENCIL:
1457ec681f3Smrg      return 2;
1467ec681f3Smrg   case GL_STENCIL:
1477ec681f3Smrg   case GL_DEPTH:
1487ec681f3Smrg      return 1;
1497ec681f3Smrg   default:
1507ec681f3Smrg      return 0;
1517ec681f3Smrg   }
1527ec681f3Smrg}
1537ec681f3Smrg
1547ec681f3Smrgstatic inline unsigned
1557ec681f3Smrg_mesa_tex_param_enum_to_count(GLenum pname)
1567ec681f3Smrg{
1577ec681f3Smrg   switch (pname) {
1587ec681f3Smrg   case GL_TEXTURE_MIN_FILTER:
1597ec681f3Smrg   case GL_TEXTURE_MAG_FILTER:
1607ec681f3Smrg   case GL_TEXTURE_WRAP_S:
1617ec681f3Smrg   case GL_TEXTURE_WRAP_T:
1627ec681f3Smrg   case GL_TEXTURE_WRAP_R:
1637ec681f3Smrg   case GL_TEXTURE_BASE_LEVEL:
1647ec681f3Smrg   case GL_TEXTURE_MAX_LEVEL:
1657ec681f3Smrg   case GL_GENERATE_MIPMAP_SGIS:
1667ec681f3Smrg   case GL_TEXTURE_COMPARE_MODE_ARB:
1677ec681f3Smrg   case GL_TEXTURE_COMPARE_FUNC_ARB:
1687ec681f3Smrg   case GL_DEPTH_TEXTURE_MODE_ARB:
1697ec681f3Smrg   case GL_DEPTH_STENCIL_TEXTURE_MODE:
1707ec681f3Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
1717ec681f3Smrg   case GL_TEXTURE_REDUCTION_MODE_EXT:
1727ec681f3Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1737ec681f3Smrg   case GL_TEXTURE_SWIZZLE_R:
1747ec681f3Smrg   case GL_TEXTURE_SWIZZLE_G:
1757ec681f3Smrg   case GL_TEXTURE_SWIZZLE_B:
1767ec681f3Smrg   case GL_TEXTURE_SWIZZLE_A:
1777ec681f3Smrg   case GL_TEXTURE_MIN_LOD:
1787ec681f3Smrg   case GL_TEXTURE_MAX_LOD:
1797ec681f3Smrg   case GL_TEXTURE_PRIORITY:
1807ec681f3Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1817ec681f3Smrg   case GL_TEXTURE_LOD_BIAS:
1827ec681f3Smrg   case GL_TEXTURE_TILING_EXT:
1837ec681f3Smrg      return 1;
1847ec681f3Smrg   case GL_TEXTURE_CROP_RECT_OES:
1857ec681f3Smrg   case GL_TEXTURE_SWIZZLE_RGBA:
1867ec681f3Smrg   case GL_TEXTURE_BORDER_COLOR:
1877ec681f3Smrg      return 4;
1887ec681f3Smrg   default:
1897ec681f3Smrg      return 0;
1907ec681f3Smrg   }
1917ec681f3Smrg}
1927ec681f3Smrg
1937ec681f3Smrgstatic inline unsigned
1947ec681f3Smrg_mesa_fog_enum_to_count(GLenum pname)
1957ec681f3Smrg{
1967ec681f3Smrg   switch (pname) {
1977ec681f3Smrg   case GL_FOG_MODE:
1987ec681f3Smrg   case GL_FOG_DENSITY:
1997ec681f3Smrg   case GL_FOG_START:
2007ec681f3Smrg   case GL_FOG_END:
2017ec681f3Smrg   case GL_FOG_INDEX:
2027ec681f3Smrg   case GL_FOG_COORDINATE_SOURCE_EXT:
2037ec681f3Smrg   case GL_FOG_DISTANCE_MODE_NV:
2047ec681f3Smrg      return 1;
2057ec681f3Smrg   case GL_FOG_COLOR:
2067ec681f3Smrg      return 4;
2077ec681f3Smrg   default:
2087ec681f3Smrg      return 0;
2097ec681f3Smrg   }
2107ec681f3Smrg}
2117ec681f3Smrg
2127ec681f3Smrgstatic inline unsigned
2137ec681f3Smrg_mesa_light_enum_to_count(GLenum pname)
2147ec681f3Smrg{
2157ec681f3Smrg   switch (pname) {
2167ec681f3Smrg   case GL_AMBIENT:
2177ec681f3Smrg   case GL_DIFFUSE:
2187ec681f3Smrg   case GL_SPECULAR:
2197ec681f3Smrg   case GL_POSITION:
2207ec681f3Smrg      return 4;
2217ec681f3Smrg   case GL_SPOT_DIRECTION:
2227ec681f3Smrg      return 3;
2237ec681f3Smrg   case GL_SPOT_EXPONENT:
2247ec681f3Smrg   case GL_SPOT_CUTOFF:
2257ec681f3Smrg   case GL_CONSTANT_ATTENUATION:
2267ec681f3Smrg   case GL_LINEAR_ATTENUATION:
2277ec681f3Smrg   case GL_QUADRATIC_ATTENUATION:
2287ec681f3Smrg      return 1;
2297ec681f3Smrg   default:
2307ec681f3Smrg      return 0;
2317ec681f3Smrg   }
2327ec681f3Smrg}
2337ec681f3Smrg
2347ec681f3Smrgstatic inline unsigned
2357ec681f3Smrg_mesa_light_model_enum_to_count(GLenum pname)
2367ec681f3Smrg{
2377ec681f3Smrg   switch (pname) {
2387ec681f3Smrg   case GL_LIGHT_MODEL_AMBIENT:
2397ec681f3Smrg      return 4;
2407ec681f3Smrg   case GL_LIGHT_MODEL_LOCAL_VIEWER:
2417ec681f3Smrg   case GL_LIGHT_MODEL_TWO_SIDE:
2427ec681f3Smrg   case GL_LIGHT_MODEL_COLOR_CONTROL:
2437ec681f3Smrg      return 1;
2447ec681f3Smrg   default:
2457ec681f3Smrg      return 0;
2467ec681f3Smrg   }
2477ec681f3Smrg}
2487ec681f3Smrg
2497ec681f3Smrgstatic inline unsigned
2507ec681f3Smrg_mesa_texenv_enum_to_count(GLenum pname)
2517ec681f3Smrg{
2527ec681f3Smrg   switch (pname) {
2537ec681f3Smrg   case GL_TEXTURE_ENV_MODE:
2547ec681f3Smrg   case GL_COMBINE_RGB:
2557ec681f3Smrg   case GL_COMBINE_ALPHA:
2567ec681f3Smrg   case GL_SOURCE0_RGB:
2577ec681f3Smrg   case GL_SOURCE1_RGB:
2587ec681f3Smrg   case GL_SOURCE2_RGB:
2597ec681f3Smrg   case GL_SOURCE3_RGB_NV:
2607ec681f3Smrg   case GL_SOURCE0_ALPHA:
2617ec681f3Smrg   case GL_SOURCE1_ALPHA:
2627ec681f3Smrg   case GL_SOURCE2_ALPHA:
2637ec681f3Smrg   case GL_SOURCE3_ALPHA_NV:
2647ec681f3Smrg   case GL_OPERAND0_RGB:
2657ec681f3Smrg   case GL_OPERAND1_RGB:
2667ec681f3Smrg   case GL_OPERAND2_RGB:
2677ec681f3Smrg   case GL_OPERAND3_RGB_NV:
2687ec681f3Smrg   case GL_OPERAND0_ALPHA:
2697ec681f3Smrg   case GL_OPERAND1_ALPHA:
2707ec681f3Smrg   case GL_OPERAND2_ALPHA:
2717ec681f3Smrg   case GL_OPERAND3_ALPHA_NV:
2727ec681f3Smrg   case GL_RGB_SCALE:
2737ec681f3Smrg   case GL_ALPHA_SCALE:
2747ec681f3Smrg   case GL_TEXTURE_LOD_BIAS_EXT:
2757ec681f3Smrg   case GL_COORD_REPLACE:
2767ec681f3Smrg      return 1;
2777ec681f3Smrg   case GL_TEXTURE_ENV_COLOR:
2787ec681f3Smrg      return 4;
2797ec681f3Smrg   default:
2807ec681f3Smrg      return 0;
2817ec681f3Smrg   }
2827ec681f3Smrg}
2837ec681f3Smrg
2847ec681f3Smrgstatic inline unsigned
2857ec681f3Smrg_mesa_texgen_enum_to_count(GLenum pname)
2867ec681f3Smrg{
2877ec681f3Smrg   switch (pname) {
2887ec681f3Smrg   case GL_TEXTURE_GEN_MODE:
2897ec681f3Smrg      return 1;
2907ec681f3Smrg   case GL_OBJECT_PLANE:
2917ec681f3Smrg   case GL_EYE_PLANE:
2927ec681f3Smrg      return 4;
2937ec681f3Smrg   default:
2947ec681f3Smrg      return 0;
2957ec681f3Smrg   }
2967ec681f3Smrg}
2977ec681f3Smrg
2987ec681f3Smrgstatic inline unsigned
2997ec681f3Smrg_mesa_material_enum_to_count(GLenum pname)
3007ec681f3Smrg{
3017ec681f3Smrg   switch (pname) {
3027ec681f3Smrg   case GL_EMISSION:
3037ec681f3Smrg   case GL_AMBIENT:
3047ec681f3Smrg   case GL_DIFFUSE:
3057ec681f3Smrg   case GL_SPECULAR:
3067ec681f3Smrg   case GL_AMBIENT_AND_DIFFUSE:
3077ec681f3Smrg      return 4;
3087ec681f3Smrg   case GL_COLOR_INDEXES:
3097ec681f3Smrg      return 3;
3107ec681f3Smrg   case GL_SHININESS:
3117ec681f3Smrg      return 1;
3127ec681f3Smrg   default:
3137ec681f3Smrg      return 0;
3147ec681f3Smrg   }
3157ec681f3Smrg}
3167ec681f3Smrg
3177ec681f3Smrgstatic inline unsigned
3187ec681f3Smrg_mesa_point_param_enum_to_count(GLenum pname)
3197ec681f3Smrg{
3207ec681f3Smrg   switch (pname) {
3217ec681f3Smrg   case GL_DISTANCE_ATTENUATION_EXT:
3227ec681f3Smrg      return 3;
3237ec681f3Smrg   case GL_POINT_SIZE_MIN_EXT:
3247ec681f3Smrg   case GL_POINT_SIZE_MAX_EXT:
3257ec681f3Smrg   case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
3267ec681f3Smrg   case GL_POINT_SPRITE_COORD_ORIGIN:
3277ec681f3Smrg      return 1;
3287ec681f3Smrg   default:
3297ec681f3Smrg      return 0;
3307ec681f3Smrg   }
3317ec681f3Smrg}
3327ec681f3Smrg
3337ec681f3Smrgstatic inline unsigned
3347ec681f3Smrg_mesa_calllists_enum_to_count(GLenum type)
3357ec681f3Smrg{
3367ec681f3Smrg   switch (type) {
3377ec681f3Smrg   case GL_BYTE:
3387ec681f3Smrg   case GL_UNSIGNED_BYTE:
3397ec681f3Smrg      return 1;
3407ec681f3Smrg   case GL_SHORT:
3417ec681f3Smrg   case GL_UNSIGNED_SHORT:
3427ec681f3Smrg   case GL_2_BYTES:
3437ec681f3Smrg      return 2;
3447ec681f3Smrg   case GL_3_BYTES:
3457ec681f3Smrg      return 3;
3467ec681f3Smrg   case GL_INT:
3477ec681f3Smrg   case GL_UNSIGNED_INT:
3487ec681f3Smrg   case GL_FLOAT:
3497ec681f3Smrg   case GL_4_BYTES:
3507ec681f3Smrg      return 4;
3517ec681f3Smrg   default:
3527ec681f3Smrg      return 0;
3537ec681f3Smrg   }
3547ec681f3Smrg}
3557ec681f3Smrg
3567ec681f3Smrgstatic inline unsigned
3577ec681f3Smrg_mesa_patch_param_enum_to_count(GLenum pname)
3587ec681f3Smrg{
3597ec681f3Smrg   switch (pname) {
3607ec681f3Smrg   case GL_PATCH_DEFAULT_OUTER_LEVEL:
3617ec681f3Smrg      return 4;
3627ec681f3Smrg   case GL_PATCH_DEFAULT_INNER_LEVEL:
3637ec681f3Smrg      return 2;
3647ec681f3Smrg   default:
3657ec681f3Smrg      return 0;
3667ec681f3Smrg   }
3677ec681f3Smrg}
3687ec681f3Smrg
3697ec681f3Smrgstatic inline unsigned
3707ec681f3Smrg_mesa_memobj_enum_to_count(GLenum pname)
3717ec681f3Smrg{
3727ec681f3Smrg   switch (pname) {
3737ec681f3Smrg   case GL_DEDICATED_MEMORY_OBJECT_EXT:
3747ec681f3Smrg      return 1;
3757ec681f3Smrg   default:
3767ec681f3Smrg      return 0;
3777ec681f3Smrg   }
3787ec681f3Smrg}
3797ec681f3Smrg
3807ec681f3Smrgstatic inline unsigned
3817ec681f3Smrg_mesa_semaphore_enum_to_count(GLenum pname)
3827ec681f3Smrg{
3837ec681f3Smrg   switch (pname) {
3847ec681f3Smrg   /* EXT_semaphore and EXT_semaphore_fd define no parameters */
3857ec681f3Smrg   default:
3867ec681f3Smrg      return 0;
3877ec681f3Smrg   }
3887ec681f3Smrg}
3897ec681f3Smrg
3907ec681f3Smrgstatic inline gl_vert_attrib
3917ec681f3Smrg_mesa_array_to_attrib(struct gl_context *ctx, GLenum array)
3927ec681f3Smrg{
3937ec681f3Smrg   switch (array) {
3947ec681f3Smrg   case GL_VERTEX_ARRAY:
3957ec681f3Smrg      return VERT_ATTRIB_POS;
3967ec681f3Smrg   case GL_NORMAL_ARRAY:
3977ec681f3Smrg      return VERT_ATTRIB_NORMAL;
3987ec681f3Smrg   case GL_COLOR_ARRAY:
3997ec681f3Smrg      return VERT_ATTRIB_COLOR0;
4007ec681f3Smrg   case GL_INDEX_ARRAY:
4017ec681f3Smrg      return VERT_ATTRIB_COLOR_INDEX;
4027ec681f3Smrg   case GL_TEXTURE_COORD_ARRAY:
4037ec681f3Smrg      return VERT_ATTRIB_TEX(ctx->GLThread.ClientActiveTexture);
4047ec681f3Smrg   case GL_EDGE_FLAG_ARRAY:
4057ec681f3Smrg      return VERT_ATTRIB_EDGEFLAG;
4067ec681f3Smrg   case GL_FOG_COORDINATE_ARRAY:
4077ec681f3Smrg      return VERT_ATTRIB_FOG;
4087ec681f3Smrg   case GL_SECONDARY_COLOR_ARRAY:
4097ec681f3Smrg      return VERT_ATTRIB_COLOR1;
4107ec681f3Smrg   case GL_POINT_SIZE_ARRAY_OES:
4117ec681f3Smrg      return VERT_ATTRIB_POINT_SIZE;
4127ec681f3Smrg   case GL_PRIMITIVE_RESTART_NV:
4137ec681f3Smrg      return VERT_ATTRIB_PRIMITIVE_RESTART_NV;
4147ec681f3Smrg   default:
4157ec681f3Smrg      if (array >= GL_TEXTURE0 && array <= GL_TEXTURE7)
4167ec681f3Smrg         return VERT_ATTRIB_TEX(array - GL_TEXTURE0);
4177ec681f3Smrg      return VERT_ATTRIB_MAX;
4187ec681f3Smrg   }
4197ec681f3Smrg}
4207ec681f3Smrg
4217ec681f3Smrgstatic inline gl_matrix_index
4227ec681f3Smrg_mesa_get_matrix_index(struct gl_context *ctx, GLenum mode)
4237ec681f3Smrg{
4247ec681f3Smrg   if (mode == GL_MODELVIEW || mode == GL_PROJECTION)
4257ec681f3Smrg      return M_MODELVIEW + (mode - GL_MODELVIEW);
4267ec681f3Smrg
4277ec681f3Smrg   if (mode == GL_TEXTURE)
4287ec681f3Smrg      return M_TEXTURE0 + ctx->GLThread.ActiveTexture;
4297ec681f3Smrg
4307ec681f3Smrg   if (mode >= GL_TEXTURE0 && mode <= GL_TEXTURE0 + MAX_TEXTURE_UNITS - 1)
4317ec681f3Smrg      return M_TEXTURE0 + (mode - GL_TEXTURE0);
4327ec681f3Smrg
4337ec681f3Smrg   if (mode >= GL_MATRIX0_ARB && mode <= GL_MATRIX0_ARB + MAX_PROGRAM_MATRICES - 1)
4347ec681f3Smrg      return M_PROGRAM0 + (mode - GL_MATRIX0_ARB);
4357ec681f3Smrg
4367ec681f3Smrg   return M_DUMMY;
4377ec681f3Smrg}
4387ec681f3Smrg
4397ec681f3Smrgstatic inline void
4407ec681f3Smrg_mesa_glthread_Enable(struct gl_context *ctx, GLenum cap)
4417ec681f3Smrg{
4427ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
4437ec681f3Smrg      return;
4447ec681f3Smrg
4457ec681f3Smrg   if (cap == GL_PRIMITIVE_RESTART ||
4467ec681f3Smrg       cap == GL_PRIMITIVE_RESTART_FIXED_INDEX)
4477ec681f3Smrg      _mesa_glthread_set_prim_restart(ctx, cap, true);
4487ec681f3Smrg   else if (cap == GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB)
4497ec681f3Smrg      _mesa_glthread_disable(ctx, "Enable(DEBUG_OUTPUT_SYNCHRONOUS)");
4507ec681f3Smrg}
4517ec681f3Smrg
4527ec681f3Smrgstatic inline void
4537ec681f3Smrg_mesa_glthread_Disable(struct gl_context *ctx, GLenum cap)
4547ec681f3Smrg{
4557ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
4567ec681f3Smrg      return;
4577ec681f3Smrg
4587ec681f3Smrg   if (cap == GL_PRIMITIVE_RESTART ||
4597ec681f3Smrg       cap == GL_PRIMITIVE_RESTART_FIXED_INDEX)
4607ec681f3Smrg      _mesa_glthread_set_prim_restart(ctx, cap, false);
4617ec681f3Smrg}
4627ec681f3Smrg
4637ec681f3Smrgstatic inline void
4647ec681f3Smrg_mesa_glthread_PushAttrib(struct gl_context *ctx, GLbitfield mask)
4657ec681f3Smrg{
4667ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
4677ec681f3Smrg      return;
4687ec681f3Smrg
4697ec681f3Smrg   struct glthread_attrib_node *attr =
4707ec681f3Smrg      &ctx->GLThread.AttribStack[ctx->GLThread.AttribStackDepth++];
4717ec681f3Smrg
4727ec681f3Smrg   attr->Mask = mask;
4737ec681f3Smrg
4747ec681f3Smrg   if (mask & GL_TEXTURE_BIT)
4757ec681f3Smrg      attr->ActiveTexture = ctx->GLThread.ActiveTexture;
4767ec681f3Smrg
4777ec681f3Smrg   if (mask & GL_TRANSFORM_BIT)
4787ec681f3Smrg      attr->MatrixMode = ctx->GLThread.MatrixMode;
4797ec681f3Smrg}
4807ec681f3Smrg
4817ec681f3Smrgstatic inline void
4827ec681f3Smrg_mesa_glthread_PopAttrib(struct gl_context *ctx)
4837ec681f3Smrg{
4847ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
4857ec681f3Smrg      return;
4867ec681f3Smrg
4877ec681f3Smrg   struct glthread_attrib_node *attr =
4887ec681f3Smrg      &ctx->GLThread.AttribStack[--ctx->GLThread.AttribStackDepth];
4897ec681f3Smrg   unsigned mask = attr->Mask;
4907ec681f3Smrg
4917ec681f3Smrg   if (mask & GL_TEXTURE_BIT)
4927ec681f3Smrg      ctx->GLThread.ActiveTexture = attr->ActiveTexture;
4937ec681f3Smrg
4947ec681f3Smrg   if (mask & GL_TRANSFORM_BIT) {
4957ec681f3Smrg      ctx->GLThread.MatrixMode = attr->MatrixMode;
4967ec681f3Smrg      ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, attr->MatrixMode);
4977ec681f3Smrg   }
4987ec681f3Smrg}
4997ec681f3Smrg
5007ec681f3Smrgstatic inline void
5017ec681f3Smrg_mesa_glthread_MatrixPushEXT(struct gl_context *ctx, GLenum matrixMode)
5027ec681f3Smrg{
5037ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
5047ec681f3Smrg      return;
5057ec681f3Smrg
5067ec681f3Smrg   ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)]++;
5077ec681f3Smrg}
5087ec681f3Smrg
5097ec681f3Smrgstatic inline void
5107ec681f3Smrg_mesa_glthread_MatrixPopEXT(struct gl_context *ctx, GLenum matrixMode)
5117ec681f3Smrg{
5127ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
5137ec681f3Smrg      return;
5147ec681f3Smrg
5157ec681f3Smrg   ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)]--;
5167ec681f3Smrg}
5177ec681f3Smrg
5187ec681f3Smrgstatic inline void
5197ec681f3Smrg_mesa_glthread_ActiveTexture(struct gl_context *ctx, GLenum texture)
5207ec681f3Smrg{
5217ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
5227ec681f3Smrg      return;
5237ec681f3Smrg
5247ec681f3Smrg   ctx->GLThread.ActiveTexture = texture - GL_TEXTURE0;
5257ec681f3Smrg   if (ctx->GLThread.MatrixMode == GL_TEXTURE)
5267ec681f3Smrg      ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, texture);
5277ec681f3Smrg}
5287ec681f3Smrg
5297ec681f3Smrgstatic inline void
5307ec681f3Smrg_mesa_glthread_PushMatrix(struct gl_context *ctx)
5317ec681f3Smrg{
5327ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
5337ec681f3Smrg      return;
5347ec681f3Smrg
5357ec681f3Smrg   ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex]++;
5367ec681f3Smrg}
5377ec681f3Smrg
5387ec681f3Smrgstatic inline void
5397ec681f3Smrg_mesa_glthread_PopMatrix(struct gl_context *ctx)
5407ec681f3Smrg{
5417ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
5427ec681f3Smrg      return;
5437ec681f3Smrg
5447ec681f3Smrg   ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex]--;
5457ec681f3Smrg}
5467ec681f3Smrg
5477ec681f3Smrgstatic inline void
5487ec681f3Smrg_mesa_glthread_MatrixMode(struct gl_context *ctx, GLenum mode)
5497ec681f3Smrg{
5507ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
5517ec681f3Smrg      return;
5527ec681f3Smrg
5537ec681f3Smrg   ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, mode);
5547ec681f3Smrg   ctx->GLThread.MatrixMode = mode;
5557ec681f3Smrg}
5567ec681f3Smrg
5577ec681f3Smrgstatic inline void
5587ec681f3Smrg_mesa_glthread_ListBase(struct gl_context *ctx, GLuint base)
5597ec681f3Smrg{
5607ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
5617ec681f3Smrg      return;
5627ec681f3Smrg
5637ec681f3Smrg   ctx->GLThread.ListBase = base;
5647ec681f3Smrg}
5657ec681f3Smrg
5667ec681f3Smrgstatic inline void
5677ec681f3Smrg_mesa_glthread_CallList(struct gl_context *ctx, GLuint list)
5687ec681f3Smrg{
5697ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
5707ec681f3Smrg      return;
5717ec681f3Smrg
5727ec681f3Smrg   /* Wait for all glEndList and glDeleteLists calls to finish to ensure that
5737ec681f3Smrg    * all display lists are up to date and the driver thread is not
5747ec681f3Smrg    * modifiying them. We will be executing them in the application thread.
5757ec681f3Smrg    */
5767ec681f3Smrg   int batch = p_atomic_read(&ctx->GLThread.LastDListChangeBatchIndex);
5777ec681f3Smrg   if (batch != -1) {
5787ec681f3Smrg      util_queue_fence_wait(&ctx->GLThread.batches[batch].fence);
5797ec681f3Smrg      p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, -1);
5807ec681f3Smrg   }
5817ec681f3Smrg
5827ec681f3Smrg   /* Clear GL_COMPILE_AND_EXECUTE if needed. We only execute here. */
5837ec681f3Smrg   unsigned saved_mode = ctx->GLThread.ListMode;
5847ec681f3Smrg   ctx->GLThread.ListMode = 0;
5857ec681f3Smrg
5867ec681f3Smrg   _mesa_glthread_execute_list(ctx, list);
5877ec681f3Smrg
5887ec681f3Smrg   ctx->GLThread.ListMode = saved_mode;
5897ec681f3Smrg}
5907ec681f3Smrg
5917ec681f3Smrgstatic inline void
5927ec681f3Smrg_mesa_glthread_CallLists(struct gl_context *ctx, GLsizei n, GLenum type,
5937ec681f3Smrg                         const GLvoid *lists)
5947ec681f3Smrg{
5957ec681f3Smrg   if (ctx->GLThread.ListMode == GL_COMPILE)
5967ec681f3Smrg      return;
5977ec681f3Smrg
5987ec681f3Smrg   if (n <= 0 || !lists)
5997ec681f3Smrg      return;
6007ec681f3Smrg
6017ec681f3Smrg   /* Wait for all glEndList and glDeleteLists calls to finish to ensure that
6027ec681f3Smrg    * all display lists are up to date and the driver thread is not
6037ec681f3Smrg    * modifiying them. We will be executing them in the application thread.
6047ec681f3Smrg    */
6057ec681f3Smrg   int batch = p_atomic_read(&ctx->GLThread.LastDListChangeBatchIndex);
6067ec681f3Smrg   if (batch != -1) {
6077ec681f3Smrg      util_queue_fence_wait(&ctx->GLThread.batches[batch].fence);
6087ec681f3Smrg      p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, -1);
6097ec681f3Smrg   }
6107ec681f3Smrg
6117ec681f3Smrg   /* Clear GL_COMPILE_AND_EXECUTE if needed. We only execute here. */
6127ec681f3Smrg   unsigned saved_mode = ctx->GLThread.ListMode;
6137ec681f3Smrg   ctx->GLThread.ListMode = 0;
6147ec681f3Smrg
6157ec681f3Smrg   unsigned base = ctx->GLThread.ListBase;
6167ec681f3Smrg
6177ec681f3Smrg   GLbyte *bptr;
6187ec681f3Smrg   GLubyte *ubptr;
6197ec681f3Smrg   GLshort *sptr;
6207ec681f3Smrg   GLushort *usptr;
6217ec681f3Smrg   GLint *iptr;
6227ec681f3Smrg   GLuint *uiptr;
6237ec681f3Smrg   GLfloat *fptr;
6247ec681f3Smrg
6257ec681f3Smrg   switch (type) {
6267ec681f3Smrg   case GL_BYTE:
6277ec681f3Smrg      bptr = (GLbyte *) lists;
6287ec681f3Smrg      for (unsigned i = 0; i < n; i++)
6297ec681f3Smrg         _mesa_glthread_CallList(ctx, base + bptr[i]);
6307ec681f3Smrg      break;
6317ec681f3Smrg   case GL_UNSIGNED_BYTE:
6327ec681f3Smrg      ubptr = (GLubyte *) lists;
6337ec681f3Smrg      for (unsigned i = 0; i < n; i++)
6347ec681f3Smrg         _mesa_glthread_CallList(ctx, base + ubptr[i]);
6357ec681f3Smrg      break;
6367ec681f3Smrg   case GL_SHORT:
6377ec681f3Smrg      sptr = (GLshort *) lists;
6387ec681f3Smrg      for (unsigned i = 0; i < n; i++)
6397ec681f3Smrg         _mesa_glthread_CallList(ctx, base + sptr[i]);
6407ec681f3Smrg      break;
6417ec681f3Smrg   case GL_UNSIGNED_SHORT:
6427ec681f3Smrg      usptr = (GLushort *) lists;
6437ec681f3Smrg      for (unsigned i = 0; i < n; i++)
6447ec681f3Smrg         _mesa_glthread_CallList(ctx, base + usptr[i]);
6457ec681f3Smrg      break;
6467ec681f3Smrg   case GL_INT:
6477ec681f3Smrg      iptr = (GLint *) lists;
6487ec681f3Smrg      for (unsigned i = 0; i < n; i++)
6497ec681f3Smrg         _mesa_glthread_CallList(ctx, base + iptr[i]);
6507ec681f3Smrg      break;
6517ec681f3Smrg   case GL_UNSIGNED_INT:
6527ec681f3Smrg      uiptr = (GLuint *) lists;
6537ec681f3Smrg      for (unsigned i = 0; i < n; i++)
6547ec681f3Smrg         _mesa_glthread_CallList(ctx, base + uiptr[i]);
6557ec681f3Smrg      break;
6567ec681f3Smrg   case GL_FLOAT:
6577ec681f3Smrg      fptr = (GLfloat *) lists;
6587ec681f3Smrg      for (unsigned i = 0; i < n; i++)
6597ec681f3Smrg         _mesa_glthread_CallList(ctx, base + fptr[i]);
6607ec681f3Smrg      break;
6617ec681f3Smrg   case GL_2_BYTES:
6627ec681f3Smrg      ubptr = (GLubyte *) lists;
6637ec681f3Smrg      for (unsigned i = 0; i < n; i++) {
6647ec681f3Smrg         _mesa_glthread_CallList(ctx, base +
6657ec681f3Smrg                                 (GLint)ubptr[2 * i] * 256 +
6667ec681f3Smrg                                 (GLint)ubptr[2 * i + 1]);
6677ec681f3Smrg      }
6687ec681f3Smrg      break;
6697ec681f3Smrg   case GL_3_BYTES:
6707ec681f3Smrg      ubptr = (GLubyte *) lists;
6717ec681f3Smrg      for (unsigned i = 0; i < n; i++) {
6727ec681f3Smrg         _mesa_glthread_CallList(ctx, base +
6737ec681f3Smrg                                 (GLint)ubptr[3 * i] * 65536 +
6747ec681f3Smrg                                 (GLint)ubptr[3 * i + 1] * 256 +
6757ec681f3Smrg                                 (GLint)ubptr[3 * i + 2]);
6767ec681f3Smrg      }
6777ec681f3Smrg      break;
6787ec681f3Smrg   case GL_4_BYTES:
6797ec681f3Smrg      ubptr = (GLubyte *) lists;
6807ec681f3Smrg      for (unsigned i = 0; i < n; i++) {
6817ec681f3Smrg         _mesa_glthread_CallList(ctx, base +
6827ec681f3Smrg                                 (GLint)ubptr[4 * i] * 16777216 +
6837ec681f3Smrg                                 (GLint)ubptr[4 * i + 1] * 65536 +
6847ec681f3Smrg                                 (GLint)ubptr[4 * i + 2] * 256 +
6857ec681f3Smrg                                 (GLint)ubptr[4 * i + 3]);
6867ec681f3Smrg      }
6877ec681f3Smrg      break;
6887ec681f3Smrg   }
6897ec681f3Smrg
6907ec681f3Smrg   ctx->GLThread.ListMode = saved_mode;
6917ec681f3Smrg}
6927ec681f3Smrg
6937ec681f3Smrgstatic inline void
6947ec681f3Smrg_mesa_glthread_NewList(struct gl_context *ctx, GLuint list, GLuint mode)
6957ec681f3Smrg{
6967ec681f3Smrg   if (!ctx->GLThread.ListMode)
6977ec681f3Smrg      ctx->GLThread.ListMode = mode;
6987ec681f3Smrg}
6997ec681f3Smrg
7007ec681f3Smrgstatic inline void
7017ec681f3Smrg_mesa_glthread_EndList(struct gl_context *ctx)
7027ec681f3Smrg{
7037ec681f3Smrg   if (!ctx->GLThread.ListMode)
7047ec681f3Smrg      return;
7057ec681f3Smrg
7067ec681f3Smrg   ctx->GLThread.ListMode = 0;
7077ec681f3Smrg
7087ec681f3Smrg   /* Track the last display list change. */
7097ec681f3Smrg   p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, ctx->GLThread.next);
7107ec681f3Smrg   _mesa_glthread_flush_batch(ctx);
7117ec681f3Smrg}
7127ec681f3Smrg
7137ec681f3Smrgstatic inline void
7147ec681f3Smrg_mesa_glthread_DeleteLists(struct gl_context *ctx, GLsizei range)
7157ec681f3Smrg{
7167ec681f3Smrg   if (range < 0)
7177ec681f3Smrg      return;
7187ec681f3Smrg
7197ec681f3Smrg   /* Track the last display list change. */
7207ec681f3Smrg   p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, ctx->GLThread.next);
7217ec681f3Smrg   _mesa_glthread_flush_batch(ctx);
7227ec681f3Smrg}
7237ec681f3Smrg
7247ec681f3Smrgstruct marshal_cmd_CallList
7257ec681f3Smrg{
7267ec681f3Smrg   struct marshal_cmd_base cmd_base;
7277ec681f3Smrg   GLuint list;
7287ec681f3Smrg};
7297ec681f3Smrg
7307ec681f3Smrg#endif /* MARSHAL_H */
731