glthread: set marshal functions in dispatch only if they exist in the API

We now have proper nop dispatch for the unset functions.

The autogenerated code looks like this:

   if ((ctx->API == API_OPENGLES2 && ctx->Version >= 31)) {
      if (_gloffset_DepthRangeArrayfvOES >= 0)
         ((_glapi_proc *)(ctx->MarshalExec))[_gloffset_DepthRangeArrayfvOES] = (_glapi_proc)_mesa_marshal_DepthRangeArrayfvOES;
      if (_gloffset_DepthRangeIndexedfOES >= 0)
         ((_glapi_proc *)(ctx->MarshalExec))[_gloffset_DepthRangeIndexedfOES] = (_glapi_proc)_mesa_marshal_DepthRangeIndexedfOES;
   }
   if (_mesa_is_desktop_gl(ctx)) {
      if (_gloffset_AlphaToCoverageDitherControlNV >= 0)
         ((_glapi_proc *)(ctx->MarshalExec))[_gloffset_AlphaToCoverageDitherControlNV] = (_glapi_proc)_mesa_marshal_AlphaToCoverageDitherControlNV;
      if (_gloffset_AttachObjectARB >= 0)
         ((_glapi_proc *)(ctx->MarshalExec))[_gloffset_AttachObjectARB] = (_glapi_proc)_mesa_marshal_AttachObjectARB;
      if (_gloffset_BeginQueryIndexed >= 0)
         ((_glapi_proc *)(ctx->MarshalExec))[_gloffset_BeginQueryIndexed] = (_glapi_proc)_mesa_marshal_BeginQueryIndexed;
      if (_gloffset_BindBufferOffsetEXT >= 0)
         ((_glapi_proc *)(ctx->MarshalExec))[_gloffset_BindBufferOffsetEXT] = (_glapi_proc)_mesa_marshal_BindBufferOffsetEXT;
   ...

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14000>
This commit is contained in:
Marek Olšák
2021-11-28 19:39:45 -05:00
parent e93a9b422c
commit 7b123ad16a
3 changed files with 37 additions and 18 deletions
+34 -14
View File
@@ -26,6 +26,8 @@ import gl_XML
import license
import marshal_XML
import sys
import collections
import apiexec
header = """
#include "context.h"
@@ -377,30 +379,48 @@ class PrintCode(gl_XML.gl_print_base):
out('#if defined(__GNUC__) && !defined(__clang__)')
out('__attribute__((optimize("O1")))')
out('#endif')
out('struct _glapi_table *')
out('_mesa_create_marshal_table(const struct gl_context *ctx)')
out('bool')
out('_mesa_create_marshal_tables(struct gl_context *ctx)')
out('{')
with indent():
out('struct _glapi_table *table;')
out('')
out('table = _mesa_alloc_dispatch_table(true);')
out('if (table == NULL)')
out('ctx->MarshalExec = _mesa_alloc_dispatch_table(true);')
out('if (!ctx->MarshalExec)')
with indent():
out('return NULL;')
out('return false;')
out('')
# Collect SET_* calls by the condition under which they should
# be called.
settings_by_condition = collections.defaultdict(lambda: [])
for func in api.functionIterateAll():
if func.marshal_flavor() == 'skip':
continue
condition = apiexec.get_api_condition(func)
if not condition:
continue
# Don't use the SET_* functions, because they increase compile time
# by 20 seconds (on Ryzen 1700X).
out('if (_gloffset_{0} >= 0)'.format(func.name))
out(' ((_glapi_proc *)(table))[_gloffset_{0}] = (_glapi_proc)_mesa_marshal_{0};'
.format(func.name))
out('')
out('return table;')
settings_by_condition[condition].append(
('if (_gloffset_{0} >= 0)\n' +
' ((_glapi_proc *)(ctx->MarshalExec))[_gloffset_{0}] =' +
' (_glapi_proc)_mesa_marshal_{0};').format(func.name))
# Print out an if statement for each unique condition, with
# the SET_* calls nested inside it.
for condition in sorted(settings_by_condition.keys()):
out('if ({0}) {{'.format(condition))
with indent():
for setting in sorted(settings_by_condition[condition]):
for line in setting.split('\n'):
out(line)
out('}')
out('')
out(' return true;')
out('}')
out('')
out('')
def printBody(self, api):
# The first file only contains the dispatch tables