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

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

View File

@ -110,8 +110,7 @@ _mesa_glthread_init(struct gl_context *ctx)
_mesa_glthread_reset_vao(&glthread->DefaultVAO);
glthread->CurrentVAO = &glthread->DefaultVAO;
ctx->MarshalExec = _mesa_create_marshal_table(ctx);
if (!ctx->MarshalExec) {
if (!_mesa_create_marshal_tables(ctx)) {
_mesa_DeleteHashTable(glthread->VAOs);
util_queue_destroy(&glthread->queue);
return;

View File

@ -132,8 +132,8 @@ _mesa_glthread_has_non_vbo_vertices_or_indices_or_indirect(const struct gl_conte
}
struct _glapi_table *
_mesa_create_marshal_table(const struct gl_context *ctx);
bool
_mesa_create_marshal_tables(struct gl_context *ctx);
static inline unsigned
_mesa_buffer_enum_to_count(GLenum buffer)