diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2019-01-29 10:51:18 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2019-01-29 10:51:18 +0000 |
commit | 726e4bceb8bf5b8123eda80e45a9fdeb016f3790 (patch) | |
tree | 32ed745d6aeb44b4c130f647e49d6627320a3857 /lib | |
parent | 5c0a71df6e14d3ae04cc0faa6dad6e5d0a01d27a (diff) |
Import Mesa 18.3.2
Diffstat (limited to 'lib')
307 files changed, 44062 insertions, 6306 deletions
diff --git a/lib/mesa/bin/git_sha1_gen.py b/lib/mesa/bin/git_sha1_gen.py index c75dba101..c6fbf4903 100755 --- a/lib/mesa/bin/git_sha1_gen.py +++ b/lib/mesa/bin/git_sha1_gen.py @@ -1,11 +1,10 @@ -#!/usr/bin/env python - """ Generate the contents of the git_sha1.h file. The output of this script goes to stdout. """ +import argparse import os import os.path import subprocess @@ -27,10 +26,25 @@ def get_git_sha1(): git_sha1 = '' return git_sha1 +def write_if_different(contents): + """ + Avoid touching the output file if it doesn't need modifications + Useful to avoid triggering rebuilds when nothing has changed. + """ + if os.path.isfile(args.output): + with open(args.output, 'r') as file: + if file.read() == contents: + return + with open(args.output, 'w') as file: + file.write(contents) + +parser = argparse.ArgumentParser() +parser.add_argument('--output', help='File to write the #define in', + required=True) +args = parser.parse_args() git_sha1 = os.environ.get('MESA_GIT_SHA1_OVERRIDE', get_git_sha1())[:10] if git_sha1: - git_sha1_h_in_path = os.path.join(os.path.dirname(sys.argv[0]), - '..', 'src', 'git_sha1.h.in') - with open(git_sha1_h_in_path , 'r') as git_sha1_h_in: - sys.stdout.write(git_sha1_h_in.read().replace('@VCS_TAG@', git_sha1)) + write_if_different('#define MESA_GIT_SHA1 " (git-' + git_sha1 + ')"') +else: + write_if_different('#define MESA_GIT_SHA1 ""') diff --git a/lib/mesa/bin/install_megadrivers.py b/lib/mesa/bin/install_megadrivers.py new file mode 100644 index 000000000..d29b19112 --- /dev/null +++ b/lib/mesa/bin/install_megadrivers.py @@ -0,0 +1,74 @@ +# encoding=utf-8 +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Script to install megadriver symlinks for meson.""" + +from __future__ import print_function +import argparse +import os +import shutil + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('megadriver') + parser.add_argument('libdir') + parser.add_argument('drivers', nargs='+') + args = parser.parse_args() + + if os.path.isabs(args.libdir): + to = os.path.join(os.environ.get('DESTDIR', '/'), args.libdir[1:]) + else: + to = os.path.join(os.environ['MESON_INSTALL_DESTDIR_PREFIX'], args.libdir) + + master = os.path.join(to, os.path.basename(args.megadriver)) + + if not os.path.exists(to): + if os.path.lexists(to): + os.unlink(to) + os.makedirs(to) + shutil.copy(args.megadriver, master) + + for driver in args.drivers: + abs_driver = os.path.join(to, driver) + + if os.path.lexists(abs_driver): + os.unlink(abs_driver) + print('installing {} to {}'.format(args.megadriver, abs_driver)) + os.link(master, abs_driver) + + try: + ret = os.getcwd() + os.chdir(to) + + name, ext = os.path.splitext(driver) + while ext != '.so': + if os.path.lexists(name): + os.unlink(name) + os.symlink(driver, name) + name, ext = os.path.splitext(name) + finally: + os.chdir(ret) + os.unlink(master) + + +if __name__ == '__main__': + main() diff --git a/lib/mesa/bin/meson.build b/lib/mesa/bin/meson.build new file mode 100644 index 000000000..b8b44baf7 --- /dev/null +++ b/lib/mesa/bin/meson.build @@ -0,0 +1,21 @@ +# Copyright © 2017 Eric Engestrom + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +git_sha1_gen_py = files('git_sha1_gen.py') diff --git a/lib/mesa/bin/meson_get_version.py b/lib/mesa/bin/meson_get_version.py new file mode 100644 index 000000000..a221e26f2 --- /dev/null +++ b/lib/mesa/bin/meson_get_version.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# encoding=utf-8 +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import print_function +import os + + +def main(): + filename = os.path.join(os.environ['MESON_SOURCE_ROOT'], 'VERSION') + with open(filename) as f: + version = f.read().strip() + print(version, end='') + + +if __name__ == '__main__': + main() diff --git a/lib/mesa/meson.build b/lib/mesa/meson.build new file mode 100644 index 000000000..5a20e1ea3 --- /dev/null +++ b/lib/mesa/meson.build @@ -0,0 +1,1468 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +project( + 'mesa', + ['c', 'cpp'], + version : run_command( + [find_program('python', 'python2', 'python3'), 'bin/meson_get_version.py'] + ).stdout(), + license : 'MIT', + meson_version : '>= 0.45', + default_options : ['buildtype=debugoptimized', 'b_ndebug=if-release', 'c_std=c99', 'cpp_std=c++11'] +) + +cc = meson.get_compiler('c') +cpp = meson.get_compiler('cpp') + +null_dep = dependency('', required : false) + +system_has_kms_drm = ['openbsd', 'netbsd', 'freebsd', 'dragonfly', 'linux'].contains(host_machine.system()) + +# Arguments for the preprocessor, put these in a separate array from the C and +# C++ (cpp in meson terminology) arguments since they need to be added to the +# default arguments for both C and C++. +pre_args = [ + '-D__STDC_CONSTANT_MACROS', + '-D__STDC_FORMAT_MACROS', + '-D__STDC_LIMIT_MACROS', + '-DVERSION="@0@"'.format(meson.project_version()), + '-DPACKAGE_VERSION=VERSION', + '-DPACKAGE_BUGREPORT="https://bugs.freedesktop.org/enter_bug.cgi?product=Mesa"', +] + +with_vulkan_icd_dir = get_option('vulkan-icd-dir') +with_tests = get_option('build-tests') +with_valgrind = get_option('valgrind') +with_libunwind = get_option('libunwind') +with_asm = get_option('asm') +with_glx_read_only_text = get_option('glx-read-only-text') +with_glx_direct = get_option('glx-direct') +with_osmesa = get_option('osmesa') +with_swr_arches = get_option('swr-arches') +with_tools = get_option('tools') +if with_tools.contains('all') + with_tools = ['freedreno', 'glsl', 'intel', 'nir', 'nouveau', 'xvmc'] +endif + +dri_drivers_path = get_option('dri-drivers-path') +if dri_drivers_path == '' + dri_drivers_path = join_paths(get_option('libdir'), 'dri') +endif +dri_search_path = get_option('dri-search-path') +if dri_search_path == '' + dri_search_path = join_paths(get_option('prefix'), dri_drivers_path) +endif + +with_gles1 = get_option('gles1') +with_gles2 = get_option('gles2') +with_opengl = get_option('opengl') +with_any_opengl = with_opengl or with_gles1 or with_gles2 +# Only build shared_glapi if at least one OpenGL API is enabled +with_shared_glapi = get_option('shared-glapi') and with_any_opengl + + +# shared-glapi is required if at least two OpenGL APIs are being built +if not with_shared_glapi + if ((with_gles1 and with_gles2) or (with_gles1 and with_opengl) + or (with_gles2 and with_opengl)) + error('shared-glapi required for building two or more of OpenGL, OpenGL ES 1.x, OpenGL ES 2.x') + endif +endif + +# We require OpenGL for OpenGL ES +if (with_gles1 or with_gles2) and not with_opengl + error('building OpenGL ES without OpenGL is not supported.') +endif + +system_has_kms_drm = ['openbsd', 'netbsd', 'freebsd', 'dragonfly', 'linux'].contains(host_machine.system()) + +_drivers = get_option('dri-drivers') +if _drivers.contains('auto') + if system_has_kms_drm + # TODO: PPC, Sparc + if ['x86', 'x86_64'].contains(host_machine.cpu_family()) + _drivers = ['i915', 'i965', 'r100', 'r200', 'nouveau'] + elif ['arm', 'aarch64'].contains(host_machine.cpu_family()) + _drivers = [] + else + error('Unknown architecture @0@. Please pass -Ddri-drivers to set driver options. Patches gladly accepted to fix this.'.format( + host_machine.cpu_family())) + endif + elif ['darwin', 'windows', 'cygwin', 'haiku'].contains(host_machine.system()) + # only swrast would make sense here, but gallium swrast is a much better default + _drivers = [] + else + error('Unknown OS @0@. Please pass -Ddri-drivers to set driver options. Patches gladly accepted to fix this.'.format( + host_machine.system())) + endif +endif + +with_dri_i915 = _drivers.contains('i915') +with_dri_i965 = _drivers.contains('i965') +with_dri_r100 = _drivers.contains('r100') +with_dri_r200 = _drivers.contains('r200') +with_dri_nouveau = _drivers.contains('nouveau') +with_dri_swrast = _drivers.contains('swrast') + +with_dri = _drivers.length() != 0 and _drivers != [''] + +_drivers = get_option('gallium-drivers') +if _drivers.contains('auto') + if system_has_kms_drm + # TODO: PPC, Sparc + if ['x86', 'x86_64'].contains(host_machine.cpu_family()) + _drivers = [ + 'r300', 'r600', 'radeonsi', 'nouveau', 'virgl', 'svga', 'swrast' + ] + elif ['arm', 'aarch64'].contains(host_machine.cpu_family()) + _drivers = [ + 'pl111', 'v3d', 'vc4', 'freedreno', 'etnaviv', 'imx', 'nouveau', + 'tegra', 'virgl', 'swrast', + ] + else + error('Unknown architecture @0@. Please pass -Dgallium-drivers to set driver options. Patches gladly accepted to fix this.'.format( + host_machine.cpu_family())) + endif + elif ['darwin', 'windows', 'cygwin', 'haiku'].contains(host_machine.system()) + _drivers = ['swrast'] + else + error('Unknown OS @0@. Please pass -Dgallium-drivers to set driver options. Patches gladly accepted to fix this.'.format( + host_machine.system())) + endif +endif +with_gallium_pl111 = _drivers.contains('pl111') +with_gallium_radeonsi = _drivers.contains('radeonsi') +with_gallium_r300 = _drivers.contains('r300') +with_gallium_r600 = _drivers.contains('r600') +with_gallium_nouveau = _drivers.contains('nouveau') +with_gallium_freedreno = _drivers.contains('freedreno') +with_gallium_softpipe = _drivers.contains('swrast') +with_gallium_vc4 = _drivers.contains('vc4') +with_gallium_v3d = _drivers.contains('v3d') +with_gallium_etnaviv = _drivers.contains('etnaviv') +with_gallium_imx = _drivers.contains('imx') +with_gallium_tegra = _drivers.contains('tegra') +with_gallium_i915 = _drivers.contains('i915') +with_gallium_svga = _drivers.contains('svga') +with_gallium_virgl = _drivers.contains('virgl') +with_gallium_swr = _drivers.contains('swr') + +with_gallium = _drivers.length() != 0 and _drivers != [''] + +if with_gallium and system_has_kms_drm + _glx = get_option('glx') + _egl = get_option('egl') + if _glx == 'dri' or _egl == 'true' or (_glx == 'disabled' and _egl != 'false') + with_dri = true + endif +endif + +_vulkan_drivers = get_option('vulkan-drivers') +if _vulkan_drivers.contains('auto') + if system_has_kms_drm + if host_machine.cpu_family().startswith('x86') + _vulkan_drivers = ['amd', 'intel'] + elif ['arm', 'aarch64'].contains(host_machine.cpu_family()) + _vulkan_drivers = [] + else + error('Unknown architecture @0@. Please pass -Dvulkan-drivers to set driver options. Patches gladly accepted to fix this.'.format( + host_machine.cpu_family())) + endif + elif ['darwin', 'windows', 'cygwin', 'haiku'].contains(host_machine.system()) + # No vulkan driver supports windows or macOS currently + _vulkan_drivers = [] + else + error('Unknown OS @0@. Please pass -Dvulkan-drivers to set driver options. Patches gladly accepted to fix this.'.format( + host_machine.system())) + endif +endif + +with_intel_vk = _vulkan_drivers.contains('intel') +with_amd_vk = _vulkan_drivers.contains('amd') +with_any_vk = _vulkan_drivers.length() != 0 and _vulkan_drivers != [''] + +if with_dri_swrast and (with_gallium_softpipe or with_gallium_swr) + error('Only one swrast provider can be built') +endif +if with_dri_i915 and with_gallium_i915 + error('Only one i915 provider can be built') +endif +if with_gallium_imx and not with_gallium_etnaviv + error('IMX driver requires etnaviv driver') +endif +if with_gallium_pl111 and not with_gallium_vc4 + error('pl111 driver requires vc4 driver') +endif +if with_gallium_tegra and not with_gallium_nouveau + error('tegra driver requires nouveau driver') +endif + +if host_machine.system() == 'darwin' + with_dri_platform = 'apple' +elif ['windows', 'cygwin'].contains(host_machine.system()) + with_dri_platform = 'windows' +elif system_has_kms_drm + with_dri_platform = 'drm' +else + # FIXME: haiku doesn't use dri, and xlib doesn't use dri, probably should + # assert here that one of those cases has been met. + # FIXME: illumos ends up here as well + with_dri_platform = 'none' +endif + +_platforms = get_option('platforms') +if _platforms.contains('auto') + if system_has_kms_drm + _platforms = ['x11', 'wayland', 'drm', 'surfaceless'] + elif ['darwin', 'windows', 'cygwin'].contains(host_machine.system()) + _platforms = ['x11', 'surfaceless'] + elif ['haiku'].contains(host_machine.system()) + _platforms = ['haiku'] + else + error('Unknown OS @0@. Please pass -Dplatforms to set platforms. Patches gladly accepted to fix this.'.format( + host_machine.system())) + endif +endif + +with_platform_android = _platforms.contains('android') +with_platform_x11 = _platforms.contains('x11') +with_platform_wayland = _platforms.contains('wayland') +with_platform_drm = _platforms.contains('drm') +with_platform_haiku = _platforms.contains('haiku') +with_platform_surfaceless = _platforms.contains('surfaceless') + +with_platforms = false +if _platforms.length() != 0 and _platforms != [''] + with_platforms = true + egl_native_platform = _platforms[0] +endif + +_xlib_lease = get_option('xlib-lease') +if _xlib_lease == 'auto' + with_xlib_lease = with_platform_x11 and with_platform_drm +else + with_xlib_lease = _xlib_lease == 'true' +endif + +with_glx = get_option('glx') +if with_glx == 'auto' + if with_dri + with_glx = 'dri' + elif with_platform_haiku + with_glx = 'disabled' + elif with_gallium + # Even when building just gallium drivers the user probably wants dri + with_glx = 'dri' + elif with_platform_x11 and with_any_opengl and not with_any_vk + # The automatic behavior should not be to turn on xlib based glx when + # building only vulkan drivers + with_glx = 'xlib' + else + with_glx = 'disabled' + endif +endif +if with_glx == 'dri' + if with_gallium + with_dri = true + endif +endif + +if not (with_dri or with_gallium or with_glx == 'xlib' or with_glx == 'gallium-xlib') + with_gles1 = false + with_gles2 = false + with_opengl = false + with_any_opengl = false + with_shared_glapi = false +endif + +_gbm = get_option('gbm') +if _gbm == 'auto' + with_gbm = system_has_kms_drm and with_dri +else + with_gbm = _gbm == 'true' +endif +if with_gbm and not system_has_kms_drm + error('GBM only supports DRM/KMS platforms') +endif + +_egl = get_option('egl') +if _egl == 'auto' + with_egl = ( + not ['darwin', 'windows'].contains(host_machine.system()) and + with_dri and with_shared_glapi and with_platforms + ) +elif _egl == 'true' + if not with_dri + error('EGL requires dri') + elif not with_shared_glapi + error('EGL requires shared-glapi') + elif not with_platforms + error('No platforms specified, consider -Dplatforms=drm,x11,surfaceless at least') + elif not ['disabled', 'dri'].contains(with_glx) + error('EGL requires dri, but a GLX is being built without dri') + elif ['darwin', 'windows'].contains(host_machine.system()) + error('EGL is not available on Windows or MacOS') + endif + with_egl = true +else + with_egl = false +endif + +if with_egl and not (with_platform_drm or with_platform_surfaceless) + if with_gallium_radeonsi + error('RadeonSI requires drm or surfaceless platform when using EGL') + endif + if with_gallium_virgl + error('Virgl requires drm or surfaceless platform when using EGL') + endif +endif + +pre_args += '-DGLX_USE_TLS' +if with_glx != 'disabled' + if not (with_platform_x11 and with_any_opengl) + error('Cannot build GLX support without X11 platform support and at least one OpenGL API') + elif with_glx == 'gallium-xlib' + if not with_gallium + error('Gallium-xlib based GLX requires at least one gallium driver') + elif not with_gallium_softpipe + error('Gallium-xlib based GLX requires softpipe or llvmpipe.') + elif with_dri + error('gallium-xlib conflicts with any dri driver') + endif + elif with_glx == 'xlib' + if with_dri + error('xlib conflicts with any dri driver') + endif + elif with_glx == 'dri' + if not with_dri + error('dri based GLX requires at least one DRI driver') + elif not with_shared_glapi + error('dri based GLX requires shared-glapi') + endif + endif +endif + +with_glvnd = get_option('glvnd') +if with_glvnd + if with_glx == 'xlib' or with_glx == 'gallium-xlib' + error('Cannot build glvnd support for GLX that is not DRI based.') + elif with_glx == 'disabled' and not with_egl + error('glvnd requires DRI based GLX and/or EGL') + endif +endif + +if with_vulkan_icd_dir == '' + with_vulkan_icd_dir = join_paths(get_option('datadir'), 'vulkan/icd.d') +endif + +with_dri2 = (with_dri or with_any_vk) and with_dri_platform == 'drm' +_dri3 = get_option('dri3') +if _dri3 == 'auto' + with_dri3 = system_has_kms_drm and with_dri2 +else + with_dri3 = _dri3 == 'true' +endif + +if with_any_vk and (with_platform_x11 and not with_dri3) + error('Vulkan drivers require dri3 for X11 support') +endif +if with_dri + if with_glx == 'disabled' and not with_egl and not with_gbm + error('building dri drivers require at least one windowing system') + endif +endif + +prog_pkgconfig = find_program('pkg-config') + +_vdpau = get_option('gallium-vdpau') +if not system_has_kms_drm + if _vdpau == 'true' + error('VDPAU state tracker can only be build on unix-like OSes.') + else + _vdpau = 'false' + endif +elif not with_platform_x11 + if _vdpau == 'true' + error('VDPAU state tracker requires X11 support.') + else + _vdpau = 'false' + endif +elif not (with_gallium_r300 or with_gallium_r600 or with_gallium_radeonsi or + with_gallium_nouveau) + if _vdpau == 'true' + error('VDPAU state tracker requires at least one of the following gallium drivers: r300, r600, radeonsi, nouveau.') + else + _vdpau = 'false' + endif +endif +dep_vdpau = null_dep +with_gallium_vdpau = false +if _vdpau != 'false' + dep_vdpau = dependency('vdpau', version : '>= 1.1', required : _vdpau == 'true') + if dep_vdpau.found() + dep_vdpau = declare_dependency( + compile_args : run_command(prog_pkgconfig, ['vdpau', '--cflags']).stdout().split() + ) + with_gallium_vdpau = true + endif +endif + +if with_gallium_vdpau + pre_args += '-DHAVE_ST_VDPAU' +endif +vdpau_drivers_path = get_option('vdpau-libs-path') +if vdpau_drivers_path == '' + vdpau_drivers_path = join_paths(get_option('libdir'), 'vdpau') +endif + +_xvmc = get_option('gallium-xvmc') +if not system_has_kms_drm + if _xvmc == 'true' + error('XVMC state tracker can only be build on unix-like OSes.') + else + _xvmc = 'false' + endif +elif not with_platform_x11 + if _xvmc == 'true' + error('XVMC state tracker requires X11 support.') + else + _xvmc = 'false' + endif +elif not (with_gallium_r600 or with_gallium_nouveau) + if _xvmc == 'true' + error('XVMC state tracker requires at least one of the following gallium drivers: r600, nouveau.') + else + _xvmc = 'false' + endif +endif +dep_xvmc = null_dep +with_gallium_xvmc = false +if _xvmc != 'false' + dep_xvmc = dependency('xvmc', version : '>= 1.0.6', required : _xvmc == 'true') + with_gallium_xvmc = dep_xvmc.found() +endif + +xvmc_drivers_path = get_option('xvmc-libs-path') +if xvmc_drivers_path == '' + xvmc_drivers_path = get_option('libdir') +endif + +_omx = get_option('gallium-omx') +if not system_has_kms_drm + if ['auto', 'disabled'].contains(_omx) + _omx = 'disabled' + else + error('OMX state tracker can only be built on unix-like OSes.') + endif +elif not (with_platform_x11 or with_platform_drm) + if ['auto', 'disabled'].contains(_omx) + _omx = 'disabled' + else + error('OMX state tracker requires X11 or drm platform support.') + endif +elif not (with_gallium_r600 or with_gallium_radeonsi or with_gallium_nouveau) + if ['auto', 'disabled'].contains(_omx) + _omx = 'disabled' + else + error('OMX state tracker requires at least one of the following gallium drivers: r600, radeonsi, nouveau.') + endif +endif +with_gallium_omx = _omx +dep_omx = null_dep +dep_omx_other = [] +if ['auto', 'bellagio'].contains(_omx) + dep_omx = dependency( + 'libomxil-bellagio', required : _omx == 'bellagio' + ) + if dep_omx.found() + with_gallium_omx = 'bellagio' + endif +endif +if ['auto', 'tizonia'].contains(_omx) + if with_dri and with_egl + dep_omx = dependency( + 'libtizonia', version : '>= 0.10.0', + required : _omx == 'tizonia', + ) + dep_omx_other = [ + dependency('libtizplatform', required : _omx == 'tizonia'), + dependency('tizilheaders', required : _omx == 'tizonia'), + ] + if dep_omx.found() and dep_omx_other[0].found() and dep_omx_other[1].found() + with_gallium_omx = 'tizonia' + endif + elif _omx == 'tizonia' + error('OMX-Tizonia state tracker requires dri and egl') + endif +endif +if _omx == 'auto' + with_gallium_omx = 'disabled' +else + with_gallium_omx = _omx +endif + +pre_args += [ + '-DENABLE_ST_OMX_BELLAGIO=' + (with_gallium_omx == 'bellagio' ? '1' : '0'), + '-DENABLE_ST_OMX_TIZONIA=' + (with_gallium_omx == 'tizonia' ? '1' : '0'), +] + + +omx_drivers_path = get_option('omx-libs-path') + +if with_gallium_omx != 'disabled' + # Figure out where to put the omx driver. + # FIXME: this could all be vastly simplified by adding a 'defined_variable' + # argument to meson's get_pkgconfig_variable method. + if omx_drivers_path == '' + _omx_libdir = dep_omx.get_pkgconfig_variable('libdir') + _omx_drivers_dir = dep_omx.get_pkgconfig_variable('pluginsdir') + if _omx_libdir == get_option('libdir') + omx_drivers_path = _omx_drivers_dir + else + _omx_base_dir = [] + # This will fail on windows. Does OMX run on windows? + _omx_libdir = _omx_libdir.split('/') + _omx_drivers_dir = _omx_drivers_dir.split('/') + foreach o : _omx_drivers_dir + if not _omx_libdir.contains(o) + _omx_base_dir += o + endif + endforeach + omx_drivers_path = join_paths(get_option('libdir'), _omx_base_dir) + endif + endif +endif + +_va = get_option('gallium-va') +if not system_has_kms_drm + if _va == 'true' + error('VA state tracker can only be built on unix-like OSes.') + else + _va = 'false' + endif +elif not (with_platform_x11 or with_platform_drm) + if _va == 'true' + error('VA state tracker requires X11 or drm or wayland platform support.') + else + _va = 'false' + endif +elif not (with_gallium_r600 or with_gallium_radeonsi or with_gallium_nouveau) + if _va == 'true' + error('VA state tracker requires at least one of the following gallium drivers: r600, radeonsi, nouveau.') + else + _va = 'false' + endif +endif +with_gallium_va = false +dep_va = null_dep +if _va != 'false' + dep_va = dependency('libva', version : '>= 0.38.0', required : _va == 'true') + if dep_va.found() + dep_va_headers = declare_dependency( + compile_args : run_command(prog_pkgconfig, ['libva', '--cflags']).stdout().split() + ) + with_gallium_va = true + endif +endif + +va_drivers_path = get_option('va-libs-path') +if va_drivers_path == '' + va_drivers_path = join_paths(get_option('libdir'), 'dri') +endif + +_xa = get_option('gallium-xa') +if not system_has_kms_drm + if _xa == 'true' + error('XA state tracker can only be built on unix-like OSes.') + else + _xa = 'false' + endif +elif not (with_gallium_nouveau or with_gallium_freedreno or with_gallium_i915 + or with_gallium_svga) + if _xa == 'true' + error('XA state tracker requires at least one of the following gallium drivers: nouveau, freedreno, i915, svga.') + else + _xa = 'false' + endif +endif +with_gallium_xa = _xa != 'false' + +d3d_drivers_path = get_option('d3d-drivers-path') +if d3d_drivers_path == '' + d3d_drivers_path = join_paths(get_option('libdir'), 'd3d') +endif + +with_gallium_st_nine = get_option('gallium-nine') +if with_gallium_st_nine + if not with_gallium_softpipe + error('The nine state tracker requires gallium softpipe/llvmpipe.') + elif not (with_gallium_radeonsi or with_gallium_nouveau or with_gallium_r600 + or with_gallium_r300 or with_gallium_svga or with_gallium_i915) + error('The nine state tracker requires at least one non-swrast gallium driver.') + endif + if not with_dri3 + error('Using nine with wine requires dri3') + endif +endif + +if get_option('power8') != 'false' + # on old versions of meson the cpu family would return as ppc64le on little + # endian power8, this was changed in 0.48 such that the family would always + # be ppc64 regardless of endianness, and the the machine.endian() value + # should be checked. Since we support versions < 0.48 we need to use + # startswith. + if host_machine.cpu_family().startswith('ppc64') and host_machine.endian() == 'little' + if cc.get_id() == 'gcc' and cc.version().version_compare('< 4.8') + error('Altivec is not supported with gcc version < 4.8.') + endif + if cc.compiles(''' + #include <altivec.h> + int main() { + vector unsigned char r; + vector unsigned int v = vec_splat_u32 (1); + r = __builtin_vec_vgbbd ((vector unsigned char) v); + return 0; + }''', + args : '-mpower8-vector', + name : 'POWER8 intrinsics') + pre_args += ['-D_ARCH_PWR8', '-mpower8-vector'] + elif get_option('power8') == 'true' + error('POWER8 intrinsic support required but not found.') + endif + endif +endif + +_opencl = get_option('gallium-opencl') +clover_cpp_std = [] +if _opencl != 'disabled' + if not with_gallium + error('OpenCL Clover implementation requires at least one gallium driver.') + endif + + dep_clc = dependency('libclc') + with_gallium_opencl = true + with_opencl_icd = _opencl == 'icd' + + if host_machine.cpu_family().startswith('ppc') and cpp.compiles(''' + #if !defined(__VEC__) || !defined(__ALTIVEC__) + #error "AltiVec not enabled" + #endif''', + name : 'Altivec') + clover_cpp_std += ['cpp_std=gnu++11'] + endif +else + dep_clc = null_dep + with_gallium_opencl = false + with_gallium_icd = false +endif + +gl_pkgconfig_c_flags = [] +if with_platform_x11 + if with_any_vk or with_egl or (with_glx == 'dri' and with_dri_platform == 'drm') + pre_args += '-DHAVE_X11_PLATFORM' + endif + if with_glx == 'xlib' or with_glx == 'gallium-xlib' + pre_args += '-DUSE_XSHM' + else + pre_args += '-DGLX_INDIRECT_RENDERING' + if with_glx_direct + pre_args += '-DGLX_DIRECT_RENDERING' + endif + if with_dri_platform == 'drm' + pre_args += '-DGLX_USE_DRM' + elif with_dri_platform == 'apple' + pre_args += '-DGLX_USE_APPLEGL' + elif with_dri_platform == 'windows' + pre_args += '-DGLX_USE_WINDOWSGL' + endif + endif +else + pre_args += '-DMESA_EGL_NO_X11_HEADERS' + gl_pkgconfig_c_flags += '-DMESA_EGL_NO_X11_HEADERS' +endif +if with_platform_drm + if with_egl and not with_gbm + error('EGL drm platform requires gbm') + endif + pre_args += '-DHAVE_DRM_PLATFORM' +endif +if with_platform_surfaceless + pre_args += '-DHAVE_SURFACELESS_PLATFORM' +endif +if with_platform_android + dep_android = [ + dependency('cutils'), + dependency('hardware'), + dependency('sync'), + ] + pre_args += '-DHAVE_ANDROID_PLATFORM' +endif +if with_platform_haiku + pre_args += '-DHAVE_HAIKU_PLATFORM' +endif + +prog_python = import('python3').find_python() +has_mako = run_command( + prog_python, '-c', + ''' +from distutils.version import StrictVersion +import mako +assert StrictVersion(mako.__version__) > StrictVersion("0.8.0") + ''') +if has_mako.returncode() != 0 + error('Python (3.x) mako module >= 0.8.0 required to build mesa.') +endif + +if cc.get_id() == 'gcc' and cc.version().version_compare('< 4.4.6') + error('When using GCC, version 4.4.6 or later is required.') +endif + +# Define DEBUG for debug builds only (debugoptimized is not included on this one) +if get_option('buildtype') == 'debug' + pre_args += '-DDEBUG' +endif + +if get_option('shader-cache') + pre_args += '-DENABLE_SHADER_CACHE' +elif with_amd_vk + error('Radv requires shader cache support') +endif + +# Check for GCC style builtins +foreach b : ['bswap32', 'bswap64', 'clz', 'clzll', 'ctz', 'expect', 'ffs', + 'ffsll', 'popcount', 'popcountll', 'unreachable'] + if cc.has_function(b) + pre_args += '-DHAVE___BUILTIN_@0@'.format(b.to_upper()) + endif +endforeach + +# check for GCC __attribute__ +foreach a : ['const', 'flatten', 'malloc', 'pure', 'unused', + 'warn_unused_result', 'weak',] + if cc.compiles('int foo(void) __attribute__((@0@));'.format(a), + name : '__attribute__((@0@))'.format(a)) + pre_args += '-DHAVE_FUNC_ATTRIBUTE_@0@'.format(a.to_upper()) + endif +endforeach +if cc.compiles('int foo(const char *p, ...) __attribute__((format(printf, 1, 2)));', + name : '__attribute__((format(...)))') + pre_args += '-DHAVE_FUNC_ATTRIBUTE_FORMAT' +endif +if cc.compiles('struct __attribute__((packed)) foo { int bar; };', + name : '__attribute__((packed))') + pre_args += '-DHAVE_FUNC_ATTRIBUTE_PACKED' +endif +if cc.compiles('int *foo(void) __attribute__((returns_nonnull));', + name : '__attribute__((returns_nonnull))') + pre_args += '-DHAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL' +endif +if cc.compiles('''int foo_def(void) __attribute__((visibility("default"))); + int foo_hid(void) __attribute__((visibility("hidden"))); + int foo_int(void) __attribute__((visibility("internal"))); + int foo_pro(void) __attribute__((visibility("protected")));''', + name : '__attribute__((visibility(...)))') + pre_args += '-DHAVE_FUNC_ATTRIBUTE_VISIBILITY' +endif +if cc.compiles('int foo(void) { return 0; } int bar(void) __attribute__((alias("foo")));', + name : '__attribute__((alias(...)))') + pre_args += '-DHAVE_FUNC_ATTRIBUTE_ALIAS' +endif +if cc.compiles('int foo(void) __attribute__((__noreturn__));', + name : '__attribute__((__noreturn__))') + pre_args += '-DHAVE_FUNC_ATTRIBUTE_NORETURN' +endif + +# TODO: this is very incomplete +if ['linux', 'cygwin', 'gnu'].contains(host_machine.system()) + pre_args += '-D_GNU_SOURCE' +endif + +# Check for generic C arguments +c_args = [] +foreach a : ['-Werror=implicit-function-declaration', + '-Werror=missing-prototypes', '-Werror=return-type', + '-fno-math-errno', + '-fno-trapping-math', '-Qunused-arguments'] + if cc.has_argument(a) + c_args += a + endif +endforeach + +foreach a : ['missing-field-initializers', 'format-truncation'] + if cc.has_argument('-W' + a) + c_args += '-Wno-' + a + endif +endforeach + +c_vis_args = [] +if cc.has_argument('-fvisibility=hidden') + c_vis_args += '-fvisibility=hidden' +endif + +# Check for generic C++ arguments +cpp_args = [] +foreach a : ['-Werror=return-type', + '-fno-math-errno', '-fno-trapping-math', + '-Qunused-arguments'] + if cpp.has_argument(a) + cpp_args += a + endif +endforeach + +# For some reason, the test for -Wno-foo always succeeds with gcc, even if the +# option is not supported. Hence, check for -Wfoo instead. + +foreach a : ['non-virtual-dtor', 'missing-field-initializers', 'format-truncation'] + if cpp.has_argument('-W' + a) + cpp_args += '-Wno-' + a + endif +endforeach + +no_override_init_args = [] +foreach a : ['override-init', 'initializer-overrides'] + if cc.has_argument('-W' + a) + no_override_init_args += '-Wno-' + a + endif +endforeach + +cpp_vis_args = [] +if cpp.has_argument('-fvisibility=hidden') + cpp_vis_args += '-fvisibility=hidden' +endif + +# Check for C and C++ arguments for MSVC2013 compatibility. These are only used +# in parts of the mesa code base that need to compile with old versions of +# MSVC, mainly common code +c_msvc_compat_args = [] +cpp_msvc_compat_args = [] +foreach a : ['-Werror=pointer-arith', '-Werror=vla'] + if cc.has_argument(a) + c_msvc_compat_args += a + endif + if cpp.has_argument(a) + cpp_msvc_compat_args += a + endif +endforeach + +if host_machine.cpu_family().startswith('x86') + pre_args += '-DUSE_SSE41' + with_sse41 = true + sse41_args = ['-msse4.1'] + + # GCC on x86 (not x86_64) with -msse* assumes a 16 byte aligned stack, but + # that's not guaranteed + if host_machine.cpu_family() == 'x86' + sse41_args += '-mstackrealign' + endif +else + with_sse41 = false + sse41_args = [] +endif + +# Check for GCC style atomics +dep_atomic = null_dep + +if cc.compiles('''#include <stdint.h> + int main() { + struct { + uint64_t *v; + } x; + return (int)__atomic_load_n(x.v, __ATOMIC_ACQUIRE) & + (int)__atomic_add_fetch(x.v, (uint64_t)1, __ATOMIC_ACQ_REL); + + }''', + name : 'GCC atomic builtins') + pre_args += '-DUSE_GCC_ATOMIC_BUILTINS' + + # Not all atomic calls can be turned into lock-free instructions, in which + # GCC will make calls into the libatomic library. Check whether we need to + # link with -latomic. + # + # This can happen for 64-bit atomic operations on 32-bit architectures such + # as ARM. + if not cc.links('''#include <stdint.h> + int main() { + struct { + uint64_t *v; + } x; + return (int)__atomic_load_n(x.v, __ATOMIC_ACQUIRE) & + (int)__atomic_add_fetch(x.v, (uint64_t)1, __ATOMIC_ACQ_REL); + }''', + name : 'GCC atomic builtins required -latomic') + dep_atomic = cc.find_library('atomic') + endif +endif +if not cc.links('''#include <stdint.h> + uint64_t v; + int main() { + return __sync_add_and_fetch(&v, (uint64_t)1); + }''', + dependencies : dep_atomic, + name : 'GCC 64bit atomics') + pre_args += '-DMISSING_64BIT_ATOMICS' +endif + +# TODO: shared/static? Is this even worth doing? + +# When cross compiling we generally need to turn off the use of assembly, +# because mesa's assembly relies on building an executable for the host system, +# and running it to get information about struct sizes. There is at least one +# case of cross compiling where we can use asm, and that's x86_64 -> x86 when +# host OS == build OS, since in that case the build machine can run the host's +# binaries. +if meson.is_cross_build() + if build_machine.system() != host_machine.system() + # TODO: It may be possible to do this with an exe_wrapper (like wine). + message('Cross compiling from one OS to another, disabling assembly.') + with_asm = false + elif not (build_machine.cpu_family().startswith('x86') and host_machine.cpu_family() == 'x86') + # FIXME: Gentoo always sets -m32 for x86_64 -> x86 builds, resulting in an + # x86 -> x86 cross compile. We use startswith rather than == to handle this + # case. + # TODO: There may be other cases where the 64 bit version of the + # architecture can run 32 bit binaries (aarch64 and armv7 for example) + message(''' + Cross compiling to different architectures, and the host cannot run + the build machine's binaries. Disabling assembly. + ''') + with_asm = false + endif +endif + +with_asm_arch = '' +if with_asm + if host_machine.cpu_family() == 'x86' + if system_has_kms_drm or host_machine.system() == 'gnu' + with_asm_arch = 'x86' + pre_args += ['-DUSE_X86_ASM', '-DUSE_MMX_ASM', '-DUSE_3DNOW_ASM', + '-DUSE_SSE_ASM'] + + if with_glx_read_only_text + pre_args += ['-DGLX_X86_READONLY_TEXT'] + endif + endif + elif host_machine.cpu_family() == 'x86_64' + if system_has_kms_drm + with_asm_arch = 'x86_64' + pre_args += ['-DUSE_X86_64_ASM'] + endif + elif host_machine.cpu_family() == 'arm' + if system_has_kms_drm + with_asm_arch = 'arm' + pre_args += ['-DUSE_ARM_ASM'] + endif + elif host_machine.cpu_family() == 'aarch64' + if system_has_kms_drm + with_asm_arch = 'aarch64' + pre_args += ['-DUSE_AARCH64_ASM'] + endif + elif host_machine.cpu_family() == 'sparc64' + if system_has_kms_drm + with_asm_arch = 'sparc' + pre_args += ['-DUSE_SPARC_ASM'] + endif + elif host_machine.cpu_family().startswith('ppc64') and host_machine.endian() == 'little' + if system_has_kms_drm + with_asm_arch = 'ppc64le' + pre_args += ['-DUSE_PPC64LE_ASM'] + endif + endif +endif + +# Check for standard headers and functions +if cc.has_header_symbol('sys/sysmacros.h', 'major') + pre_args += '-DMAJOR_IN_SYSMACROS' +elif cc.has_header_symbol('sys/mkdev.h', 'major') + pre_args += '-DMAJOR_IN_MKDEV' +endif + +foreach h : ['xlocale.h', 'sys/sysctl.h', 'linux/futex.h', 'endian.h', 'dlfcn.h'] + if cc.compiles('#include <@0@>'.format(h), name : '@0@'.format(h)) + pre_args += '-DHAVE_@0@'.format(h.to_upper().underscorify()) + endif +endforeach + +foreach f : ['strtof', 'mkostemp', 'posix_memalign', 'timespec_get', 'memfd_create'] + if cc.has_function(f) + pre_args += '-DHAVE_@0@'.format(f.to_upper()) + endif +endforeach + +# strtod locale support +if cc.links(''' + #define _GNU_SOURCE + #include <stdlib.h> + #include <locale.h> + #ifdef HAVE_XLOCALE_H + #include <xlocale.h> + #endif + int main() { + locale_t loc = newlocale(LC_CTYPE_MASK, "C", NULL); + const char *s = "1.0"; + char *end; + double d = strtod_l(s, end, loc); + float f = strtof_l(s, end, loc); + freelocale(loc); + return 0; + }''', + args : pre_args, + name : 'strtod has locale support') + pre_args += '-DHAVE_STRTOD_L' +endif + +# Check for some linker flags +ld_args_bsymbolic = [] +if cc.links('int main() { return 0; }', args : '-Wl,-Bsymbolic', name : 'Bsymbolic') + ld_args_bsymbolic += '-Wl,-Bsymbolic' +endif +ld_args_gc_sections = [] +if cc.links('static char unused() { return 5; } int main() { return 0; }', + args : '-Wl,--gc-sections', name : 'gc-sections') + ld_args_gc_sections += '-Wl,--gc-sections' +endif +with_ld_version_script = false +if cc.links('int main() { return 0; }', + args : '-Wl,--version-script=@0@'.format( + join_paths(meson.source_root(), 'build-support/conftest.map')), + name : 'version-script') + with_ld_version_script = true +endif +with_ld_dynamic_list = false +if cc.links('int main() { return 0; }', + args : '-Wl,--dynamic-list=@0@'.format( + join_paths(meson.source_root(), 'build-support/conftest.dyn')), + name : 'dynamic-list') + with_ld_dynamic_list = true +endif +ld_args_build_id = [] +if build_machine.system() != 'darwin' + ld_args_build_id += '-Wl,--build-id=sha1' +endif + +# check for dl support +if cc.has_function('dlopen') + dep_dl = null_dep +else + dep_dl = cc.find_library('dl') +endif +if cc.has_function('dladdr', dependencies : dep_dl) + # This is really only required for megadrivers + pre_args += '-DHAVE_DLADDR' +endif + +if cc.has_function('dl_iterate_phdr') + pre_args += '-DHAVE_DL_ITERATE_PHDR' +elif with_intel_vk + error('Intel "Anvil" Vulkan driver requires the dl_iterate_phdr function') +elif with_dri_i965 and get_option('shader-cache') + error('Intel i965 GL driver requires dl_iterate_phdr when built with shader caching.') +endif + +# Determine whether or not the rt library is needed for time functions +if cc.has_function('clock_gettime') + dep_clock = null_dep +else + dep_clock = cc.find_library('rt') +endif + +# TODO: some of these may be conditional +dep_zlib = dependency('zlib', version : '>= 1.2.3') +pre_args += '-DHAVE_ZLIB' +dep_thread = dependency('threads') +if dep_thread.found() and host_machine.system() != 'windows' + pre_args += '-DHAVE_PTHREAD' + if cc.has_function( + 'pthread_setaffinity_np', + dependencies : dep_thread, + prefix : '#include <pthread.h>', + args : '-D_GNU_SOURCE') + pre_args += '-DHAVE_PTHREAD_SETAFFINITY' + endif +endif +dep_expat = dependency('expat') +# this only exists on linux so either this is linux and it will be found, or +# its not linux and and wont +dep_m = cc.find_library('m', required : false) + +# Check for libdrm. various drivers have different libdrm version requirements, +# but we always want to use the same version for all libdrm modules. That means +# even if driver foo requires 2.4.0 and driver bar requires 2.4.3, if foo and +# bar are both on use 2.4.3 for both of them +dep_libdrm_amdgpu = null_dep +dep_libdrm_radeon = null_dep +dep_libdrm_nouveau = null_dep +dep_libdrm_etnaviv = null_dep +dep_libdrm_intel = null_dep + +_drm_amdgpu_ver = '2.4.95' +_drm_radeon_ver = '2.4.71' +_drm_nouveau_ver = '2.4.66' +_drm_etnaviv_ver = '2.4.89' +_drm_intel_ver = '2.4.75' +_drm_ver = '2.4.75' + +_libdrm_checks = [ + ['intel', with_dri_i915 or with_gallium_i915], + ['amdgpu', with_amd_vk or with_gallium_radeonsi], + ['radeon', (with_gallium_radeonsi or with_dri_r100 or with_dri_r200 or + with_gallium_r300 or with_gallium_r600)], + ['nouveau', (with_gallium_nouveau or with_dri_nouveau)], + ['etnaviv', with_gallium_etnaviv], +] + +# VC4 only needs core libdrm support of this version, not a libdrm_vc4 +# library. +if with_gallium_vc4 + _drm_ver = '2.4.89' +endif + +# Loop over the enables versions and get the highest libdrm requirement for all +# active drivers. +_drm_blame = '' +foreach d : _libdrm_checks + ver = get_variable('_drm_@0@_ver'.format(d[0])) + if d[1] and ver.version_compare('>' + _drm_ver) + _drm_ver = ver + _drm_blame = d[0] + endif +endforeach +if _drm_blame != '' + message('libdrm @0@ needed because @1@ has the highest requirement'.format(_drm_ver, _drm_blame)) +endif + +# Then get each libdrm module +foreach d : _libdrm_checks + if d[1] + set_variable( + 'dep_libdrm_' + d[0], + dependency('libdrm_' + d[0], version : '>=' + _drm_ver) + ) + endif +endforeach + +with_gallium_drisw_kms = false +dep_libdrm = dependency( + 'libdrm', version : '>=' + _drm_ver, + required : with_dri2 or with_dri3 +) +if dep_libdrm.found() + pre_args += '-DHAVE_LIBDRM' + if with_dri_platform == 'drm' and with_dri + with_gallium_drisw_kms = true + endif +endif + +llvm_modules = ['bitwriter', 'engine', 'mcdisassembler', 'mcjit'] +llvm_optional_modules = [] +if with_amd_vk or with_gallium_radeonsi or with_gallium_r600 + llvm_modules += ['amdgpu', 'native', 'bitreader', 'ipo'] + if with_gallium_r600 + llvm_modules += 'asmparser' + endif +endif +if with_gallium_opencl + llvm_modules += [ + 'all-targets', 'linker', 'coverage', 'instrumentation', 'ipo', 'irreader', + 'lto', 'option', 'objcarcopts', 'profiledata', + ] + llvm_optional_modules += ['coroutines'] +endif + +if with_amd_vk or with_gallium_radeonsi + _llvm_version = '>= 6.0.0' +elif with_gallium_swr + _llvm_version = '>= 6.0.0' +elif with_gallium_opencl or with_gallium_r600 + _llvm_version = '>= 3.9.0' +else + _llvm_version = '>= 3.3.0' +endif + +_shared_llvm = get_option('shared-llvm') + +_llvm = get_option('llvm') +dep_llvm = null_dep +with_llvm = false +if _llvm != 'false' + dep_llvm = dependency( + 'llvm', + version : _llvm_version, + modules : llvm_modules, + optional_modules : llvm_optional_modules, + required : ( + with_amd_vk or with_gallium_radeonsi or with_gallium_swr or + with_gallium_opencl or _llvm == 'true' + ), + static : not _shared_llvm, + ) + with_llvm = dep_llvm.found() +endif +if with_llvm + _llvm_version = dep_llvm.version().split('.') + + # 3 digits versions in LLVM only started from 3.4.1 on + if dep_llvm.version().version_compare('>= 3.4.1') + _llvm_patch = _llvm_version[2] + else + _llvm_patch = '0' + endif + + pre_args += [ + '-DHAVE_LLVM=0x0@0@0@1@'.format(_llvm_version[0], _llvm_version[1]), + '-DMESA_LLVM_VERSION_PATCH=@0@'.format(_llvm_patch), + ] + + # LLVM can be built without rtti, turning off rtti changes the ABI of C++ + # programs, so we need to build all C++ code in mesa without rtti as well to + # ensure that linking works. + if dep_llvm.get_configtool_variable('has-rtti') == 'NO' + if with_gallium_nouveau + error('The Nouveau driver requires rtti. You either need to turn off nouveau or use an LLVM built with LLVM_ENABLE_RTTI.') + endif + cpp_args += '-fno-rtti' + endif +elif with_amd_vk or with_gallium_radeonsi or with_gallium_swr + error('The following drivers require LLVM: Radv, RadeonSI, SWR. One of these is enabled, but LLVM is disabled.') +endif + +if (with_amd_vk or with_gallium_radeonsi or with_gallium_opencl or + (with_gallium_r600 and with_llvm)) + dep_elf = dependency('libelf', required : false) + if not dep_elf.found() + dep_elf = cc.find_library('elf') + endif +else + dep_elf = null_dep +endif + +dep_glvnd = null_dep +if with_glvnd + dep_glvnd = dependency('libglvnd', version : '>= 0.2.0') + pre_args += '-DUSE_LIBGLVND=1' +endif + +if with_valgrind != 'false' + dep_valgrind = dependency('valgrind', required : with_valgrind == 'true') + if dep_valgrind.found() + pre_args += '-DHAVE_VALGRIND' + endif +else + dep_valgrind = null_dep +endif + +# pthread stubs. Lets not and say we didn't + +prog_bison = find_program('bison', required : with_any_opengl) +prog_flex = find_program('flex', required : with_any_opengl) + +dep_selinux = null_dep +if get_option('selinux') + dep_selinux = dependency('libselinux') + pre_args += '-DMESA_SELINUX' +endif + +if with_libunwind != 'false' + dep_unwind = dependency('libunwind', required : with_libunwind == 'true') + if dep_unwind.found() + pre_args += '-DHAVE_LIBUNWIND' + endif +else + dep_unwind = null_dep +endif + +if with_osmesa != 'none' + if with_osmesa == 'classic' and not with_dri_swrast + error('OSMesa classic requires dri (classic) swrast.') + endif + if with_osmesa == 'gallium' and not with_gallium_softpipe + error('OSMesa gallium requires gallium softpipe or llvmpipe.') + endif + osmesa_lib_name = 'OSMesa' + osmesa_bits = get_option('osmesa-bits') + if osmesa_bits != '8' + if with_dri or with_glx != 'disabled' + error('OSMesa bits must be 8 if building glx or dir based drivers') + endif + osmesa_lib_name = osmesa_lib_name + osmesa_bits + pre_args += [ + '-DCHAN_BITS=@0@'.format(osmesa_bits), '-DDEFAULT_SOFTWARE_DEPTH_BITS=31' + ] + endif +endif + +# TODO: symbol mangling + +if with_platform_wayland + dep_wl_scanner = dependency('wayland-scanner', native: true) + prog_wl_scanner = find_program(dep_wl_scanner.get_pkgconfig_variable('wayland_scanner')) + if dep_wl_scanner.version().version_compare('>= 1.15') + wl_scanner_arg = 'private-code' + else + wl_scanner_arg = 'code' + endif + dep_wl_protocols = dependency('wayland-protocols', version : '>= 1.8') + dep_wayland_client = dependency('wayland-client', version : '>=1.11') + dep_wayland_server = dependency('wayland-server', version : '>=1.11') + if with_egl + dep_wayland_egl = dependency('wayland-egl-backend', version : '>= 3') + dep_wayland_egl_headers = declare_dependency( + compile_args : run_command(prog_pkgconfig, ['wayland-egl-backend', '--cflags']).stdout().split()) + endif + wayland_dmabuf_xml = join_paths( + dep_wl_protocols.get_pkgconfig_variable('pkgdatadir'), 'unstable', + 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml' + ) + pre_args += ['-DHAVE_WAYLAND_PLATFORM', '-DWL_HIDE_DEPRECATED'] +endif + +dep_x11 = null_dep +dep_xext = null_dep +dep_xdamage = null_dep +dep_xfixes = null_dep +dep_x11_xcb = null_dep +dep_xcb = null_dep +dep_xcb_glx = null_dep +dep_xcb_dri2 = null_dep +dep_xcb_dri3 = null_dep +dep_dri2proto = null_dep +dep_glproto = null_dep +dep_xxf86vm = null_dep +dep_xcb_dri3 = null_dep +dep_xcb_present = null_dep +dep_xcb_sync = null_dep +dep_xcb_xfixes = null_dep +dep_xshmfence = null_dep +dep_xcb_xrandr = null_dep +dep_xlib_xrandr = null_dep +if with_platform_x11 + if with_glx == 'xlib' or with_glx == 'gallium-xlib' + dep_x11 = dependency('x11') + dep_xext = dependency('xext') + dep_xcb = dependency('xcb') + elif with_glx == 'dri' + dep_x11 = dependency('x11') + dep_xext = dependency('xext') + dep_xdamage = dependency('xdamage', version : '>= 1.1') + dep_xfixes = dependency('xfixes') + dep_xcb_glx = dependency('xcb-glx', version : '>= 1.8.1') + endif + if (with_any_vk or with_glx == 'dri' or + (with_gallium_vdpau or with_gallium_xvmc or with_gallium_va or + with_gallium_omx != 'disabled')) + dep_xcb = dependency('xcb') + dep_x11_xcb = dependency('x11-xcb') + endif + if with_any_vk or with_egl or (with_glx == 'dri' and with_dri_platform == 'drm') + dep_xcb_dri2 = dependency('xcb-dri2', version : '>= 1.8') + + if with_dri3 + pre_args += '-DHAVE_DRI3' + dep_xcb_dri3 = dependency('xcb-dri3') + dep_xcb_present = dependency('xcb-present') + # until xcb-dri3 has been around long enough to make a hard-dependency: + if (dep_xcb_dri3.version().version_compare('>= 1.13') and + dep_xcb_present.version().version_compare('>= 1.13')) + pre_args += '-DHAVE_DRI3_MODIFIERS' + endif + dep_xcb_sync = dependency('xcb-sync') + dep_xshmfence = dependency('xshmfence', version : '>= 1.1') + endif + endif + if with_glx == 'dri' + if with_dri_platform == 'drm' + dep_dri2proto = dependency('dri2proto', version : '>= 2.8') + dep_xxf86vm = dependency('xxf86vm') + endif + dep_glproto = dependency('glproto', version : '>= 1.4.14') + endif + if (with_egl or ( + with_gallium_vdpau or with_gallium_xvmc or with_gallium_xa or + with_gallium_omx != 'disabled')) + dep_xcb_xfixes = dependency('xcb-xfixes') + endif + if with_xlib_lease + dep_xcb_xrandr = dependency('xcb-randr', version : '>= 1.12') + dep_xlib_xrandr = dependency('xrandr', version : '>= 1.3') + endif +endif + +if get_option('gallium-extra-hud') + pre_args += '-DHAVE_GALLIUM_EXTRA_HUD=1' +endif + +_sensors = get_option('lmsensors') +if _sensors != 'false' + dep_lmsensors = cc.find_library('sensors', required : _sensors == 'true') + if dep_lmsensors.found() + pre_args += '-DHAVE_LIBSENSORS=1' + endif +else + dep_lmsensors = null_dep +endif + +foreach a : pre_args + add_project_arguments(a, language : ['c', 'cpp']) +endforeach +foreach a : c_args + add_project_arguments(a, language : ['c']) +endforeach +foreach a : cpp_args + add_project_arguments(a, language : ['cpp']) +endforeach + +inc_include = include_directories('include') + +gl_priv_reqs = [] + +if with_glx == 'xlib' or with_glx == 'gallium-xlib' + gl_priv_reqs += ['x11', 'xext', 'xcb'] +elif with_glx == 'dri' + gl_priv_reqs += [ + 'x11', 'xext', 'xdamage >= 1.1', 'xfixes', 'x11-xcb', 'xcb', + 'xcb-glx >= 1.8.1'] + if with_dri_platform == 'drm' + gl_priv_reqs += 'xcb-dri2 >= 1.8' + gl_priv_reqs += 'xxf86vm' + endif +endif +if dep_libdrm.found() + gl_priv_reqs += 'libdrm >= 2.4.75' +endif + +gl_priv_libs = [] +if dep_thread.found() + gl_priv_libs += ['-lpthread', '-pthread'] +endif +if dep_m.found() + gl_priv_libs += '-lm' +endif +if dep_dl.found() + gl_priv_libs += '-ldl' +endif + +pkg = import('pkgconfig') + +env_test = environment() +env_test.set('NM', find_program('nm').path()) + +subdir('include') +subdir('bin') +subdir('src') diff --git a/lib/mesa/meson_options.txt b/lib/mesa/meson_options.txt new file mode 100644 index 000000000..589d10bb3 --- /dev/null +++ b/lib/mesa/meson_options.txt @@ -0,0 +1,326 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +option( + 'platforms', + type : 'array', + value : ['auto'], + choices : [ + '', 'auto', 'x11', 'wayland', 'drm', 'surfaceless', 'haiku', 'android', + ], + description : 'window systems to support. If this is set to `auto`, all platforms applicable will be enabled.' +) +option( + 'dri3', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'enable support for dri3' +) +option( + 'dri-drivers', + type : 'array', + value : ['auto'], + choices : ['', 'auto', 'i915', 'i965', 'r100', 'r200', 'nouveau', 'swrast'], + description : 'List of dri drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built' +) +option( + 'dri-drivers-path', + type : 'string', + value : '', + description : 'Location to install dri drivers. Default: $libdir/dri.' +) +option( + 'dri-search-path', + type : 'string', + value : '', + description : 'Locations to search for dri drivers, passed as colon separated list. Default: dri-drivers-path.' +) +option( + 'gallium-drivers', + type : 'array', + value : ['auto'], + choices : [ + '', 'auto', 'pl111', 'radeonsi', 'r300', 'r600', 'nouveau', 'freedreno', + 'swrast', 'v3d', 'vc4', 'etnaviv', 'imx', 'tegra', 'i915', 'svga', 'virgl', + 'swr', + ], + description : 'List of gallium drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built' +) +option( + 'gallium-extra-hud', + type : 'boolean', + value : false, + description : 'Enable HUD block/NIC I/O HUD status support', +) +option( + 'gallium-vdpau', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'enable gallium vdpau state tracker.', +) +option( + 'vdpau-libs-path', + type : 'string', + value : '', + description : 'path to put vdpau libraries. defaults to $libdir/vdpau.' +) +option( + 'gallium-xvmc', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'enable gallium xvmc state tracker.', +) +option( + 'xvmc-libs-path', + type : 'string', + value : '', + description : 'path to put xvmc libraries. defaults to $libdir.' +) +option( + 'gallium-omx', + type : 'combo', + value : 'auto', + choices : ['auto', 'disabled', 'bellagio', 'tizonia'], + description : 'enable gallium omx state tracker.', +) +option( + 'omx-libs-path', + type : 'string', + value : '', + description : 'path to put omx libraries. defaults to omx-bellagio pkg-config pluginsdir.' +) +option( + 'gallium-va', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'enable gallium va state tracker.', +) +option( + 'va-libs-path', + type : 'string', + value : '', + description : 'path to put va libraries. defaults to $libdir/dri.' +) +option( + 'gallium-xa', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'enable gallium xa state tracker.', +) +option( + 'gallium-nine', + type : 'boolean', + value : false, + description : 'build gallium "nine" Direct3D 9.x state tracker.', +) +option( + 'gallium-opencl', + type : 'combo', + choices : ['icd', 'standalone', 'disabled'], + value : 'disabled', + description : 'build gallium "clover" OpenCL state tracker.', +) +option( + 'd3d-drivers-path', + type : 'string', + value : '', + description : 'Location of D3D drivers. Default: $libdir/d3d', +) +option( + 'vulkan-drivers', + type : 'array', + value : ['auto'], + choices : ['', 'auto', 'amd', 'intel'], + description : 'List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built' +) +option( + 'shader-cache', + type : 'boolean', + value : true, + description : 'Build with on-disk shader cache support' +) +option( + 'vulkan-icd-dir', + type : 'string', + value : '', + description : 'Location relative to prefix to put vulkan icds on install. Default: $datadir/vulkan/icd.d' +) +option( + 'shared-glapi', + type : 'boolean', + value : true, + description : 'Whether to build a shared or static glapi' +) +option( + 'gles1', + type : 'boolean', + value : true, + description : 'Build support for OpenGL ES 1.x' +) +option( + 'gles2', + type : 'boolean', + value : true, + description : 'Build support for OpenGL ES 2.x and 3.x' +) +option( + 'opengl', + type : 'boolean', + value : true, + description : 'Build support for OpenGL (all versions)' +) +option( + 'gbm', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'Build support for gbm platform' +) +option( + 'glx', + type : 'combo', + value : 'auto', + choices : ['auto', 'disabled', 'dri', 'xlib', 'gallium-xlib'], + description : 'Build support for GLX platform' +) +option( + 'egl', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'Build support for EGL platform' +) +option( + 'glvnd', + type : 'boolean', + value : false, + description : 'Enable GLVND support.' +) +option( + 'asm', + type : 'boolean', + value : true, + description : 'Build assembly code if possible' +) +option( + 'glx-read-only-text', + type : 'boolean', + value : false, + description : 'Disable writable .text section on x86 (decreases performance)' +) +option( + 'llvm', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'Build with LLVM support.' +) +option( + 'shared-llvm', + type : 'boolean', + value : true, + description : 'Whether to link llvm shared or statically.' +) +option( + 'valgrind', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'Build with valgrind support' +) +option( + 'libunwind', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'Use libunwind for stack-traces' +) +option( + 'lmsensors', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'Enable HUD lmsensors support.' +) +option( + 'build-tests', + type : 'boolean', + value : false, + description : 'Build unit tests. Currently this will build *all* unit tests, which may build more than expected.' +) +option( + 'selinux', + type : 'boolean', + value : false, + description : 'Build an SELinux-aware Mesa' +) +option( + 'osmesa', + type : 'combo', + value : 'none', + choices : ['none', 'classic', 'gallium'], + description : 'Build OSmesa.' +) +option( + 'osmesa-bits', + type : 'combo', + value : '8', + choices : ['8', '16', '32'], + description : 'Number of channel bits for OSMesa.' +) +option( + 'swr-arches', + type : 'array', + value : ['avx', 'avx2'], + choices : ['avx', 'avx2', 'knl', 'skx'], + description : 'Architectures to build SWR support for.', +) +option( + 'tools', + type : 'array', + value : [], + choices : ['freedreno', 'glsl', 'intel', 'intel-ui', 'nir', 'nouveau', 'xvmc', 'all'], + description : 'List of tools to build. (Note: `intel-ui` selects `intel`)', +) +option( + 'power8', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'Enable power8 optimizations.', +) +option( + 'xlib-lease', + type : 'combo', + value : 'auto', + choices : ['auto', 'true', 'false'], + description : 'Enable VK_EXT_acquire_xlib_display.' +) +option( + 'glx-direct', + type : 'boolean', + value : true, + description : 'Enable direct rendering in GLX and EGL for DRI', +) diff --git a/lib/mesa/src/broadcom/Makefile.v3d.am b/lib/mesa/src/broadcom/Makefile.v3d.am new file mode 100644 index 000000000..97ef2d745 --- /dev/null +++ b/lib/mesa/src/broadcom/Makefile.v3d.am @@ -0,0 +1,32 @@ +noinst_LTLIBRARIES += libbroadcom.la +noinst_LTLIBRARIES += libbroadcom_v33.la +noinst_LTLIBRARIES += libbroadcom_v41.la +noinst_LTLIBRARIES += libbroadcom_v42.la + +if USE_V3D_SIMULATOR +AM_CFLAGS += $(V3D_SIMULATOR_CFLAGS) +libbroadcom_la_LDFLAGS = $(V3D_SIMULATOR_LIBS) +endif + +libbroadcom_v33_la_SOURCES = $(BROADCOM_PER_VERSION_SOURCES) +libbroadcom_v33_la_CFLAGS = -DV3D_VERSION=33 + +libbroadcom_v41_la_SOURCES = $(BROADCOM_PER_VERSION_SOURCES) +libbroadcom_v41_la_CFLAGS = -DV3D_VERSION=41 + +libbroadcom_v42_la_SOURCES = $(BROADCOM_PER_VERSION_SOURCES) +libbroadcom_v42_la_CFLAGS = -DV3D_VERSION=42 + +libbroadcom_la_SOURCES = $(BROADCOM_FILES) + +check_PROGRAMS += \ + qpu/tests/qpu_disasm \ + $(NULL) + +LDADD = \ + libbroadcom.la \ + $(top_builddir)/src/compiler/nir/libnir.la \ + $(top_builddir)/src/util/libmesautil.la \ + $(NULL) + +TESTS += $(check_PROGRAMS) diff --git a/lib/mesa/src/broadcom/cle/meson.build b/lib/mesa/src/broadcom/cle/meson.build new file mode 100644 index 000000000..afaf5a1b4 --- /dev/null +++ b/lib/mesa/src/broadcom/cle/meson.build @@ -0,0 +1,63 @@ +# Copyright © 2017 Broadcom +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# [version, cle XML version] +v3d_versions = [ + [21, 21], + [33, 33], + [41, 33], + [42, 33] +] + +v3d_xml_files = [] +v3d_xml_pack = [] +foreach _v : v3d_versions + v = _v[0] + xmlver = _v[1] + f = 'v3d_packet_v@0@.xml'.format(xmlver) + _name = 'v3d_packet_v@0@_pack.h'.format(v) + if not v3d_xml_files.contains(f) + v3d_xml_files += f + endif + v3d_xml_pack += custom_target( + _name, + input : ['gen_pack_header.py', f], + output : _name, + command : [prog_python, '@INPUT@', '@0@'.format(v)], + capture : true, + ) +endforeach + +v3d_xml_h = custom_target( + 'v3d_xml.h', + input : ['../../intel/genxml/gen_zipped_file.py', v3d_xml_files], + output : 'v3d_xml.h', + command : [prog_python, '@INPUT@'], + capture : true, +) + +libbroadcom_cle = static_library( + ['broadcom_cle', v3d_xml_h], + 'v3d_decoder.c', + include_directories : [inc_common, inc_broadcom], + c_args : [c_vis_args, no_override_init_args], + dependencies : [dep_libdrm, dep_valgrind], + build_by_default : false, +) diff --git a/lib/mesa/src/broadcom/cle/v3d_decoder.c b/lib/mesa/src/broadcom/cle/v3d_decoder.c index 4ac40af05..373a1d996 100644 --- a/lib/mesa/src/broadcom/cle/v3d_decoder.c +++ b/lib/mesa/src/broadcom/cle/v3d_decoder.c @@ -37,6 +37,7 @@ #include "v3d_decoder.h" #include "v3d_packet_helpers.h" #include "v3d_xml.h" +#include "broadcom/clif/clif_private.h" struct v3d_spec { uint32_t ver; @@ -58,6 +59,7 @@ struct location { struct parser_context { XML_Parser parser; + const struct v3d_device_info *devinfo; int foo; struct location loc; @@ -68,6 +70,9 @@ struct parser_context { struct v3d_value *values[256]; struct v3d_spec *spec; + + int parse_depth; + int parse_skip_depth; }; const char * @@ -311,6 +316,8 @@ string_to_type(struct parser_context *ctx, const char *s) return (struct v3d_type) { .kind = V3D_TYPE_BOOL }; else if (strcmp(s, "float") == 0) return (struct v3d_type) { .kind = V3D_TYPE_FLOAT }; + else if (strcmp(s, "f187") == 0) + return (struct v3d_type) { .kind = V3D_TYPE_F187 }; else if (strcmp(s, "address") == 0) return (struct v3d_type) { .kind = V3D_TYPE_ADDRESS }; else if (strcmp(s, "offset") == 0) @@ -359,6 +366,9 @@ create_field(struct parser_context *ctx, const char **atts) else if (strcmp(atts[i], "default") == 0) { field->has_default = true; field->default_value = strtoul(atts[i + 1], &p, 0); + } else if (strcmp(atts[i], "minus_one") == 0) { + assert(strcmp(atts[i + 1], "true") == 0); + field->minus_one = true; } } @@ -411,6 +421,25 @@ set_group_opcode(struct v3d_group *group, const char **atts) return; } +static bool +ver_in_range(int ver, int min_ver, int max_ver) +{ + return ((min_ver == 0 || ver >= min_ver) && + (max_ver == 0 || ver <= max_ver)); +} + +static bool +skip_if_ver_mismatch(struct parser_context *ctx, int min_ver, int max_ver) +{ + if (!ctx->parse_skip_depth && !ver_in_range(ctx->devinfo->ver, + min_ver, max_ver)) { + assert(ctx->parse_depth != 0); + ctx->parse_skip_depth = ctx->parse_depth; + } + + return ctx->parse_skip_depth; +} + static void start_element(void *data, const char *element_name, const char **atts) { @@ -418,20 +447,35 @@ start_element(void *data, const char *element_name, const char **atts) int i; const char *name = NULL; const char *ver = NULL; + int min_ver = 0; + int max_ver = 0; ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser); for (i = 0; atts[i]; i += 2) { - if (strcmp(atts[i], "name") == 0) + if (strcmp(atts[i], "shortname") == 0) + name = atts[i + 1]; + else if (strcmp(atts[i], "name") == 0 && !name) name = atts[i + 1]; else if (strcmp(atts[i], "gen") == 0) ver = atts[i + 1]; + else if (strcmp(atts[i], "min_ver") == 0) + min_ver = strtoul(atts[i + 1], NULL, 0); + else if (strcmp(atts[i], "max_ver") == 0) + max_ver = strtoul(atts[i + 1], NULL, 0); } + if (skip_if_ver_mismatch(ctx, min_ver, max_ver)) + goto skip; + if (strcmp(element_name, "vcxml") == 0) { if (ver == NULL) fail(&ctx->loc, "no ver given"); + /* Make sure that we picked an XML that matched our version. + */ + assert(ver_in_range(ctx->devinfo->ver, min_ver, max_ver)); + int major, minor; int n = sscanf(ver, "%d.%d", &major, &minor); if (n == 0) @@ -467,6 +511,15 @@ start_element(void *data, const char *element_name, const char **atts) assert(ctx->nvalues < ARRAY_SIZE(ctx->values)); } +skip: + ctx->parse_depth++; +} + +static int +field_offset_compare(const void *a, const void *b) +{ + return ((*(const struct v3d_field **)a)->start - + (*(const struct v3d_field **)b)->start); } static void @@ -475,6 +528,14 @@ end_element(void *data, const char *name) struct parser_context *ctx = data; struct v3d_spec *spec = ctx->spec; + ctx->parse_depth--; + + if (ctx->parse_skip_depth) { + if (ctx->parse_skip_depth == ctx->parse_depth) + ctx->parse_skip_depth = 0; + return; + } + if (strcmp(name, "packet") == 0 || strcmp(name, "struct") == 0 || strcmp(name, "register") == 0) { @@ -499,6 +560,13 @@ end_element(void *data, const char *name) else if (strcmp(name, "register") == 0) spec->registers[spec->nregisters++] = group; + /* Sort the fields in increasing offset order. The XML might + * be specified in any order, but we'll want to iterate from + * the bottom. + */ + qsort(group->fields, group->nfields, sizeof(*group->fields), + field_offset_compare); + assert(spec->ncommands < ARRAY_SIZE(spec->commands)); assert(spec->nstructs < ARRAY_SIZE(spec->structs)); assert(spec->nregisters < ARRAY_SIZE(spec->registers)); @@ -586,10 +654,14 @@ v3d_spec_load(const struct v3d_device_info *devinfo) uint32_t text_offset = 0, text_length = 0, total_length; for (int i = 0; i < ARRAY_SIZE(genxml_files_table); i++) { - if (genxml_files_table[i].gen_10 == devinfo->ver) { + if (i != 0) { + assert(genxml_files_table[i - 1].gen_10 < + genxml_files_table[i].gen_10); + } + + if (genxml_files_table[i].gen_10 <= devinfo->ver) { text_offset = genxml_files_table[i].offset; text_length = genxml_files_table[i].length; - break; } } @@ -600,6 +672,7 @@ v3d_spec_load(const struct v3d_device_info *devinfo) memset(&ctx, 0, sizeof ctx); ctx.parser = XML_ParserCreate(NULL); + ctx.devinfo = devinfo; XML_SetUserData(ctx.parser, &ctx); if (ctx.parser == NULL) { fprintf(stderr, "failed to create parser\n"); @@ -687,14 +760,12 @@ v3d_group_get_length(struct v3d_group *group) void v3d_field_iterator_init(struct v3d_field_iterator *iter, struct v3d_group *group, - const uint8_t *p, - bool print_colors) + const uint8_t *p) { memset(iter, 0, sizeof(*iter)); iter->group = group; iter->p = p; - iter->print_colors = print_colors; } static const char * @@ -763,7 +834,7 @@ iter_advance_field(struct v3d_field_iterator *iter) iter->field = iter->group->fields[iter->field_iter++]; if (iter->field->name) - strncpy(iter->name, iter->field->name, sizeof(iter->name)); + snprintf(iter->name, sizeof(iter->name), "%s", iter->field->name); else memset(iter->name, 0, sizeof(iter->name)); iter->offset = iter_group_offset_bits(iter, iter->group_iter) / 8 + @@ -774,43 +845,76 @@ iter_advance_field(struct v3d_field_iterator *iter) } bool -v3d_field_iterator_next(struct v3d_field_iterator *iter) +v3d_field_iterator_next(struct clif_dump *clif, struct v3d_field_iterator *iter) { if (!iter_advance_field(iter)) return false; const char *enum_name = NULL; - int s = iter->field->start; - int e = iter->field->end; + int group_member_offset = + iter_group_offset_bits(iter, iter->group_iter); + int s = group_member_offset + iter->field->start; + int e = group_member_offset + iter->field->end; + + assert(!iter->field->minus_one || + iter->field->type.kind == V3D_TYPE_INT || + iter->field->type.kind == V3D_TYPE_UINT); switch (iter->field->type.kind) { case V3D_TYPE_UNKNOWN: case V3D_TYPE_INT: { uint32_t value = __gen_unpack_sint(iter->p, s, e); + if (iter->field->minus_one) + value++; snprintf(iter->value, sizeof(iter->value), "%d", value); enum_name = v3d_get_enum_name(&iter->field->inline_enum, value); break; } case V3D_TYPE_UINT: { uint32_t value = __gen_unpack_uint(iter->p, s, e); + if (iter->field->minus_one) + value++; + if (strcmp(iter->field->name, "Vec size") == 0 && value == 0) + value = 1 << (e - s); snprintf(iter->value, sizeof(iter->value), "%u", value); enum_name = v3d_get_enum_name(&iter->field->inline_enum, value); break; } - case V3D_TYPE_BOOL: { - const char *true_string = - iter->print_colors ? "\e[0;35mtrue\e[0m" : "true"; + case V3D_TYPE_BOOL: snprintf(iter->value, sizeof(iter->value), "%s", __gen_unpack_uint(iter->p, s, e) ? - true_string : "false"); + "1 /* true */" : "0 /* false */"); break; - } case V3D_TYPE_FLOAT: snprintf(iter->value, sizeof(iter->value), "%f", __gen_unpack_float(iter->p, s, e)); break; - case V3D_TYPE_ADDRESS: + + case V3D_TYPE_F187: + snprintf(iter->value, sizeof(iter->value), "%f", + __gen_unpack_f187(iter->p, s, e)); + break; + + case V3D_TYPE_ADDRESS: { + uint32_t addr = + __gen_unpack_uint(iter->p, s, e) << (31 - (e - s)); + struct clif_bo *bo = clif_lookup_bo(clif, addr); + if (bo) { + snprintf(iter->value, sizeof(iter->value), + "[%s+0x%08x] /* 0x%08x */", + bo->name, addr - bo->offset, addr); + } else if (addr) { + snprintf(iter->value, sizeof(iter->value), + "/* XXX: BO unknown */ 0x%08x", addr); + } else { + snprintf(iter->value, sizeof(iter->value), + "[null]"); + } + + break; + } + case V3D_TYPE_OFFSET: snprintf(iter->value, sizeof(iter->value), "0x%08"PRIx64, __gen_unpack_uint(iter->p, s, e) << (31 - (e - s))); @@ -823,14 +927,24 @@ v3d_field_iterator_next(struct v3d_field_iterator *iter) iter->field->type.v3d_struct->name); break; case V3D_TYPE_SFIXED: - snprintf(iter->value, sizeof(iter->value), "%f", - __gen_unpack_sfixed(iter->p, s, e, - iter->field->type.f)); + if (clif->pretty) { + snprintf(iter->value, sizeof(iter->value), "%f", + __gen_unpack_sfixed(iter->p, s, e, + iter->field->type.f)); + } else { + snprintf(iter->value, sizeof(iter->value), "%u", + (unsigned)__gen_unpack_uint(iter->p, s, e)); + } break; case V3D_TYPE_UFIXED: - snprintf(iter->value, sizeof(iter->value), "%f", - __gen_unpack_ufixed(iter->p, s, e, - iter->field->type.f)); + if (clif->pretty) { + snprintf(iter->value, sizeof(iter->value), "%f", + __gen_unpack_ufixed(iter->p, s, e, + iter->field->type.f)); + } else { + snprintf(iter->value, sizeof(iter->value), "%u", + (unsigned)__gen_unpack_uint(iter->p, s, e)); + } break; case V3D_TYPE_MBO: break; @@ -851,26 +965,40 @@ v3d_field_iterator_next(struct v3d_field_iterator *iter) if (enum_name) { int length = strlen(iter->value); snprintf(iter->value + length, sizeof(iter->value) - length, - " (%s)", enum_name); + " /* %s */", enum_name); } return true; } void -v3d_print_group(FILE *outfile, struct v3d_group *group, - uint64_t offset, const uint8_t *p, bool color) +v3d_print_group(struct clif_dump *clif, struct v3d_group *group, + uint64_t offset, const uint8_t *p) { struct v3d_field_iterator iter; - v3d_field_iterator_init(&iter, group, p, color); - while (v3d_field_iterator_next(&iter)) { - fprintf(outfile, " %s: %s\n", iter.name, iter.value); + v3d_field_iterator_init(&iter, group, p); + while (v3d_field_iterator_next(clif, &iter)) { + /* Clif parsing uses the packet name, and expects no + * sub-id. + */ + if (strcmp(iter.field->name, "sub-id") == 0 || + strcmp(iter.field->name, "unused") == 0 || + strcmp(iter.field->name, "Pad") == 0) + continue; + + if (clif->pretty) { + fprintf(clif->out, " %s: %s\n", + iter.name, iter.value); + } else { + fprintf(clif->out, " /* %30s: */ %s\n", + iter.name, iter.value); + } if (iter.struct_desc) { uint64_t struct_offset = offset + iter.offset; - v3d_print_group(outfile, iter.struct_desc, + v3d_print_group(clif, iter.struct_desc, struct_offset, - &p[iter.offset], color); + &p[iter.offset]); } } } diff --git a/lib/mesa/src/broadcom/cle/v3d_decoder.h b/lib/mesa/src/broadcom/cle/v3d_decoder.h index 541d877a9..b5ead383b 100644 --- a/lib/mesa/src/broadcom/cle/v3d_decoder.h +++ b/lib/mesa/src/broadcom/cle/v3d_decoder.h @@ -34,6 +34,7 @@ struct v3d_spec; struct v3d_group; struct v3d_field; +struct clif_dump; struct v3d_group *v3d_spec_find_struct(struct v3d_spec *spec, const char *name); struct v3d_spec *v3d_spec_load(const struct v3d_device_info *devinfo); @@ -57,7 +58,6 @@ struct v3d_field_iterator { int group_iter; struct v3d_field *field; - bool print_colors; }; struct v3d_group { @@ -99,6 +99,7 @@ struct v3d_type { V3D_TYPE_UINT, V3D_TYPE_BOOL, V3D_TYPE_FLOAT, + V3D_TYPE_F187, V3D_TYPE_ADDRESS, V3D_TYPE_OFFSET, V3D_TYPE_STRUCT, @@ -125,6 +126,7 @@ struct v3d_field { char *name; int start, end; struct v3d_type type; + bool minus_one; bool has_default; uint32_t default_value; @@ -133,14 +135,13 @@ struct v3d_field { void v3d_field_iterator_init(struct v3d_field_iterator *iter, struct v3d_group *group, - const uint8_t *p, - bool print_colors); + const uint8_t *p); -bool v3d_field_iterator_next(struct v3d_field_iterator *iter); +bool v3d_field_iterator_next(struct clif_dump *clif, + struct v3d_field_iterator *iter); -void v3d_print_group(FILE *out, +void v3d_print_group(struct clif_dump *clif, struct v3d_group *group, - uint64_t offset, const uint8_t *p, - bool color); + uint64_t offset, const uint8_t *p); #endif /* V3D_DECODER_H */ diff --git a/lib/mesa/src/broadcom/cle/v3d_packet_v33.xml b/lib/mesa/src/broadcom/cle/v3d_packet_v33.xml index e6562a262..f471d542c 100644 --- a/lib/mesa/src/broadcom/cle/v3d_packet_v33.xml +++ b/lib/mesa/src/broadcom/cle/v3d_packet_v33.xml @@ -1,4 +1,4 @@ -<vcxml gen="3.3"> +<vcxml gen="3.3" min_ver="33" max_ver="42"> <enum name="Compare Function" prefix="V3D_COMPARE_FUNC"> <value name="NEVER" value="0"/> @@ -69,24 +69,195 @@ <value name="TRIANGLE_FAN_TF" value="22"/> </enum> + <enum name="TMU Filter" prefix="V3D_TMU_FILTER" max_ver="33"> + <!-- Names are mip filter, min filter, mag filter --> + <value name="MIN_LIN_MIP_NONE_MAG_LIN" value="0"/> + <value name="MIN_LIN_MIP_NONE_MAG_NEAR" value="1"/> + <value name="MIN_NEAR_MIP_NONE_MAG_LIN" value="2"/> + <value name="MIN_NEAR_MIP_NONE_MAG_NEAR" value="3"/> + + <value name="MIN_NEAR_MIP_NEAR_MAG_LIN" value="4"/> + <value name="MIN_NEAR_MIP_NEAR_MAG_NEAR" value="5"/> + <value name="MIN_NEAR_MIP_LIN_MAG_LIN" value="6"/> + <value name="MIN_NEAR_MIP_LIN_MAG_NEAR" value="7"/> + + <value name="MIN_LIN_MIP_NEAR_MAG_LIN" value="8"/> + <value name="MIN_LIN_MIP_NEAR_MAG_NEAR" value="9"/> + <value name="MIN_LIN_MIP_LIN_MAG_LIN" value="10"/> + <value name="MIN_LIN_MIP_LIN_MAG_NEAR" value="11"/> + + <value name="ANISOTROPIC_2_1" value="12"/> + <value name="ANISOTROPIC_4_1" value="13"/> + <value name="ANISOTROPIC_8_1" value="14"/> + <value name="ANISOTROPIC_16_1" value="15"/> + </enum> + + <enum name="Border Color Mode" prefix="V3D_BORDER_COLOR" min_ver="41"> + <value name="0000" value="0"/> + <value name="0001" value="1"/> + <value name="1111" value="2"/> + <value name="Follows" value="7"/> + </enum> + + <enum name="Wrap Mode" prefix="V3D_WRAP_MODE" min_ver="41"> + <value name="Wrap mode REPEAT" value="0"/> + <value name="Wrap mode CLAMP" value="1"/> + <value name="Wrap mode MIRROR" value="2"/> + <value name="Wrap mode BORDER" value="3"/> + <value name="Wrap mode MIRROR_ONCE" value="4"/> + </enum> + + <enum name="TMU Op" prefix="V3D_TMU_OP" min_ver="41"> + <value name="Write ADD, Read Prefetch" value="0"/> + <value name="Write SUB, Read Clear" value="1"/> + <value name="Write XCHG, Read Flush" value="2"/> + <value name="Write CMPXCHG, Read Flush" value="3"/> + <value name="Write UMIN, Full L1 Clear" value="4"/> + <value name="Write UMAX" value="5"/> + <value name="Write SMIN" value="6"/> + <value name="Write SMAX" value="7"/> + <value name="Write AND, Read INC" value="8"/> + <value name="Write OR, Read DEC" value="9"/> + <value name="Write XOR, Read NOT" value="10"/> + <value name="Regular" value="15"/> + </enum> + + <enum name="Varying Flags Action" prefix="V3D_VARYING_FLAGS_ACTION"> + <value name="unchanged" value="0"/> + <value name="zeroed" value="1"/> + <value name="set" value="2"/> + </enum> + + <enum name="Memory Format" prefix="V3D_MEMORY_FORMAT"> + <value name="Raster" value="0"/> + <value name="Lineartile" value="1"/> + <value name="UB-linear (1 UIF block wide)" value="2"/> + <value name="UB-linear (2 UIF blocks wide)" value="3"/> + <value name="UIF (No XOR)" value="4"/> + <value name="UIF (XOR)" value="5"/> + </enum> + + <enum name="Decimate Mode" prefix="V3D_DECIMATE_MODE"> + <value name="sample 0" value="0"/> + <value name="4x" value="1"/> + <value name="all samples" value="3"/> + </enum> + + <enum name="Internal Type" prefix="V3D_INTERNAL_TYPE"> + <value name="8i" value="0"/> + <value name="8ui" value="1"/> + <value name="8" value="2"/> + <value name="16i" value="4"/> + <value name="16ui" value="5"/> + <value name="16f" value="6"/> + <value name="32i" value="8"/> + <value name="32ui" value="9"/> + <value name="32f" value="10"/> + </enum> + + <enum name="Internal BPP" prefix="V3D_INTERNAL_BPP"> + <value name="32" value="0"/> + <value name="64" value="1"/> + <value name="128" value="2"/> + </enum> + + <enum name="Internal Depth Type" prefix="V3D_INTERNAL_TYPE"> + <value name="depth_32f" value="0"/> + <value name="depth_24" value="1"/> + <value name="depth_16" value="2"/> + </enum> + + <enum name="Render Target Clamp" prefix="V3D_RENDER_TARGET_CLAMP" min_ver="41"> + <value name="none" value="0"/> <!-- no clamping --> + <value name="norm" value="1"/> <!-- [0,1] for f16 --> + <value name="pos" value="2"/> <!-- [0, for f16 --> + <value name="int" value="3" min_ver="42"/> <!-- clamp to integer RT's range --> + </enum> + + <enum name="Output Image Format" prefix="V3D_OUTPUT_IMAGE_FORMAT"> + <!-- + Formats appear with their channels named from the low bits to + the high bits. + --> + <value name="srgb8_alpha8" value="0"/> + <value name="srgb" value="1"/> + <value name="rgb10_a2ui" value="2"/> + <value name="rgb10_a2" value="3"/> + <value name="abgr1555" value="4"/> + <value name="alpha-masked abgr1555" value="5"/> + <value name="abgr4444" value="6"/> + <value name="bgr565" value="7"/> + <value name="r11f_g11f_b10f" value="8"/> + <value name="rgba32f" value="9"/> + <value name="rg32f" value="10"/> + <value name="r32f" value="11"/> + <value name="rgba32i" value="12"/> + <value name="rg32i" value="13"/> + <value name="r32i" value="14"/> + <value name="rgba32ui" value="15"/> + <value name="rg32ui" value="16"/> + <value name="r32ui" value="17"/> + <value name="rgba16f" value="18"/> + <value name="rg16f" value="19"/> + <value name="r16f" value="20"/> + <value name="rgba16i" value="21"/> + <value name="rg16i" value="22"/> + <value name="r16i" value="23"/> + <value name="rgba16ui" value="24"/> + <value name="rg16ui" value="25"/> + <value name="r16ui" value="26"/> + <value name="rgba8" value="27"/> + <value name="rgb8" value="28"/> + <value name="rg8" value="29"/> + <value name="r8" value="30"/> + <value name="rgba8i" value="31"/> + <value name="rg8i" value="32"/> + <value name="r8i" value="33"/> + <value name="rgba8ui" value="34"/> + <value name="rg8ui" value="35"/> + <value name="r8ui" value="36"/> + <value name="srgbx8" value="37" max_ver="33"/> + <value name="rgbx8" value="38" max_ver="33"/> + <value name="bstc" value="39" min_ver="41"/> + <value name="d32f" value="40" min_ver="41"/> + <value name="d24" value="41" min_ver="41"/> + <value name="d16" value="42" min_ver="41"/> + <value name="d24s8" value="43" min_ver="41"/> + <value name="s8" value="44" min_ver="41"/> + </enum> + + <enum name="Z/S Output Image Format" prefix="V3D_OUTPUT_IMAGE_FORMAT_ZS" max_ver="33"> + <value name="depth_component32f" value="0"/> + <value name="depth_component24" value="1"/> <!-- depth low, pad high --> + <value name="depth_component16" value="2"/> + <value name="depth24_stencil8" value="3"/> <!-- stencil low, depth high --> + </enum> + + <enum name="Dither Mode" prefix="V3D_DITHER_MODE"> + <value name="None" value="0"/> + <value name="RGB" value="1"/> + <value name="A" value="2"/> + <value name="RGBA" value="3"/> + </enum> + <packet code="0" name="Halt"/> <packet code="1" name="NOP"/> <packet code="4" name="Flush"/> <packet code="5" name="Flush All State"/> <packet code="6" name="Start Tile Binning"/> - <packet code="7" name="Increment Semaphore"/> - <packet code="8" name="Wait on Semaphore"/> - <packet code="9" name="Wait for previous frame"/> - <packet code="10" name="Enable Z-only rendering" cl="R"/> - <packet code="11" name="Disable Z-only rendering" cl="R"/> - <packet code="12" name="End of Z-only rendering in frame"/> - <packet code="13" name="End of rendering"/> - - <packet code="14" name="Wait for transform feedback" cl="B"> + <packet code="7" shortname="incr_semaphore" name="Increment Semaphore"/> + <packet code="8" shortname="wait_semaphore" name="Wait on Semaphore"/> + <packet code="9" shortname="wait_prev_frame" name="Wait for previous frame"/> + <packet code="10" shortname="enable_z_only" name="Enable Z-only rendering" cl="R"/> + <packet code="11" shortname="disable_z_only" name="Disable Z-only rendering" cl="R"/> + <packet code="12" shortname="end_z_only" name="End of Z-only rendering in frame"/> + <packet code="13" shortname="end_render" name="End of rendering"/> + + <packet code="14" shortname="wait_transform_feedback" name="Wait for transform feedback" cl="B"> <field name="Block count" size="8" start="0" type="uint"/> </packet> - <packet code="15" name="Branch to auto-chained sub-list"> + <packet code="15" shortname="branch_sub_autochain" name="Branch to auto-chained sub-list"> <field name="address" size="32" start="0" type="address"/> </packet> @@ -94,62 +265,69 @@ <field name="address" size="32" start="0" type="address"/> </packet> - <packet code="17" name="Branch to Sub-list"> + <packet code="17" shortname="branch_sub" name="Branch to Sub-list"> <field name="address" size="32" start="0" type="address"/> </packet> - <packet code="18" name="Return from sub-list"/> - <packet code="19" name="Flush VCD cache"/> + <packet code="18" shortname="return" name="Return from sub-list"/> + <packet code="19" shortname="clear_vcd_cache" name="Flush VCD cache"/> - <packet code="20" name="Start Address of Generic Tile List"> + <packet code="20" shortname="generic_tile_list" name="Start Address of Generic Tile List"> <field name="start" size="32" start="0" type="address"/> <field name="end" size="32" start="32" type="address"/> </packet> - <packet code="21" name="Branch to Implicit Tile List"> + <packet code="21" shortname="branch_implicit_tile" name="Branch to Implicit Tile List"> <field name="tile list set number" size="8" start="0" type="uint"/> </packet> - <packet code="22" name="Branch to Explicit Supertile"> + <packet code="22" shortname="branch_explicit_supertile" name="Branch to Explicit Supertile"> <field name="Absolute address of explicit supertile render list" size="32" start="24" type="address"/> <field name="explicit supertile number" size="8" start="16" type="uint"/> <field name="row number" size="8" start="8" type="uint"/> <field name="column number" size="8" start="0" type="uint"/> </packet> - <packet code="23" name="Supertile Coordinates"> + <packet code="23" shortname="supertile_coords" name="Supertile Coordinates"> <field name="row number in supertiles" size="8" start="8" type="uint"/> <field name="column number in supertiles" size="8" start="0" type="uint"/> </packet> - <packet code="24" name="Store Multi-Sample Resolved Tile Color Buffer" cl="R"/> + <packet code="24" shortname="store_subsample" name="Store Multi-Sample Resolved Tile Color Buffer" cl="R" max_ver="33"/> - <packet code="25" name="Store Multi-Sample Resolved Tile Color Buffer (extended)" cl="R"> + <packet code="25" shortname="store_subsample_ex" name="Store Multi-Sample Resolved Tile Color Buffer (extended)" cl="R" max_ver="33"> <field name="Disable Color Buffer write" size="8" start="8" type="uint"/> <field name="Enable Z write" size="1" start="7" type="bool"/> <field name="Enable Stencil write" size="1" start="6" type="bool"/> <!-- bit 5 unused --> - <field name="Disable Colour buffer(s) clear on write" size="1" start="4" type="bool"/> + <field name="Disable Color buffer(s) clear on write" size="1" start="4" type="bool"/> <field name="Disable Stencil buffer clear on write" size="1" start="3" type="bool"/> <field name="Disable Z buffer clear on write" size="1" start="2" type="bool"/> <field name="Disable fast opportunistic write out in multisample mode" size="1" start="1" type="bool"/> <field name="Last Tile of Frame" size="1" start="0" type="bool"/> </packet> - <packet code="26" name="Reload Tile Colour Buffer" cl="R"> - <field name="Disable Colour Buffer load" size="8" start="8" type="uint"/> + <packet code="25" shortname="clear" name="Clear Tile Buffers" cl="R" min_ver="41"> + <field name="Clear Z/Stencil Buffer" size="1" start="1" type="bool"/> + <field name="Clear all Render Targets" size="1" start="0" type="bool"/> + </packet> + + <packet code="26" shortname="load" name="Reload Tile Color Buffer" cl="R" max_ver="33"> + <field name="Disable Color Buffer load" size="8" start="8" type="uint"/> <field name="Enable Z load" size="1" start="7" type="bool"/> <field name="Enable Stencil load" size="1" start="6" type="bool"/> </packet> - <packet code="27" name="End of Tile Marker" cl="R"/> + <packet code="26" shortname="end_loads" name="End of Loads" cl="R" min_ver="41"/> - <packet code="29" name="Store Tile Buffer General" cl="R"> - <field name="Address" size="32" start="16" type="address"/> + <packet code="27" shortname="end_tile" name="End of Tile Marker" cl="R"/> + + <packet code="29" shortname="store_general" name="Store Tile Buffer General" cl="R" max_ver="33"> + <field name="Address" size="24" start="24" type="address"/> <field name="Padded height of output image in UIF blocks" size="13" start="11" type="uint"/> <field name="XOR UIF" size="1" start="10" type="bool"/> <field name="Last Tile of Frame" size="1" start="8" type="bool"/> - <field name="Disable Colour buffer(s) clear on write" size="1" start="7" type="bool"/> + <field name="Disable Color buffer(s) clear on write" size="1" start="7" type="bool"/> <field name="Disable Stencil buffer clear on write" size="1" start="6" type="bool"/> <field name="Disable Z buffer clear on write" size="1" start="5" type="bool"/> <field name="Raw Mode" size="1" start="4" type="bool"/> @@ -165,7 +343,40 @@ </field> </packet> - <packet code="30" name="Load Tile Buffer General" cl="R"> + <packet code="29" shortname="store" name="Store Tile Buffer General" cl="R" min_ver="41"> + <field name="Address" size="32" start="64" type="address"/> + + <!-- used for y flip --> + <field name="Height" size="16" start="48" type="uint"/> + + <!-- height in ub for UIF, byte stride for raster --> + <field name="Height in UB or Stride" size="20" start="28" type="uint"/> + + <field name="R/B swap" size="1" start="20" type="bool"/> + <field name="Channel Reverse" size="1" start="19" type="bool"/> + <field name="Clear buffer being stored" size="1" start="18" type="bool"/> + <field name="Output Image Format" size="6" start="12" type="Output Image Format"/> + + <field name="Decimate mode" size="2" start="10" type="Decimate Mode"/> + + <field name="Dither Mode" size="2" start="8" type="Dither Mode"/> + + <field name="Flip Y" size="1" start="7" type="bool"/> + + <field name="Memory Format" size="3" start="4" type="Memory Format"/> + <field name="Buffer to Store" size="4" start="0" type="uint"> + <value name="Render target 0" value="0"/> + <value name="Render target 1" value="1"/> + <value name="Render target 2" value="2"/> + <value name="Render target 3" value="3"/> + <value name="None" value="8"/> + <value name="Z" value="9"/> + <value name="Stencil" value="10"/> + <value name="Z+Stencil" value="11"/> + </field> + </packet> + + <packet code="30" shortname="load_general" name="Load Tile Buffer General" cl="R" max_ver="33"> <field name="Address" size="24" start="24" type="address"/> <field name="Padded height of output image in UIF blocks" size="13" start="11" type="uint"/> <field name="XOR UIF" size="1" start="10" type="bool"/> @@ -182,7 +393,40 @@ </field> </packet> - <packet code="32" name="Indexed Primitive List" cl="B"> + <packet code="30" shortname="load" name="Load Tile Buffer General" cl="R" min_ver="41"> + <field name="Address" size="32" start="64" type="address"/> + + <!-- used for y flip --> + <field name="Height" size="16" start="48" type="uint"/> + + <!-- height in ub for UIF, byte stride for raster --> + <field name="Height in UB or Stride" size="20" start="28" type="uint"/> + + <field name="R/B swap" size="1" start="20" type="bool"/> + <field name="Channel Reverse" size="1" start="19" type="bool"/> + + <field name="Input Image Format" size="6" start="12" type="Output Image Format"/> + + <field name="Decimate mode" size="2" start="10" type="Decimate Mode"/> + + <field name="Flip Y" size="1" start="7" type="bool"/> + + <field name="Memory Format" size="3" start="4" type="Memory Format"/> + <field name="Buffer to Load" size="4" start="0" type="uint"> + <value name="Render target 0" value="0"/> + <value name="Render target 1" value="1"/> + <value name="Render target 2" value="2"/> + <value name="Render target 3" value="3"/> + <value name="None" value="8"/> + <value name="Z" value="9"/> + <value name="Stencil" value="10"/> + <value name="Z+Stencil" value="11"/> + </field> + </packet> + + <packet code="31" shortname="tf_draw_flush_and_count" name="Transform Feedback Flush and Count"/> + + <packet code="32" name="Indexed Prim List" cl="B" max_ver="33"> <field name="Minimum index" size="32" start="104" type="uint"/> <field name="Enable Primitive Restarts" size="1" start="103" type="bool"/> <field name="Maximum index" size="31" start="72" type="uint"/> @@ -195,11 +439,25 @@ <value name="Index type 32-bit" value="2"/> </field> - <field name="mode" size="5" start="0" type="uint"> + <field name="mode" size="5" start="0" type="Primitive"/> + </packet> + + <packet code="32" name="Indexed Prim List" cl="B" min_ver="41"> + <field name="Index Offset" size="32" start="40" type="uint"/> + + <field name="Enable Primitive Restarts" size="1" start="39" type="bool"/> + <field name="Length" size="31" start="8" type="uint"/> + + <field name="Index type" size="2" start="6" type="uint"> + <value name="Index type 8-bit" value="0"/> + <value name="Index type 16-bit" value="1"/> + <value name="Index type 32-bit" value="2"/> </field> + + <field name="mode" size="6" start="0" type="Primitive"/> </packet> - <packet code="34" name="Indexed Instanced Primitive List" cl="B"> + <packet code="34" name="Indexed Instanced Prim List" cl="B" max_ver="33"> <field name="Enable Primitive Restarts" size="1" start="135" type="bool"/> <field name="Maximum index" size="31" start="104" type="uint"/> <field name="Address of Indices List" size="32" start="72" type="address"/> @@ -215,14 +473,29 @@ <field name="mode" size="5" start="0" type="Primitive"/> </packet> - <packet code="36" name="Vertex Array Primitives" cl="B"> + <packet code="34" name="Indexed Instanced Prim List" cl="B" min_ver="41"> + <field name="Index Offset" size="32" start="72" type="uint"/> + <field name="Number of Instances" size="32" start="40" type="uint"/> + <field name="Enable Primitive Restarts" size="1" start="39" type="bool"/> + <field name="Instance Length" size="31" start="8" type="uint"/> + + <field name="Index type" size="2" start="6" type="uint"> + <value name="Index type 8-bit" value="0"/> + <value name="Index type 16-bit" value="1"/> + <value name="Index type 32-bit" value="2"/> + </field> + + <field name="mode" size="6" start="0" type="Primitive"/> + </packet> + + <packet code="36" name="Vertex Array Prims" cl="B"> <field name="Index of First Vertex" size="32" start="40" type="uint"/> <field name="Length" size="32" start="8" type="uint"/> <field name="mode" size="8" start="0" type="Primitive"/> </packet> - <packet code="38" name="Vertex Array Instanced Primitives" cl="B"> + <packet code="38" name="Vertex Array Instanced Prims" cl="B"> <field name="Index of First Vertex" size="32" start="72" type="uint"/> <field name="Number of Instances" size="32" start="40" type="uint"/> <field name="Instance Length" size="32" start="8" type="uint"/> @@ -236,11 +509,13 @@ <field name="Base Vertex" size="32" start="0" type="uint"/> </packet> - <packet code="56" name="Primitive List Format"> - <field name="data type" size="1" start="6" type="uint"> - <value name="List Indexed" value="0"/> - <value name="List 32-bit X/Y" value="1"/> - </field> + <packet code="44" name="Index Buffer Setup" cl="B" min_ver="41"> + <field name="Address" size="32" start="0" type="address"/> + <field name="Size" size="32" start="32" type="uint"/> + </packet> + + <packet code="56" name="Prim List Format"> + <field name="tri strip or fan" size="1" start="7" type="bool"/> <field name="primitive type" size="6" start="0" type="uint"> <value name="List Points" value="0"/> <value name="List Lines" value="1"/> @@ -248,29 +523,57 @@ </field> </packet> - <packet code="64" name="GL Shader State"> + <packet code="64" shortname="gl_shader" name="GL Shader State"> <field name="address" size="27" start="5" type="address"/> <field name="number of attribute arrays" size="5" start="0" type="uint"/> </packet> - <packet code="74" name="Transform Feedback Enable"> + <packet code="71" name="VCM Cache Size" min_ver="41"> + <field name="Number of 16-vertex batches for rendering" size="4" start="4" type="uint"/> + <field name="Number of 16-vertex batches for binning" size="4" start="0" type="uint"/> + </packet> + + <packet code="73" name="VCM Cache Size" max_ver="33"> + <field name="Number of 16-vertex batches for rendering" size="4" start="4" type="uint"/> + <field name="Number of 16-vertex batches for binning" size="4" start="0" type="uint"/> + </packet> + + <packet code="73" name="Transform Feedback Buffer" min_ver="41"> + <field name="Buffer Address" size="32" start="32" type="address"/> + <field name="Buffer Size in 32-bit words" size="30" start="2" type="uint"/> + <field name="Buffer Number" size="2" start="0" type="uint"/> + </packet> + + <packet code="74" name="Transform Feedback Enable" max_ver="33"> <field name="number of 32-bit Output Buffer Address following" size="3" start="8" type="uint"/> <field name="number of 16-bit Output Data Specs following" size="5" start="11" type="uint"/> </packet> + <packet code="74" name="Transform Feedback Specs" min_ver="41"> + <field name="Enable" size="1" start="7" type="bool"/> + <field name="Number of 16-bit Output Data Specs following" size="5" start="0" type="uint"/> + </packet> + <packet code="75" name="Flush Transform Feedback Data"/> - <struct name="Transform Feedback Output Data Spec"> + <struct name="Transform Feedback Output Data Spec" max_ver="33"> + <field name="First Shaded Vertex Value to output" size="8" start="0" type="uint"/> + <field name="Number of consecutive Vertex Values to output as 32-bit values" size="4" start="8" type="uint" minus_one="true"/> + <field name="Output Buffer to write to" size="2" start="12" type="uint"/> + </struct> + + <struct name="Transform Feedback Output Data Spec" min_ver="41"> <field name="First Shaded Vertex Value to output" size="8" start="0" type="uint"/> - <field name="Number of consecutive Vertex Values to output as 32-bit values minus 1" size="4" start="8" type="uint"/> + <field name="Number of consecutive Vertex Values to output as 32-bit values" size="4" start="8" type="uint" minus_one="true"/> <field name="Output Buffer to write to" size="2" start="12" type="uint"/> + <field name="Stream number" size="2" start="14" type="uint"/> </struct> <struct name="Transform Feedback Output Address"> <field name="address" size="32" start="0" type="address"/> </struct> - <packet code="80" name="Stencil Config"> + <packet code="80" name="Stencil Cfg"> <field name="Stencil Write Mask" size="8" start="32" type="uint"/> <field name="Back Config" size="1" start="29" type="bool"/> <field name="Front Config" size="1" start="28" type="bool"/> @@ -282,32 +585,59 @@ <field name="Stencil Ref Value" size="8" start="0" type="uint"/> </packet> - <packet code="84" name="Blend Config"> - <field name="VG Coverage Modes" size="2" start="28" type="uint"/> - <field name="Colour blend dst factor" size="4" start="20" type="Blend Factor"/> - <field name="Colour blend src factor" size="4" start="16" type="Blend Factor"/> - <field name="Colour blend mode" size="4" start="12" type="Blend Mode"/> + <packet code="83" name="Blend Enables" min_ver="41"> + <field name="Mask" size="8" start="0" type="uint"/> + </packet> + + <packet code="84" name="Blend Cfg" max_ver="33"> + <field name="Color blend dst factor" size="4" start="20" type="Blend Factor"/> + <field name="Color blend src factor" size="4" start="16" type="Blend Factor"/> + <field name="Color blend mode" size="4" start="12" type="Blend Mode"/> + <field name="Alpha blend dst factor" size="4" start="8" type="Blend Factor"/> + <field name="Alpha blend src factor" size="4" start="4" type="Blend Factor"/> + <field name="Alpha blend mode" size="4" start="0" type="Blend Mode"/> + </packet> + + <packet code="84" name="Blend Cfg" min_ver="41"> + <field name="Render Target Mask" size="4" start="24" type="uint"/> + <field name="Color blend dst factor" size="4" start="20" type="Blend Factor"/> + <field name="Color blend src factor" size="4" start="16" type="Blend Factor"/> + <field name="Color blend mode" size="4" start="12" type="Blend Mode"/> <field name="Alpha blend dst factor" size="4" start="8" type="Blend Factor"/> <field name="Alpha blend src factor" size="4" start="4" type="Blend Factor"/> <field name="Alpha blend mode" size="4" start="0" type="Blend Mode"/> </packet> - <packet code="86" name="Blend Constant Colour"> + <packet code="86" shortname="blend_ccolor" name="Blend Constant Color"> <field name="Alpha (F16)" size="16" start="48" type="uint"/> <field name="Blue (F16)" size="16" start="32" type="uint"/> <field name="Green (F16)" size="16" start="16" type="uint"/> <field name="Red (F16)" size="16" start="0" type="uint"/> </packet> - <packet code="87" name="Colour Write Masks"> - <field name="Reserved" size="16" start="16" type="uint"/> - <field name="Render Target 3 per colour component write masks" size="4" start="12" type="uint"/> - <field name="Render Target 2 per colour component write masks" size="4" start="8" type="uint"/> - <field name="Render Target 1 per colour component write masks" size="4" start="4" type="uint"/> - <field name="Render Target 0 per colour component write masks" size="4" start="0" type="uint"/> + <packet code="87" shortname="color_wmasks" name="Color Write Masks"> + <field name="Mask" size="32" start="0" type="uint"/> </packet> - <packet code="96" name="Configuration Bits"> + <packet code="88" name="Zero All Centroid Flags" min_ver="41"/> + + <packet code="89" name="Centroid Flags" min_ver="41"> + <field name="Centroid Flags for varyings V0*24" size="24" start="8" type="uint"/> + <field name="Action for Centroid Flags of higher numbered varyings" size="2" start="6" type="Varying Flags Action"/> + <field name="Action for Centroid Flags of lower numbered varyings" size="2" start="4" type="Varying Flags Action"/> + <field name="Varying offset V0" size="4" start="0" type="uint"/> + </packet> + + <packet code="91" name="Sample State" min_ver="41"> + <field name="Coverage" size="16" start="16" type="f187"/> + <field name="Mask" size="4" start="0" type="uint"/> + </packet> + + <packet code="92" shortname="occlusion_query_counter_enable" name="Occlusion Query Counter"> + <field name="address" size="32" start="0" type="address"/> + </packet> + + <packet code="96" name="Cfg Bits"> <field name="Direct3D Provoking Vertex" size="1" start="21" type="bool"/> <field name="Direct3D 'Point-fill' mode" size="1" start="20" type="bool"/> <field name="Blend enable" size="1" start="19" type="bool"/> @@ -317,8 +647,6 @@ <field name="Z updates enable" size="1" start="15" type="bool"/> <field name="Depth-Test Function" size="3" start="12" type="Compare Function"/> <field name="Direct3D Wireframe triangles mode" size="1" start="11" type="bool"/> - <field name="Coverage Update Mode" size="2" start="9" type="uint"/> - <field name="Coverage Pipe Select" size="1" start="8" type="bool"/> <field name="Rasterizer Oversample Mode" size="2" start="6" type="uint"/> <field name="Line Rasterization" size="2" start="4" type="uint"/> <field name="Enable Depth Offset" size="1" start="3" type="bool"/> @@ -327,12 +655,21 @@ <field name="Enable Forward Facing Primitive" size="1" start="0" type="bool"/> </packet> - <packet code="97" name="Zero All Flat Shade Flags"/> + <packet code="97" shortname="zero_all_flatshade_flags" name="Zero All Flat Shade Flags"/> - <packet code="98" name="Flat Shade Flags"> + <packet code="98" shortname="flatshade_flags" name="Flat Shade Flags"> <field name="Flat Shade Flags for varyings V0*24" size="24" start="8" type="uint"/> - <field name="Action for Flat Shade Flags of higher numbered varyings" size="2" start="6" type="uint"/> - <field name="Action for Flat Shade Flags of lower numbered varyings" size="2" start="4" type="uint"/> + <field name="Action for Flat Shade Flags of higher numbered varyings" size="2" start="6" type="Varying Flags Action"/> + <field name="Action for Flat Shade Flags of lower numbered varyings" size="2" start="4" type="Varying Flags Action"/> + <field name="Varying offset V0" size="4" start="0" type="uint"/> + </packet> + + <packet code="99" shortname="zero_all_noperspective_flags" name="Zero All Non-perspective Flags" min_ver="41"/> + + <packet code="100" shortname="noperspective_flags" name="Non-perspective Flags" min_ver="41"> + <field name="Non-perspective Flags for varyings V0*24" size="24" start="8" type="uint"/> + <field name="Action for Non-perspective Flags of higher numbered varyings" size="2" start="6" type="Varying Flags Action"/> + <field name="Action for Non-perspective Flags of lower numbered varyings" size="2" start="4" type="Varying Flags Action"/> <field name="Varying offset V0" size="4" start="0" type="uint"/> </packet> @@ -344,54 +681,66 @@ <field name="Line width" size="32" start="0" type="float"/> </packet> - <packet name="Depth Offset" code="106"> - <!-- these fields are both float-1-8-7 encoded (top 16 bits of a float32) --> - <field name="Depth Offset Units" size="16" start="16" type="uint"/> - <field name="Depth Offset Factor" size="16" start="0" type="uint"/> + <packet name="Depth Offset" code="106" max_ver="33"> + <field name="Depth Offset Units" size="16" start="16" type="f187"/> + <field name="Depth Offset Factor" size="16" start="0" type="f187"/> + </packet> + + <packet name="Depth Offset" code="106" min_ver="41"> + <field name="Limit" size="32" start="32" type="float"/> + <field name="Depth Offset Units" size="16" start="16" type="f187"/> + <field name="Depth Offset Factor" size="16" start="0" type="f187"/> </packet> - <packet name="Clip Window" code="107"> + <packet shortname="clip" name="clip_window" code="107"> <field name="Clip Window Height in pixels" size="16" start="48" type="uint"/> <field name="Clip Window Width in pixels" size="16" start="32" type="uint"/> <field name="Clip Window Bottom Pixel Coordinate" size="16" start="16" type="uint"/> <field name="Clip Window Left Pixel Coordinate" size="16" start="0" type="uint"/> </packet> - <packet name="Viewport Offset" code="108"> + <packet name="Viewport Offset" code="108" max_ver="33"> <field name="Viewport Centre Y-coordinate" size="32" start="32" type="s24.8"/> <field name="Viewport Centre X-coordinate" size="32" start="0" type="s24.8"/> </packet> - <packet name="Clipper Z min/max clipping planes" code="109"> + <packet name="Viewport Offset" code="108" min_ver="41"> + <field name="Coarse Y" size="10" start="54" type="uint"/> + <field name="Viewport Centre Y-coordinate" size="22" start="32" type="s14.8"/> + <field name="Coarse X" size="10" start="22" type="uint"/> + <field name="Viewport Centre X-coordinate" size="22" start="0" type="s14.8"/> + </packet> + + <packet shortname="clipz" name="Clipper Z min/max clipping planes" code="109"> <field name="Maximum Zw" size="32" start="32" type="float"/> <field name="Minimum Zw" size="32" start="0" type="float"/> </packet> - <packet name="Clipper XY Scaling" code="110" cl="B"> + <packet shortname="clipper_xy" name="Clipper XY Scaling" code="110" cl="B"> <field name="Viewport Half-Height in 1/256th of pixel" size="32" start="32" type="float"/> <field name="Viewport Half-Width in 1/256th of pixel" size="32" start="0" type="float"/> </packet> - <packet name="Clipper Z Scale and Offset" code="111" cl="B"> + <packet shortname="clipper_z" name="Clipper Z Scale and Offset" code="111" cl="B"> <field name="Viewport Z Offset (Zc to Zs)" size="32" start="32" type="float"/> <field name="Viewport Z Scale (Zc to Zs)" size="32" start="0" type="float"/> </packet> - <packet code="120" name="Tile Binning Mode Configuration (Part1)"> + <packet name="Number of Layers" code="119" min_ver="41"> + <field name="Number of Layers" size="8" start="0" type="uint" minus_one="true"/> + </packet> + + <packet code="120" name="Tile Binning Mode Cfg (Part1)" max_ver="33"> <field name="Double-buffer in non-ms mode" size="1" start="63" type="bool"/> <field name="Multisample Mode (4x)" size="1" start="62" type="bool"/> - <field name="Maximum BPP of all render targets" size="2" start="60" type="uint"> - <value name="Render target maximum 32bpp" value="0"/> - <value name="Render target maximum 64bpp" value="1"/> - <value name="Render target maximum 128bpp" value="2"/> - </field> + <field name="Maximum BPP of all render targets" size="2" start="60" type="Internal BPP"/> <field name="Number of Render Targets" size="4" start="56" type="uint"/> <field name="Height (in tiles)" size="12" start="44" type="uint"/> <field name="Width (in tiles)" size="12" start="32" type="uint"/> - <field name="Tile State Data Array Base Address" size="32" start="0" type="address"/> + <field name="Tile State Data Array Base Address" size="26" start="6" type="address"/> <field name="tile allocation block size" size="2" start="4" type="uint"> <value name="tile allocation block size 64b" value="0"/> @@ -407,14 +756,42 @@ <field name="sub-id" size="1" start="0" type="uint" default="0"/> </packet> - <packet code="120" name="Tile Binning Mode Configuration (Part2)" cl="B"> + <packet code="120" name="Tile Binning Mode Cfg" min_ver="41"> + + <field name="Height (in pixels)" size="12" start="48" type="uint" minus_one="true"/> + <field name="Width (in pixels)" size="12" start="32" type="uint" minus_one="true"/> + + <field name="Double-buffer in non-ms mode" size="1" start="15" type="bool"/> + <field name="Multisample Mode (4x)" size="1" start="14" type="bool"/> + + <field name="Maximum BPP of all render targets" size="2" start="12" type="uint"> + <value name="Render target maximum 32bpp" value="0"/> + <value name="Render target maximum 64bpp" value="1"/> + <value name="Render target maximum 128bpp" value="2"/> + </field> + + <field name="Number of Render Targets" size="4" start="8" type="uint" minus_one="true"/> + + <field name="tile allocation block size" size="2" start="4" type="uint"> + <value name="tile allocation block size 64b" value="0"/> + <value name="tile allocation block size 128b" value="1"/> + <value name="tile allocation block size 256b" value="2"/> + </field> + <field name="tile allocation initial block size" size="2" start="2" type="uint"> + <value name="tile allocation initial block size 64b" value="0"/> + <value name="tile allocation initial block size 128b" value="1"/> + <value name="tile allocation initial block size 256b" value="2"/> + </field> + </packet> + + <packet code="120" name="Tile Binning Mode Cfg (Part2)" cl="B" max_ver="33"> <field name="Tile Allocation Memory Address" size="32" start="32" type="address"/> <field name="Tile Allocation Memory Size" size="32" start="0" type="uint"/> <field name="sub-id" size="1" start="0" type="uint" default="1"/> </packet> - <packet code="121" name="Tile Rendering Mode Configuration (Common Configuration)" cl="R"> + <packet code="121" name="Tile Rendering Mode Cfg (Common)" cl="R" max_ver="33"> <field name="Disable Render Target Stores" size="8" start="56" type="uint"/> <field name="Enable Z Store" size="1" start="55" type="bool"/> <field name="Enable Stencil Store" size="1" start="54" type="bool"/> @@ -426,7 +803,6 @@ <value name="Early-Z direction GT/GE" value="1"/> </field> - <field name="Select Coverage Mode" size="1" start="44" type="bool"/> <field name="Double-buffer in non-ms mode" size="1" start="43" type="bool"/> <field name="Multisample Mode (4x)" size="1" start="42" type="bool"/> @@ -438,123 +814,92 @@ <field name="Image Height (pixels)" size="16" start="24" type="uint"/> <field name="Image Width (pixels)" size="16" start="8" type="uint"/> - <field name="Number of Render Targets Minus 1" size="4" start="4" type="uint"/> + <field name="Number of Render Targets" size="4" start="4" type="uint" minus_one="true"/> + + <field name="sub-id" size="4" start="0" type="uint" default="0"/> + </packet> + + <packet code="121" name="Tile Rendering Mode Cfg (Common)" cl="R" min_ver="41"> + <field name="Pad" size="12" start="52" type="uint"/> + + <field name="Early Depth/Stencil Clear" size="1" start="51" type="bool"/> + <field name="Internal Depth Type" size="4" start="47" type="Internal Depth Type"/> + + <field name="Early-Z disable" size="1" start="46" type="bool"/> + + <field name="Early-Z Test and Update Direction" size="1" start="45" type="uint"> + <value name="Early-Z direction LT/LE" value="0"/> + <value name="Early-Z direction GT/GE" value="1"/> + </field> + + <field name="Double-buffer in non-ms mode" size="1" start="43" type="bool"/> + <field name="Multisample Mode (4x)" size="1" start="42" type="bool"/> + + <field name="Maximum BPP of all render targets" size="2" start="40" type="Internal BPP"/> + + <field name="Image Height (pixels)" size="16" start="24" type="uint"/> + <field name="Image Width (pixels)" size="16" start="8" type="uint"/> + <field name="Number of Render Targets" size="4" start="4" type="uint" minus_one="true"/> <field name="sub-id" size="4" start="0" type="uint" default="0"/> </packet> - <packet code="121" name="Tile Rendering Mode Configuration (Render Target config)" cl="R"> + <packet code="121" name="Tile Rendering Mode Cfg (Color)" cl="R" max_ver="33"> <field name="Address" size="32" start="32" type="address"/> <field name="Pad" size="4" start="28" type="uint"/> <field name="Flip Y" size="1" start="27" type="bool"/> - <field name="Memory Format" size="3" start="24" type="uint" prefix="Memory Format"> - <value name="Raster" value="0"/> - <value name="Lineartile" value="1"/> - <value name="UB-linear (1 UIF block wide)" value="2"/> - <value name="UB-linear (2 UIF blocks wide)" value="3"/> - <value name="UIF (No XOR)" value="4"/> - <value name="UIF (XOR)" value="5"/> - </field> + <field name="Memory Format" size="3" start="24" type="Memory Format"/> - <field name="A dithered" size="1" start="23" type="bool"/> - <field name="BGR dithered" size="1" start="22" type="bool"/> - - <field name="Output image format" size="6" start="16" type="uint" prefix="Output Image Format"> - <value name="srgb8_alpha8" value="0"/> - <value name="srgb" value="1"/> - <value name="rgb10_a2ui" value="2"/> - <value name="rgb10_a2" value="3"/> - <value name="abgr1555" value="4"/> - <value name="alpha-masked abgr1555" value="5"/> - <value name="abgr4444" value="6"/> - <value name="bgr565" value="7"/> - <value name="r11f_g11f_b10f" value="8"/> - <value name="rgba32f" value="9"/> - <value name="rg32f" value="10"/> - <value name="r32f" value="11"/> - <value name="rgba32i" value="12"/> - <value name="rg32i" value="13"/> - <value name="r32i" value="14"/> - <value name="rgba32ui" value="15"/> - <value name="rg32ui" value="16"/> - <value name="r32ui" value="17"/> - <value name="rgba16f" value="18"/> - <value name="rg16f" value="19"/> - <value name="r16f" value="20"/> - <value name="rgba16i" value="21"/> - <value name="rg16i" value="22"/> - <value name="r16i" value="23"/> - <value name="rgba16ui" value="24"/> - <value name="rg16ui" value="25"/> - <value name="r16ui" value="26"/> - <value name="rgba8" value="27"/> - <value name="rgb8" value="28"/> - <value name="rg8" value="29"/> - <value name="r8" value="30"/> - <value name="rgba8i" value="31"/> - <value name="rg8i" value="32"/> - <value name="r8i" value="33"/> - <value name="rgba8ui" value="34"/> - <value name="rg8ui" value="35"/> - <value name="r8ui" value="36"/> - <value name="srgbx8" value="37"/> - <value name="rgbx8" value="38"/> - </field> + <field name="Dither Mode" size="2" start="22" type="Dither Mode"/> - <field name="Decimate mode" size="2" start="14" type="uint"/> + <field name="Output image format" size="6" start="16" type="Output Image Format"/> - <field name="Internal Type" size="4" start="10" type="uint" prefix="Internal Type"> - <value name="8i" value="0"/> - <value name="8ui" value="1"/> - <value name="8" value="2"/> - <value name="16i" value="4"/> - <value name="16ui" value="5"/> - <value name="16f" value="6"/> - <value name="32i" value="8"/> - <value name="32ui" value="9"/> - <value name="32f" value="10"/> - </field> + <field name="Decimate mode" size="2" start="14" type="Decimate Mode"/> - <field name="Internal BPP" size="2" start="8" type="uint" prefix="Internal Bpp"> - <value name="32" value="0"/> - <value name="64" value="1"/> - <value name="128" value="2"/> - </field> + <field name="Internal Type" size="4" start="10" type="Internal Type"/> + <field name="Internal BPP" size="2" start="8" type="Internal BPP"/> <field name="Render Target Number" size="4" start="4" type="uint"/> <field name="sub-id" size="4" start="0" type="uint" default="2"/> </packet> - <packet code="121" name="Tile Rendering Mode Configuration (Z/Stencil config)" cl="R"> - <field name="Address" size="32" start="32" type="address"/> + <packet code="121" name="Tile Rendering Mode Cfg (Color)" cl="R" min_ver="41"> + + <field name="Pad" size="28" start="34" type="uint"/> + + <field name="Render Target 3 Clamp" size="2" start="32" type="Render Target Clamp"/> + <field name="Render Target 3 Internal Type" size="4" start="30" type="Internal Type"/> + <field name="Render Target 3 Internal BPP" size="2" start="28" type="Internal BPP"/> + + <field name="Render Target 2 Clamp" size="2" start="26" type="Render Target Clamp"/> + <field name="Render Target 2 Internal Type" size="4" start="22" type="Internal Type"/> + <field name="Render Target 2 Internal BPP" size="2" start="20" type="Internal BPP"/> + + <field name="Render Target 1 Clamp" size="2" start="18" type="Render Target Clamp"/> + <field name="Render Target 1 Internal Type" size="4" start="14" type="Internal Type"/> + <field name="Render Target 1 Internal BPP" size="2" start="12" type="Internal BPP"/> + + <field name="Render Target 0 Clamp" size="2" start="10" type="Render Target Clamp"/> + <field name="Render Target 0 Internal Type" size="4" start="6" type="Internal Type"/> + <field name="Render Target 0 Internal BPP" size="2" start="4" type="Internal BPP"/> + + <field name="sub-id" size="4" start="0" type="uint" default="1"/> + </packet> + + <packet code="121" name="Tile Rendering Mode Cfg (Z/Stencil)" cl="R" max_ver="33"> + <field name="Address" size="26" start="38" type="address"/> <field name="Padded height of output image in UIF blocks" size="13" start="25" type="uint"/> - <field name="Memory Format" size="3" start="22" type="uint" prefix="Memory Format"> - <value name="Raster" value="0"/> - <value name="Lineartile" value="1"/> - <value name="UB-linear (1 UIF block wide)" value="2"/> - <value name="UB-linear (2 UIF blocks wide)" value="3"/> - <value name="UIF (No XOR)" value="4"/> - <value name="UIF (XOR)" value="5"/> - </field> + <field name="Memory Format" size="3" start="22" type="Memory Format"/> - <field name="Output image format" size="6" start="16" type="uint" prefix="Output Image Format"> - <value name="depth_component32f" value="0"/> - <value name="depth_component24" value="1"/> - <value name="depth_component16" value="2"/> - <value name="depth24_stencil8" value="3"/> - </field> + <field name="Output image format" size="6" start="16" type="Z/S Output Image Format"/> <field name="Decimate mode" size="2" start="14" type="uint"/> - <field name="Internal Type" size="4" start="10" type="uint" prefix="Internal Type"> - <value name="depth_32f" value="0"/> - <value name="depth_24" value="1"/> - <value name="depth_16" value="2"/> - </field> + <field name="Internal Type" size="4" start="10" type="Internal Depth Type"/> <field name="Internal BPP (ignored)" size="2" start="8" type="uint"/> <!-- selects between Z/Stencil config packet and Separate Stencil packet. --> @@ -562,16 +907,25 @@ <field name="sub-id" size="4" start="0" type="uint" default="1"/> </packet> - <packet code="121" name="Tile Rendering Mode Configuration (Z Stencil Clear Values)" cl="R"> + <packet code="121" name="Tile Rendering Mode Cfg (ZS Clear Values)" cl="R" max_ver="33"> <field name="unused" size="16" start="48" type="uint"/> <field name="Z Clear Value" size="32" start="16" type="float"/> - <field name="Stencil/VG Mask Clear Value" size="8" start="8" type="uint"/> + <field name="Stencil Clear Value" size="8" start="8" type="uint"/> <field name="sub-id" size="4" start="0" type="uint" default="3"/> </packet> - <packet code="121" name="Tile Rendering Mode Configuration (Clear Colors Part1)" cl="R"> + <packet code="121" name="Tile Rendering Mode Cfg (ZS Clear Values)" cl="R" min_ver="41"> + <field name="unused" size="16" start="48" type="uint"/> + + <field name="Z Clear Value" size="32" start="16" type="float"/> + + <field name="Stencil Clear Value" size="8" start="8" type="uint"/> + <field name="sub-id" size="4" start="0" type="uint" default="2"/> + </packet> + + <packet code="121" name="Tile Rendering Mode Cfg (Clear Colors Part1)" cl="R" max_ver="33"> <!-- Express this as a 56-bit field? --> <field name="Clear Color next 24 bits" size="24" start="40" type="uint"/> <field name="Clear Color low 32 bits" size="32" start="8" type="uint"/> @@ -580,7 +934,16 @@ <field name="sub-id" size="4" start="0" type="uint" default="4"/> </packet> - <packet code="121" name="Tile Rendering Mode Configuration (Clear Colors Part2)" cl="R"> + <packet code="121" name="Tile Rendering Mode Cfg (Clear Colors Part1)" cl="R" min_ver="41"> + <!-- Express this as a 56-bit field? --> + <field name="Clear Color next 24 bits" size="24" start="40" type="uint"/> + <field name="Clear Color low 32 bits" size="32" start="8" type="uint"/> + + <field name="Render Target number" size="4" start="4" type="uint"/> + <field name="sub-id" size="4" start="0" type="uint" default="3"/> + </packet> + + <packet code="121" name="Tile Rendering Mode Cfg (Clear Colors Part2)" cl="R" max_ver="33"> <!-- Express this as a 56-bit field? --> <field name="Clear Color mid-high 24 bits" size="24" start="40" type="uint"/> <field name="Clear Color mid-low 32 bits" size="32" start="8" type="uint"/> @@ -589,7 +952,16 @@ <field name="sub-id" size="4" start="0" type="uint" default="5"/> </packet> - <packet code="121" name="Tile Rendering Mode Configuration (Clear Colors Part3)" cl="R"> + <packet code="121" name="Tile Rendering Mode Cfg (Clear Colors Part2)" cl="R" min_ver="41"> + <!-- Express this as a 56-bit field? --> + <field name="Clear Color mid-high 24 bits" size="24" start="40" type="uint"/> + <field name="Clear Color mid-low 32 bits" size="32" start="8" type="uint"/> + + <field name="Render Target number" size="4" start="4" type="uint"/> + <field name="sub-id" size="4" start="0" type="uint" default="4"/> + </packet> + + <packet code="121" name="Tile Rendering Mode Cfg (Clear Colors Part3)" cl="R" max_ver="33"> <field name="pad" size="11" start="53" type="uint"/> <field name="UIF padded height in UIF blocks" size="13" start="40" type="uint"/> <!-- image height is for Y flipping --> @@ -600,12 +972,24 @@ <field name="sub-id" size="4" start="0" type="uint" default="6"/> </packet> - <packet code="124" name="Tile Coordinates"> + <packet code="121" name="Tile Rendering Mode Cfg (Clear Colors Part3)" cl="R" min_ver="41"> + <field name="pad" size="11" start="53" type="uint"/> + <field name="UIF padded height in UIF blocks" size="13" start="40" type="uint"/> + <!-- image height is for Y flipping --> + <field name="Raster Row Stride or Image Height in Pixels" size="16" start="24" type="uint"/> + <field name="Clear Color high 16 bits" size="16" start="8" type="uint"/> + + <field name="Render Target number" size="4" start="4" type="uint"/> + <field name="sub-id" size="4" start="0" type="uint" default="5"/> + </packet> + + <packet code="124" shortname="tile_coords" name="Tile Coordinates"> <field name="tile row number" size="12" start="12" type="uint"/> <field name="tile column number" size="12" start="0" type="uint"/> </packet> - <packet code="122" name="Multicore Rendering Supertile Configuration" cl="R"> + <packet code="122" name="Multicore Rendering Supertile Cfg" cl="R"> + <field name="Number of Bin Tile Lists" size="3" start="61" type="uint" minus_one="true"/> <field name="Supertile Raster Order" size="1" start="60" type="bool"/> <field name="Multicore Enable" size="1" start="56" type="bool"/> @@ -615,17 +999,17 @@ <field name="Total Frame Height in Supertiles" size="8" start="24" type="uint"/> <field name="Total Frame Width in Supertiles" size="8" start="16" type="uint"/> - <field name="Supertile Height in Tiles minus 1" size="8" start="8" type="uint"/> - <field name="Supertile Width in Tiles minus 1" size="8" start="0" type="uint"/> + <field name="Supertile Height in Tiles" size="8" start="8" type="uint" minus_one="true"/> + <field name="Supertile Width in Tiles" size="8" start="0" type="uint" minus_one="true"/> </packet> - <packet code="123" name="Multicore Rendering Tile List Set Base" cl="R"> + <packet code="123" shortname="multicore_rendering_tile_list_base" name="Multicore Rendering Tile List Set Base" cl="R"> <field name="address" size="26" start="6" type="address"/> <field name="Tile List Set Number" size="4" start="0" type="uint"/> </packet> <!-- add fields --> - <packet code="125" name="Tile Coordinates Implicit"/> + <packet code="125" shortname="implicit_tile_coords" name="Tile Coordinates Implicit"/> <packet code="126" name="Tile List Initial Block Size"> <field name="Use auto-chained tile lists" size="1" start="2" type="bool"/> @@ -637,7 +1021,7 @@ </field> </packet> - <struct name="GL Shader State Record"> + <struct name="GL Shader State Record" max_ver="33"> <field name="Point size in shaded vertex data" size="1" start="0" type="bool"/> <field name="Enable clipping" size="1" start="1" type="bool"/> <field name="Vertex ID read by coordinate shader" size="1" start="2" type="bool"/> @@ -657,17 +1041,128 @@ <field name="Vertex Shader input VPM segment size" size="8" start="7b" type="uint"/> <field name="Address of default attribute values" size="32" start="8b" type="address"/> <field name="Fragment Shader Code Address" size="29" start="99" type="address"/> - <field name="2-way threadable" size="1" start="96" type="bool"/> - <field name="4-way threadable" size="1" start="97" type="bool"/> - <field name="Propagate NaNs" size="1" start="98" type="bool"/> + <field name="Fragment Shader 2-way threadable" size="1" start="96" type="bool"/> + <field name="Fragment Shader 4-way threadable" size="1" start="97" type="bool"/> + <field name="Fragment Shader Propagate NaNs" size="1" start="98" type="bool"/> <field name="Fragment Shader Uniforms Address" size="32" start="16b" type="address"/> <field name="Vertex Shader Code Address" size="32" start="20b" type="address"/> + <field name="Vertex Shader 2-way threadable" size="1" start="160" type="bool"/> + <field name="Vertex Shader 4-way threadable" size="1" start="161" type="bool"/> + <field name="Vertex Shader Propagate NaNs" size="1" start="162" type="bool"/> <field name="Vertex Shader Uniforms Address" size="32" start="24b" type="address"/> <field name="Coordinate Shader Code Address" size="32" start="28b" type="address"/> + <field name="Coordinate Shader 2-way threadable" size="1" start="224" type="bool"/> + <field name="Coordinate Shader 4-way threadable" size="1" start="225" type="bool"/> + <field name="Coordinate Shader Propagate NaNs" size="1" start="226" type="bool"/> <field name="Coordinate Shader Uniforms Address" size="32" start="32b" type="address"/> </struct> - <struct name="GL Shader State Attribute Record"> + <struct name="GL Shader State Record" min_ver="41"> + <field name="Point size in shaded vertex data" size="1" start="0" type="bool"/> + <field name="Enable clipping" size="1" start="1" type="bool"/> + + <field name="Vertex ID read by coordinate shader" size="1" start="2" type="bool"/> + <field name="Instance ID read by coordinate shader" size="1" start="3" type="bool"/> + <field name="Base Instance ID read by coordinate shader" size="1" start="4" type="bool"/> + <field name="Vertex ID read by vertex shader" size="1" start="5" type="bool"/> + <field name="Instance ID read by vertex shader" size="1" start="6" type="bool"/> + <field name="Base Instance ID read by vertex shader" size="1" start="7" type="bool"/> + + <field name="Fragment shader does Z writes" size="1" start="8" type="bool"/> + <field name="Turn off early-z test" size="1" start="9" type="bool"/> + <field name="Coordinate shader has separate input and output VPM blocks" size="1" start="10" type="bool"/> + <field name="Vertex shader has separate input and output VPM blocks" size="1" start="11" type="bool"/> + <field name="Fragment shader uses real pixel centre W in addition to centroid W2" size="1" start="12" type="bool"/> + <field name="Enable Sample Rate Shading" size="1" start="13" type="bool"/> + <field name="Any shader reads hardware-written Primitive ID" size="1" start="14" type="bool"/> + <field name="Insert Primitive ID as first varying to fragment shader" size="1" start="15" type="bool"/> + <field name="Turn off scoreboard" size="1" start="16" type="bool"/> + <field name="Do scoreboard wait on first thread switch" size="1" start="17" type="bool"/> + <field name="Disable implicit point/line varyings" size="1" start="18" type="bool"/> + <field name="No prim pack" size="1" start="19" type="bool"/> + + <field name="Number of varyings in Fragment Shader" size="8" start="3b" type="uint"/> + + <field name="Coordinate Shader output VPM segment size" size="4" start="4b" type="uint"/> + <field name="Min Coord Shader output segments required in play in addition to VCM cache size" size="4" start="36" type="uint"/> + + <field name="Coordinate Shader input VPM segment size" size="4" start="5b" type="uint"/> + <field name="Min Coord Shader input segments required in play" size="4" start="44" type="uint" minus_one="true"/> + + <field name="Vertex Shader output VPM segment size" size="4" start="6b" type="uint"/> + <field name="Min Vertex Shader output segments required in play in addition to VCM cache size" size="4" start="52" type="uint"/> + + <field name="Vertex Shader input VPM segment size" size="4" start="7b" type="uint"/> + <field name="Min Vertex Shader input segments required in play" size="4" start="60" type="uint" minus_one="true"/> + + <field name="Address of default attribute values" size="32" start="8b" type="address"/> + + <field name="Fragment Shader Code Address" size="29" start="99" type="address"/> + <field name="Fragment Shader 4-way threadable" size="1" start="96" type="bool"/> + <field name="Fragment Shader start in final thread section" size="1" start="97" type="bool"/> + <field name="Fragment Shader Propagate NaNs" size="1" start="98" type="bool"/> + <field name="Fragment Shader Uniforms Address" size="32" start="16b" type="address"/> + + <field name="Vertex Shader Code Address" size="29" start="163" type="address"/> + <field name="Vertex Shader 4-way threadable" size="1" start="160" type="bool"/> + <field name="Vertex Shader start in final thread section" size="1" start="161" type="bool"/> + <field name="Vertex Shader Propagate NaNs" size="1" start="162" type="bool"/> + <field name="Vertex Shader Uniforms Address" size="32" start="24b" type="address"/> + + <field name="Coordinate Shader Code Address" size="29" start="227" type="address"/> + <field name="Coordinate Shader 4-way threadable" size="1" start="224" type="bool"/> + <field name="Coordinate Shader start in final thread section" size="1" start="225" type="bool"/> + <field name="Coordinate Shader Propagate NaNs" size="1" start="226" type="bool"/> + <field name="Coordinate Shader Uniforms Address" size="32" start="32b" type="address"/> + </struct> + + <struct name="Geometry Shader State Record" min_ver="41"> + <field name="Geometry Bin Mode Shader Code Address" size="32" start="0b" type="address"/> + <field name="4-way threadable" size="1" start="0" type="bool"/> + <field name="Start in final thread section" size="1" start="1" type="bool"/> + <field name="Propagate NaNs" size="1" start="2" type="bool"/> + <field name="Geometry Bin Mode Shader Uniforms Address" size="32" start="4b" type="address"/> + <field name="Geometry Render Mode Shader Code Address" size="32" start="8b" type="address"/> + <field name="Geometry Render Mode Shader Uniforms Address" size="32" start="12b" type="address"/> + </struct> + + <struct name="Tessellation Shader State Record" min_ver="41"> + <field name="Tessellation Bin Mode Control Shader Code Address" size="32" start="0b" type="address"/> + <field name="Tessellation Bin Mode Control Shader Uniforms Address" size="32" start="4b" type="address"/> + <field name="Tessellation Render Mode Control Shader Code Address" size="32" start="8b" type="address"/> + <field name="Tessellation Render Mode Control Shader Uniforms Address" size="32" start="12b" type="address"/> + + <field name="Tessellation Bin Mode Evaluation Shader Code Address" size="32" start="16b" type="address"/> + <field name="Tessellation Bin Mode Evaluation Shader Uniforms Address" size="32" start="20b" type="address"/> + <field name="Tessellation Render Mode Evaluation Shader Code Address" size="32" start="24b" type="address"/> + <field name="Tessellation Render Mode Evaluation Shader Uniforms Address" size="32" start="28b" type="address"/> + </struct> + + <struct name="GL Shader State Attribute Record" max_ver="33"> + <field name="Address" size="32" start="0" type="address"/> + + <field name="Vec size" size="2" start="32" type="uint"/> + <field name="Type" size="3" start="34" type="uint"> + <value name="Attribute half-float" value="1"/> + <value name="Attribute float" value="2"/> + <value name="Attribute fixed" value="3"/> + <value name="Attribute byte" value="4"/> + <value name="Attribute short" value="5"/> + <value name="Attribute int" value="6"/> + <value name="Attribute int2_10_10_10" value="7"/> + </field> + <field name="Signed int type" size="1" start="37" type="bool"/> + <field name="Normalized int type" size="1" start="38" type="bool"/> + <field name="Read as int/uint" size="1" start="39" type="bool"/> + + <field name="Number of values read by Coordinate shader" size="4" start="40" type="uint"/> + <field name="Number of values read by Vertex shader" size="4" start="44" type="uint"/> + + <field name="Instance Divisor" size="16" start="6b" type="uint"/> + <field name="Stride" size="32" start="8b" type="uint"/> + </struct> + + <struct name="GL Shader State Attribute Record" min_ver="41"> <field name="Address" size="32" start="0" type="address"/> <field name="Vec size" size="2" start="32" type="uint"/> @@ -689,6 +1184,7 @@ <field name="Instance Divisor" size="16" start="6b" type="uint"/> <field name="Stride" size="32" start="8b" type="uint"/> + <field name="Maximum Index" size="32" start="12b" type="uint"/> </struct> <struct name="VPM generic block write setup"> @@ -727,7 +1223,7 @@ <field name="addr" size="13" start="0" type="uint"/> </struct> - <struct name="Texture Uniform Parameter 0 CFG_MODE=1"> + <struct name="Texture Uniform Parameter 0 CFG_MODE=1" max_ver="33"> <field name="Per-pixel mask enable" size="1" start="31" type="bool"/> <field name="Texel offset for r coordinate" size="4" start="27" type="int"/> @@ -767,7 +1263,7 @@ <field name="Gather sample mode" size="1" start="4" type="bool"/> <field name="Fetch sample mode" size="1" start="3" type="bool"/> - <field name="Lookup Type" size="3" start="0" type="bool"> + <field name="Lookup Type" size="3" start="0" type="uint"> <value name="Texture 2D" value="0"/> <value name="Texture 2D array" value="1"/> <value name="Texture 3D" value="2"/> @@ -778,18 +1274,59 @@ </field> </struct> - <struct name="Texture Uniform Parameter 1 CFG_MODE=1"> - <field name="Texture state record base address" size="32" start="0" type="address"/> - <field name="Return word 3 of texture data" size="1" start="3" type="bool"/> - <field name="Return word 2 of texture data" size="1" start="2" type="bool"/> - <field name="Return word 1 of texture data" size="1" start="1" type="bool"/> - <field name="Return word 0 of texture data" size="1" start="0" type="bool"/> + <struct name="Texture Uniform Parameter 1 CFG_MODE=1" max_ver="33"> + <field name="Texture state record base address" size="28" start="4" type="address"/> + <field name="Return words of texture data" size="4" start="0" type="uint"/> + </struct> + + <struct name="TMU Config Parameter 0" min_ver="41"> + <field name="Texture state address" size="32" start="0" type="address"/> + <field name="Return words of texture data" size="4" start="0" type="uint"/> + </struct> + + <struct name="TMU Config Parameter 1" min_ver="41"> + <field name="Sampler state address" size="32" start="0" type="address"/> + <field name="Per-pixel mask enable" size="1" start="2" type="bool"/> + <field name="Unnormalized coordinates" size="1" start="1" type="bool"/> + <field name="Output Type 32-bit" size="1" start="0" type="bool"/> </struct> - <struct name="Texture Shader State"> + <struct name="TMU Config Parameter 2" min_ver="41" max_ver="41"> + <field name="Pad" size="24" start="8" type="uint"/> + <field name="Op" size="4" start="20" type="TMU Op"/> + <field name="Offset R" size="4" start="16" type="int"/> + <field name="Offset T" size="4" start="12" type="int"/> + <field name="Offset S" size="4" start="8" type="int"/> + <field name="Gather Mode" size="1" start="7" type="bool"/> + <field name="Gather Component" size="2" start="5" type="uint"/> + <field name="Coefficient Mode" size="1" start="4" type="bool"/> + <field name="Sample Number" size="2" start="2" type="uint"/> + <field name="Disable AutoLOD" size="1" start="1" type="bool"/> + <field name="Offset Format 8" size="1" start="0" type="bool"/> + </struct> + + <struct name="TMU Config Parameter 2" min_ver="42"> + <field name="Pad" size="23" start="9" type="uint"/> + <field name="LOD Query" size="1" start="8" type="bool"/> + <field name="Op" size="4" start="20" type="TMU Op"/> + <field name="Offset R" size="4" start="16" type="int"/> + <field name="Offset T" size="4" start="12" type="int"/> + <field name="Offset S" size="4" start="8" type="int"/> + <field name="Gather Mode" size="1" start="7" type="bool"/> + <field name="Gather Component" size="2" start="5" type="uint"/> + <field name="Coefficient Mode" size="1" start="4" type="bool"/> + <field name="Sample Number" size="2" start="2" type="uint"/> + <field name="Disable AutoLOD" size="1" start="1" type="bool"/> + <field name="Offset Format 8" size="1" start="0" type="bool"/> + </struct> + + <struct name="Texture Shader State" max_ver="33"> + <field name="UIF XOR disable" size="1" start="255" type="bool"/> <field name="Level 0 is strictly UIF" size="1" start="254" type="bool"/> <field name="Level 0 XOR enable" size="1" start="252" type="bool"/> <field name="Level 0 UB_PAD" size="4" start="248" type="uint"/> + <field name="Output 32-bit" size="1" start="246" type="bool"/> + <field name="Sample Number" size="2" start="244" type="uint"/> <field name="Base Level" size="4" start="240" type="uint"/> <field name="Fixed Bias" size="16" start="224" type="s8.8"/> @@ -831,23 +1368,94 @@ <field name="Array Stride (64-byte aligned)" size="26" start="32" type="uint"/> + <field name="Texture base pointer" size="30" start="2" type="address"/> + + <field name="Filter" size="4" start="0" type="TMU Filter"/> + </struct> + + <struct name="Texture Shader State" min_ver="41"> + <field name="Pad" size="56" start="136" type="uint"/> + <field name="UIF XOR disable" size="1" start="135" type="bool"/> + <field name="Level 0 is strictly UIF" size="1" start="134" type="bool"/> + <field name="Level 0 XOR enable" size="1" start="132" type="bool"/> + <field name="Level 0 UB_PAD" size="4" start="128" type="uint"/> + + <field name="Base Level" size="4" start="124" type="uint"/> + <field name="Max Level" size="4" start="120" type="uint"/> + + <field name="Swizzle A" size="3" start="117" type="uint"> + <value name="Swizzle Zero" value="0"/> + <value name="Swizzle One" value="1"/> + <value name="Swizzle Red" value="2"/> + <value name="Swizzle Green" value="3"/> + <value name="Swizzle Blue" value="4"/> + <value name="Swizzle Alpha" value="5"/> + </field> + + <field name="Swizzle B" size="3" start="114" type="uint"/> + <field name="Swizzle G" size="3" start="111" type="uint"/> + <field name="Swizzle R" size="3" start="108" type="uint"/> + <field name="Extended" size="1" start="107" type="bool"/> + + <field name="Texture type" size="7" start="100" type="uint"/> + <field name="Image Depth" size="14" start="86" type="uint"/> + <field name="Image Height" size="14" start="72" type="uint"/> + <field name="Image Width" size="14" start="58" type="uint"/> + + <field name="Array Stride (64-byte aligned)" size="26" start="32" type="uint"/> + <field name="Texture base pointer" size="32" start="0" type="address"/> - <field name="Minification Filter" size="3" start="1" type="uint"/> - <field name="Magnification Filter" size="1" start="0" type="uint"/> + <field name="Reverse Standard Border Color" size="1" start="5" type="bool"/> + <field name="AHDR" size="1" start="4" type="bool"/> + <field name="sRGB" size="1" start="3" type="bool"/> + <field name="Flip S and T on incoming request" size="1" start="2" type="bool"/> + <field name="Flip texture Y Axis" size="1" start="1" type="bool"/> + <field name="Flip texture X Axis" size="1" start="0" type="bool"/> + </struct> + + <struct name="Sampler State" min_ver="41"> + <field name="Border color Alpha" size="32" start="160" type="uint"/> + <field name="Border color Blue" size="32" start="128" type="uint"/> + <field name="Border color Green" size="32" start="96" type="uint"/> + <field name="Border color Red" size="32" start="64" type="uint"/> + + <field name="Maximum Anisotropy" size="2" start="61" type="uint"/> + <field name="Border Color Mode" size="3" start="58" type="Border Color Mode"/> + <field name="Wrap I Border" size="1" start="57" type="bool"/> + <field name="Wrap R" size="3" start="54" type="Wrap Mode"/> + <field name="Wrap T" size="3" start="51" type="Wrap Mode"/> + <field name="Wrap S" size="3" start="48" type="Wrap Mode"/> + + <field name="Fixed Bias" size="16" start="32" type="s8.8"/> + <field name="Max Level-of-Detail" size="12" start="20" type="u4.8"/> + <field name="Min Level-of-Detail" size="12" start="8" type="u4.8"/> + + <field name="sRGB Disable" size="1" start="7" type="bool"/> + + <field name="Depth Compare Function" size="3" start="4" type="Compare Function"/> + + <field name="Anisotropy Enable" size="1" start="3" type="bool"/> + <field name="Mip filter Nearest" size="1" start="2" type="bool"/> + <field name="Min filter Nearest" size="1" start="1" type="bool"/> + <field name="Mag filter Nearest" size="1" start="0" type="bool"/> </struct> <enum name="Texture Data Formats"> + <!-- + most formats here have R in the low bits, A in the high bits. + Exceptions noted. + --> <value name="Texture Data Format R8" value="0"/> <value name="Texture Data Format R8 SNORM" value="1"/> <value name="Texture Data Format RG8" value="2"/> <value name="Texture Data Format RG8 SNORM" value="3"/> <value name="Texture Data Format RGBA8" value="4"/> <value name="Texture Data Format RGBA8 SNORM" value="5"/> - <value name="Texture Data Format RGB565" value="6"/> - <value name="Texture Data Format RGBA4" value="7"/> - <value name="Texture Data Format RGB5_A1" value="8"/> - <value name="Texture Data Format RGB10_A2" value="9"/> + <value name="Texture Data Format RGB565" value="6"/> <!-- B in low bits --> + <value name="Texture Data Format RGBA4" value="7"/> <!-- A low, R high --> + <value name="Texture Data Format RGB5_A1" value="8"/> <!-- A low, R high --> + <value name="Texture Data Format RGB10_A2" value="9"/> <!-- R low, A high --> <value name="Texture Data Format R16" value="10"/> <value name="Texture Data Format R16 SNORM" value="11"/> <value name="Texture Data Format RG16" value="12"/> @@ -862,7 +1470,7 @@ <value name="Texture Data Format DEPTH COMP16" value="21"/> <value name="Texture Data Format DEPTH COMP24" value="22"/> <value name="Texture Data Format DEPTH COMP32F" value="23"/> - <value name="Texture Data Format DEPTH24_X8" value="24"/> + <value name="Texture Data Format DEPTH24_X8" value="24"/> <!-- X low, D high --> <value name="Texture Data Format R4" value="25"/> <value name="Texture Data Format R1" value="26"/> <!-- generic unfiltered 8-bit sample --> @@ -906,5 +1514,28 @@ <value name="Texture Data Format ASTC_10x10" value="75"/> <value name="Texture Data Format ASTC_12x10" value="76"/> <value name="Texture Data Format ASTC_12x12" value="77"/> + + <value name="Texture Data Format R8I" value="96"/> + <value name="Texture Data Format R8UI" value="97"/> + <value name="Texture Data Format RG8I" value="98"/> + <value name="Texture Data Format RG8UI" value="99"/> + <value name="Texture Data Format RGBA8I" value="100"/> + <value name="Texture Data Format RGBA8UI" value="101"/> + + <value name="Texture Data Format R16I" value="102"/> + <value name="Texture Data Format R16UI" value="103"/> + <value name="Texture Data Format RG16I" value="104"/> + <value name="Texture Data Format RG16UI" value="105"/> + <value name="Texture Data Format RGBA16I" value="106"/> + <value name="Texture Data Format RGBA16UI" value="107"/> + + <value name="Texture Data Format R32I" value="108"/> + <value name="Texture Data Format R32UI" value="109"/> + <value name="Texture Data Format RG32I" value="110"/> + <value name="Texture Data Format RG32UI" value="111"/> + <value name="Texture Data Format RGBA32I" value="112"/> + <value name="Texture Data Format RGBA32UI" value="113"/> + <value name="Texture Data Format RGB10_A2UI" value="114"/> + </enum> </vcxml> diff --git a/lib/mesa/src/broadcom/cle/v3d_packet_v33_pack.h b/lib/mesa/src/broadcom/cle/v3d_packet_v33_pack.h index 934b0de4f..ba3bf8de8 100644 --- a/lib/mesa/src/broadcom/cle/v3d_packet_v33_pack.h +++ b/lib/mesa/src/broadcom/cle/v3d_packet_v33_pack.h @@ -9,7 +9,7 @@ #ifndef V3D33_PACK_H #define V3D33_PACK_H -#include "v3d_packet_helpers.h" +#include "cle/v3d_packet_helpers.h" enum V3D33_Compare_Function { @@ -81,6 +81,126 @@ enum V3D33_Primitive { V3D_PRIM_TRIANGLE_FAN_TF = 22, }; +enum V3D33_TMU_Filter { + V3D_TMU_FILTER_MIN_LIN_MIP_NONE_MAG_LIN = 0, + V3D_TMU_FILTER_MIN_LIN_MIP_NONE_MAG_NEAR = 1, + V3D_TMU_FILTER_MIN_NEAR_MIP_NONE_MAG_LIN = 2, + V3D_TMU_FILTER_MIN_NEAR_MIP_NONE_MAG_NEAR = 3, + V3D_TMU_FILTER_MIN_NEAR_MIP_NEAR_MAG_LIN = 4, + V3D_TMU_FILTER_MIN_NEAR_MIP_NEAR_MAG_NEAR = 5, + V3D_TMU_FILTER_MIN_NEAR_MIP_LIN_MAG_LIN = 6, + V3D_TMU_FILTER_MIN_NEAR_MIP_LIN_MAG_NEAR = 7, + V3D_TMU_FILTER_MIN_LIN_MIP_NEAR_MAG_LIN = 8, + V3D_TMU_FILTER_MIN_LIN_MIP_NEAR_MAG_NEAR = 9, + V3D_TMU_FILTER_MIN_LIN_MIP_LIN_MAG_LIN = 10, + V3D_TMU_FILTER_MIN_LIN_MIP_LIN_MAG_NEAR = 11, + V3D_TMU_FILTER_ANISOTROPIC_2_1 = 12, + V3D_TMU_FILTER_ANISOTROPIC_4_1 = 13, + V3D_TMU_FILTER_ANISOTROPIC_8_1 = 14, + V3D_TMU_FILTER_ANISOTROPIC_16_1 = 15, +}; + +enum V3D33_Varying_Flags_Action { + V3D_VARYING_FLAGS_ACTION_UNCHANGED = 0, + V3D_VARYING_FLAGS_ACTION_ZEROED = 1, + V3D_VARYING_FLAGS_ACTION_SET = 2, +}; + +enum V3D33_Memory_Format { + V3D_MEMORY_FORMAT_RASTER = 0, + V3D_MEMORY_FORMAT_LINEARTILE = 1, + V3D_MEMORY_FORMAT_UB_LINEAR_1_UIF_BLOCK_WIDE = 2, + V3D_MEMORY_FORMAT_UB_LINEAR_2_UIF_BLOCKS_WIDE = 3, + V3D_MEMORY_FORMAT_UIF_NO_XOR = 4, + V3D_MEMORY_FORMAT_UIF_XOR = 5, +}; + +enum V3D33_Decimate_Mode { + V3D_DECIMATE_MODE_SAMPLE_0 = 0, + V3D_DECIMATE_MODE_4X = 1, + V3D_DECIMATE_MODE_ALL_SAMPLES = 3, +}; + +enum V3D33_Internal_Type { + V3D_INTERNAL_TYPE_8I = 0, + V3D_INTERNAL_TYPE_8UI = 1, + V3D_INTERNAL_TYPE_8 = 2, + V3D_INTERNAL_TYPE_16I = 4, + V3D_INTERNAL_TYPE_16UI = 5, + V3D_INTERNAL_TYPE_16F = 6, + V3D_INTERNAL_TYPE_32I = 8, + V3D_INTERNAL_TYPE_32UI = 9, + V3D_INTERNAL_TYPE_32F = 10, +}; + +enum V3D33_Internal_BPP { + V3D_INTERNAL_BPP_32 = 0, + V3D_INTERNAL_BPP_64 = 1, + V3D_INTERNAL_BPP_128 = 2, +}; + +enum V3D33_Internal_Depth_Type { + V3D_INTERNAL_TYPE_DEPTH_32F = 0, + V3D_INTERNAL_TYPE_DEPTH_24 = 1, + V3D_INTERNAL_TYPE_DEPTH_16 = 2, +}; + +enum V3D33_Output_Image_Format { + V3D_OUTPUT_IMAGE_FORMAT_SRGB8_ALPHA8 = 0, + V3D_OUTPUT_IMAGE_FORMAT_SRGB = 1, + V3D_OUTPUT_IMAGE_FORMAT_RGB10_A2UI = 2, + V3D_OUTPUT_IMAGE_FORMAT_RGB10_A2 = 3, + V3D_OUTPUT_IMAGE_FORMAT_ABGR1555 = 4, + V3D_OUTPUT_IMAGE_FORMAT_ALPHA_MASKED_ABGR1555 = 5, + V3D_OUTPUT_IMAGE_FORMAT_ABGR4444 = 6, + V3D_OUTPUT_IMAGE_FORMAT_BGR565 = 7, + V3D_OUTPUT_IMAGE_FORMAT_R11F_G11F_B10F = 8, + V3D_OUTPUT_IMAGE_FORMAT_RGBA32F = 9, + V3D_OUTPUT_IMAGE_FORMAT_RG32F = 10, + V3D_OUTPUT_IMAGE_FORMAT_R32F = 11, + V3D_OUTPUT_IMAGE_FORMAT_RGBA32I = 12, + V3D_OUTPUT_IMAGE_FORMAT_RG32I = 13, + V3D_OUTPUT_IMAGE_FORMAT_R32I = 14, + V3D_OUTPUT_IMAGE_FORMAT_RGBA32UI = 15, + V3D_OUTPUT_IMAGE_FORMAT_RG32UI = 16, + V3D_OUTPUT_IMAGE_FORMAT_R32UI = 17, + V3D_OUTPUT_IMAGE_FORMAT_RGBA16F = 18, + V3D_OUTPUT_IMAGE_FORMAT_RG16F = 19, + V3D_OUTPUT_IMAGE_FORMAT_R16F = 20, + V3D_OUTPUT_IMAGE_FORMAT_RGBA16I = 21, + V3D_OUTPUT_IMAGE_FORMAT_RG16I = 22, + V3D_OUTPUT_IMAGE_FORMAT_R16I = 23, + V3D_OUTPUT_IMAGE_FORMAT_RGBA16UI = 24, + V3D_OUTPUT_IMAGE_FORMAT_RG16UI = 25, + V3D_OUTPUT_IMAGE_FORMAT_R16UI = 26, + V3D_OUTPUT_IMAGE_FORMAT_RGBA8 = 27, + V3D_OUTPUT_IMAGE_FORMAT_RGB8 = 28, + V3D_OUTPUT_IMAGE_FORMAT_RG8 = 29, + V3D_OUTPUT_IMAGE_FORMAT_R8 = 30, + V3D_OUTPUT_IMAGE_FORMAT_RGBA8I = 31, + V3D_OUTPUT_IMAGE_FORMAT_RG8I = 32, + V3D_OUTPUT_IMAGE_FORMAT_R8I = 33, + V3D_OUTPUT_IMAGE_FORMAT_RGBA8UI = 34, + V3D_OUTPUT_IMAGE_FORMAT_RG8UI = 35, + V3D_OUTPUT_IMAGE_FORMAT_R8UI = 36, + V3D_OUTPUT_IMAGE_FORMAT_SRGBX8 = 37, + V3D_OUTPUT_IMAGE_FORMAT_RGBX8 = 38, +}; + +enum V3D33_Z_S_Output_Image_Format { + V3D_OUTPUT_IMAGE_FORMAT_ZS_DEPTH_COMPONENT32F = 0, + V3D_OUTPUT_IMAGE_FORMAT_ZS_DEPTH_COMPONENT24 = 1, + V3D_OUTPUT_IMAGE_FORMAT_ZS_DEPTH_COMPONENT16 = 2, + V3D_OUTPUT_IMAGE_FORMAT_ZS_DEPTH24_STENCIL8 = 3, +}; + +enum V3D33_Dither_Mode { + V3D_DITHER_MODE_NONE = 0, + V3D_DITHER_MODE_RGB = 1, + V3D_DITHER_MODE_A = 2, + V3D_DITHER_MODE_RGBA = 3, +}; + #define V3D33_HALT_opcode 0 #define V3D33_HALT_header \ .opcode = 0 @@ -805,7 +925,7 @@ struct V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED { uint32_t disable_color_buffer_write; bool enable_z_write; bool enable_stencil_write; - bool disable_colour_buffers_clear_on_write; + bool disable_color_buffers_clear_on_write; bool disable_stencil_buffer_clear_on_write; bool disable_z_buffer_clear_on_write; bool disable_fast_opportunistic_write_out_in_multisample_mode; @@ -820,7 +940,7 @@ V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_pack(__gen_user_dat cl[ 1] = __gen_uint(values->enable_z_write, 7, 7) | __gen_uint(values->enable_stencil_write, 6, 6) | - __gen_uint(values->disable_colour_buffers_clear_on_write, 4, 4) | + __gen_uint(values->disable_color_buffers_clear_on_write, 4, 4) | __gen_uint(values->disable_stencil_buffer_clear_on_write, 3, 3) | __gen_uint(values->disable_z_buffer_clear_on_write, 2, 2) | __gen_uint(values->disable_fast_opportunistic_write_out_in_multisample_mode, 1, 1) | @@ -840,7 +960,7 @@ V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_unpack(const uint8_ values->disable_color_buffer_write = __gen_unpack_uint(cl, 16, 23); values->enable_z_write = __gen_unpack_uint(cl, 15, 15); values->enable_stencil_write = __gen_unpack_uint(cl, 14, 14); - values->disable_colour_buffers_clear_on_write = __gen_unpack_uint(cl, 12, 12); + values->disable_color_buffers_clear_on_write = __gen_unpack_uint(cl, 12, 12); values->disable_stencil_buffer_clear_on_write = __gen_unpack_uint(cl, 11, 11); values->disable_z_buffer_clear_on_write = __gen_unpack_uint(cl, 10, 10); values->disable_fast_opportunistic_write_out_in_multisample_mode = __gen_unpack_uint(cl, 9, 9); @@ -849,38 +969,38 @@ V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_unpack(const uint8_ #endif -#define V3D33_RELOAD_TILE_COLOUR_BUFFER_opcode 26 -#define V3D33_RELOAD_TILE_COLOUR_BUFFER_header \ +#define V3D33_RELOAD_TILE_COLOR_BUFFER_opcode 26 +#define V3D33_RELOAD_TILE_COLOR_BUFFER_header \ .opcode = 26 -struct V3D33_RELOAD_TILE_COLOUR_BUFFER { +struct V3D33_RELOAD_TILE_COLOR_BUFFER { uint32_t opcode; - uint32_t disable_colour_buffer_load; + uint32_t disable_color_buffer_load; bool enable_z_load; bool enable_stencil_load; }; static inline void -V3D33_RELOAD_TILE_COLOUR_BUFFER_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_RELOAD_TILE_COLOUR_BUFFER * restrict values) +V3D33_RELOAD_TILE_COLOR_BUFFER_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_RELOAD_TILE_COLOR_BUFFER * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); cl[ 1] = __gen_uint(values->enable_z_load, 7, 7) | __gen_uint(values->enable_stencil_load, 6, 6); - cl[ 2] = __gen_uint(values->disable_colour_buffer_load, 0, 7); + cl[ 2] = __gen_uint(values->disable_color_buffer_load, 0, 7); } -#define V3D33_RELOAD_TILE_COLOUR_BUFFER_length 3 +#define V3D33_RELOAD_TILE_COLOR_BUFFER_length 3 #ifdef __gen_unpack_address static inline void -V3D33_RELOAD_TILE_COLOUR_BUFFER_unpack(const uint8_t * restrict cl, - struct V3D33_RELOAD_TILE_COLOUR_BUFFER * restrict values) +V3D33_RELOAD_TILE_COLOR_BUFFER_unpack(const uint8_t * restrict cl, + struct V3D33_RELOAD_TILE_COLOR_BUFFER * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); - values->disable_colour_buffer_load = __gen_unpack_uint(cl, 16, 23); + values->disable_color_buffer_load = __gen_unpack_uint(cl, 16, 23); values->enable_z_load = __gen_unpack_uint(cl, 15, 15); values->enable_stencil_load = __gen_unpack_uint(cl, 14, 14); } @@ -924,7 +1044,7 @@ struct V3D33_STORE_TILE_BUFFER_GENERAL { uint32_t padded_height_of_output_image_in_uif_blocks; bool xor_uif; bool last_tile_of_frame; - bool disable_colour_buffers_clear_on_write; + bool disable_color_buffers_clear_on_write; bool disable_stencil_buffer_clear_on_write; bool disable_z_buffer_clear_on_write; bool raw_mode; @@ -945,7 +1065,7 @@ V3D33_STORE_TILE_BUFFER_GENERAL_pack(__gen_user_data *data, uint8_t * restrict c { cl[ 0] = __gen_uint(values->opcode, 0, 7); - cl[ 1] = __gen_uint(values->disable_colour_buffers_clear_on_write, 7, 7) | + cl[ 1] = __gen_uint(values->disable_color_buffers_clear_on_write, 7, 7) | __gen_uint(values->disable_stencil_buffer_clear_on_write, 6, 6) | __gen_uint(values->disable_z_buffer_clear_on_write, 5, 5) | __gen_uint(values->raw_mode, 4, 4) | @@ -955,10 +1075,9 @@ V3D33_STORE_TILE_BUFFER_GENERAL_pack(__gen_user_data *data, uint8_t * restrict c __gen_uint(values->xor_uif, 2, 2) | __gen_uint(values->last_tile_of_frame, 0, 0); - __gen_emit_reloc(data, &values->address); - cl[ 3] = __gen_address_offset(&values->address) | - __gen_uint(values->padded_height_of_output_image_in_uif_blocks, 3, 15) >> 8; + cl[ 3] = __gen_uint(values->padded_height_of_output_image_in_uif_blocks, 3, 15) >> 8; + __gen_emit_reloc(data, &values->address); cl[ 4] = __gen_address_offset(&values->address) >> 8; cl[ 5] = __gen_address_offset(&values->address) >> 16; @@ -974,11 +1093,11 @@ V3D33_STORE_TILE_BUFFER_GENERAL_unpack(const uint8_t * restrict cl, struct V3D33_STORE_TILE_BUFFER_GENERAL * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); - values->address = __gen_unpack_address(cl, 24, 55); + values->address = __gen_unpack_address(cl, 32, 55); values->padded_height_of_output_image_in_uif_blocks = __gen_unpack_uint(cl, 19, 31); values->xor_uif = __gen_unpack_uint(cl, 18, 18); values->last_tile_of_frame = __gen_unpack_uint(cl, 16, 16); - values->disable_colour_buffers_clear_on_write = __gen_unpack_uint(cl, 15, 15); + values->disable_color_buffers_clear_on_write = __gen_unpack_uint(cl, 15, 15); values->disable_stencil_buffer_clear_on_write = __gen_unpack_uint(cl, 14, 14); values->disable_z_buffer_clear_on_write = __gen_unpack_uint(cl, 13, 13); values->raw_mode = __gen_unpack_uint(cl, 12, 12); @@ -1023,11 +1142,11 @@ V3D33_LOAD_TILE_BUFFER_GENERAL_pack(__gen_user_data *data, uint8_t * restrict cl cl[ 3] = __gen_uint(values->padded_height_of_output_image_in_uif_blocks, 3, 15) >> 8; __gen_emit_reloc(data, &values->address); - cl[ 4] = __gen_address_offset(&values->address); + cl[ 4] = __gen_address_offset(&values->address) >> 8; - cl[ 5] = __gen_address_offset(&values->address) >> 8; + cl[ 5] = __gen_address_offset(&values->address) >> 16; - cl[ 6] = __gen_address_offset(&values->address) >> 16; + cl[ 6] = __gen_address_offset(&values->address) >> 24; } @@ -1047,11 +1166,38 @@ V3D33_LOAD_TILE_BUFFER_GENERAL_unpack(const uint8_t * restrict cl, #endif -#define V3D33_INDEXED_PRIMITIVE_LIST_opcode 32 -#define V3D33_INDEXED_PRIMITIVE_LIST_header \ +#define V3D33_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_opcode 31 +#define V3D33_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_header\ + .opcode = 31 + +struct V3D33_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT { + uint32_t opcode; +}; + +static inline void +V3D33_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D33_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_length 1 +#ifdef __gen_unpack_address +static inline void +V3D33_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_unpack(const uint8_t * restrict cl, + struct V3D33_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D33_INDEXED_PRIM_LIST_opcode 32 +#define V3D33_INDEXED_PRIM_LIST_header \ .opcode = 32 -struct V3D33_INDEXED_PRIMITIVE_LIST { +struct V3D33_INDEXED_PRIM_LIST { uint32_t opcode; uint32_t minimum_index; bool enable_primitive_restarts; @@ -1062,12 +1208,12 @@ struct V3D33_INDEXED_PRIMITIVE_LIST { #define INDEX_TYPE_8_BIT 0 #define INDEX_TYPE_16_BIT 1 #define INDEX_TYPE_32_BIT 2 - uint32_t mode; + enum V3D33_Primitive mode; }; static inline void -V3D33_INDEXED_PRIMITIVE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_INDEXED_PRIMITIVE_LIST * restrict values) +V3D33_INDEXED_PRIM_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_INDEXED_PRIM_LIST * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -1098,11 +1244,11 @@ V3D33_INDEXED_PRIMITIVE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, memcpy(&cl[14], &values->minimum_index, sizeof(values->minimum_index)); } -#define V3D33_INDEXED_PRIMITIVE_LIST_length 18 +#define V3D33_INDEXED_PRIM_LIST_length 18 #ifdef __gen_unpack_address static inline void -V3D33_INDEXED_PRIMITIVE_LIST_unpack(const uint8_t * restrict cl, - struct V3D33_INDEXED_PRIMITIVE_LIST * restrict values) +V3D33_INDEXED_PRIM_LIST_unpack(const uint8_t * restrict cl, + struct V3D33_INDEXED_PRIM_LIST * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->minimum_index = __gen_unpack_uint(cl, 112, 143); @@ -1116,11 +1262,11 @@ V3D33_INDEXED_PRIMITIVE_LIST_unpack(const uint8_t * restrict cl, #endif -#define V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_opcode 34 -#define V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_header\ +#define V3D33_INDEXED_INSTANCED_PRIM_LIST_opcode 34 +#define V3D33_INDEXED_INSTANCED_PRIM_LIST_header\ .opcode = 34 -struct V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST { +struct V3D33_INDEXED_INSTANCED_PRIM_LIST { uint32_t opcode; bool enable_primitive_restarts; uint32_t maximum_index; @@ -1135,8 +1281,8 @@ struct V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST { }; static inline void -V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST * restrict values) +V3D33_INDEXED_INSTANCED_PRIM_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_INDEXED_INSTANCED_PRIM_LIST * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -1167,11 +1313,11 @@ V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_pack(__gen_user_data *data, uint8_t * res } -#define V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_length 18 +#define V3D33_INDEXED_INSTANCED_PRIM_LIST_length 18 #ifdef __gen_unpack_address static inline void -V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_unpack(const uint8_t * restrict cl, - struct V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST * restrict values) +V3D33_INDEXED_INSTANCED_PRIM_LIST_unpack(const uint8_t * restrict cl, + struct V3D33_INDEXED_INSTANCED_PRIM_LIST * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->enable_primitive_restarts = __gen_unpack_uint(cl, 143, 143); @@ -1185,11 +1331,11 @@ V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_unpack(const uint8_t * restrict cl, #endif -#define V3D33_VERTEX_ARRAY_PRIMITIVES_opcode 36 -#define V3D33_VERTEX_ARRAY_PRIMITIVES_header \ +#define V3D33_VERTEX_ARRAY_PRIMS_opcode 36 +#define V3D33_VERTEX_ARRAY_PRIMS_header \ .opcode = 36 -struct V3D33_VERTEX_ARRAY_PRIMITIVES { +struct V3D33_VERTEX_ARRAY_PRIMS { uint32_t opcode; uint32_t index_of_first_vertex; uint32_t length; @@ -1197,8 +1343,8 @@ struct V3D33_VERTEX_ARRAY_PRIMITIVES { }; static inline void -V3D33_VERTEX_ARRAY_PRIMITIVES_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_VERTEX_ARRAY_PRIMITIVES * restrict values) +V3D33_VERTEX_ARRAY_PRIMS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_VERTEX_ARRAY_PRIMS * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -1210,11 +1356,11 @@ V3D33_VERTEX_ARRAY_PRIMITIVES_pack(__gen_user_data *data, uint8_t * restrict cl, memcpy(&cl[6], &values->index_of_first_vertex, sizeof(values->index_of_first_vertex)); } -#define V3D33_VERTEX_ARRAY_PRIMITIVES_length 10 +#define V3D33_VERTEX_ARRAY_PRIMS_length 10 #ifdef __gen_unpack_address static inline void -V3D33_VERTEX_ARRAY_PRIMITIVES_unpack(const uint8_t * restrict cl, - struct V3D33_VERTEX_ARRAY_PRIMITIVES * restrict values) +V3D33_VERTEX_ARRAY_PRIMS_unpack(const uint8_t * restrict cl, + struct V3D33_VERTEX_ARRAY_PRIMS * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->index_of_first_vertex = __gen_unpack_uint(cl, 48, 79); @@ -1224,11 +1370,11 @@ V3D33_VERTEX_ARRAY_PRIMITIVES_unpack(const uint8_t * restrict cl, #endif -#define V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_opcode 38 -#define V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_header\ +#define V3D33_VERTEX_ARRAY_INSTANCED_PRIMS_opcode 38 +#define V3D33_VERTEX_ARRAY_INSTANCED_PRIMS_header\ .opcode = 38 -struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES { +struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMS { uint32_t opcode; uint32_t index_of_first_vertex; uint32_t number_of_instances; @@ -1237,8 +1383,8 @@ struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES { }; static inline void -V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES * restrict values) +V3D33_VERTEX_ARRAY_INSTANCED_PRIMS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMS * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -1252,11 +1398,11 @@ V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_pack(__gen_user_data *data, uint8_t * re memcpy(&cl[10], &values->index_of_first_vertex, sizeof(values->index_of_first_vertex)); } -#define V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_length 14 +#define V3D33_VERTEX_ARRAY_INSTANCED_PRIMS_length 14 #ifdef __gen_unpack_address static inline void -V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_unpack(const uint8_t * restrict cl, - struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES * restrict values) +V3D33_VERTEX_ARRAY_INSTANCED_PRIMS_unpack(const uint8_t * restrict cl, + struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMS * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->index_of_first_vertex = __gen_unpack_uint(cl, 80, 111); @@ -1302,15 +1448,13 @@ V3D33_BASE_VERTEX_BASE_INSTANCE_unpack(const uint8_t * restrict cl, #endif -#define V3D33_PRIMITIVE_LIST_FORMAT_opcode 56 -#define V3D33_PRIMITIVE_LIST_FORMAT_header \ +#define V3D33_PRIM_LIST_FORMAT_opcode 56 +#define V3D33_PRIM_LIST_FORMAT_header \ .opcode = 56 -struct V3D33_PRIMITIVE_LIST_FORMAT { +struct V3D33_PRIM_LIST_FORMAT { uint32_t opcode; - uint32_t data_type; -#define LIST_INDEXED 0 -#define LIST_32_BIT_X_Y 1 + bool tri_strip_or_fan; uint32_t primitive_type; #define LIST_POINTS 0 #define LIST_LINES 1 @@ -1318,24 +1462,24 @@ struct V3D33_PRIMITIVE_LIST_FORMAT { }; static inline void -V3D33_PRIMITIVE_LIST_FORMAT_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_PRIMITIVE_LIST_FORMAT * restrict values) +V3D33_PRIM_LIST_FORMAT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_PRIM_LIST_FORMAT * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); - cl[ 1] = __gen_uint(values->data_type, 6, 6) | + cl[ 1] = __gen_uint(values->tri_strip_or_fan, 7, 7) | __gen_uint(values->primitive_type, 0, 5); } -#define V3D33_PRIMITIVE_LIST_FORMAT_length 2 +#define V3D33_PRIM_LIST_FORMAT_length 2 #ifdef __gen_unpack_address static inline void -V3D33_PRIMITIVE_LIST_FORMAT_unpack(const uint8_t * restrict cl, - struct V3D33_PRIMITIVE_LIST_FORMAT * restrict values) +V3D33_PRIM_LIST_FORMAT_unpack(const uint8_t * restrict cl, + struct V3D33_PRIM_LIST_FORMAT * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); - values->data_type = __gen_unpack_uint(cl, 14, 14); + values->tri_strip_or_fan = __gen_unpack_uint(cl, 15, 15); values->primitive_type = __gen_unpack_uint(cl, 8, 13); } #endif @@ -1382,6 +1526,40 @@ V3D33_GL_SHADER_STATE_unpack(const uint8_t * restrict cl, #endif +#define V3D33_VCM_CACHE_SIZE_opcode 73 +#define V3D33_VCM_CACHE_SIZE_header \ + .opcode = 73 + +struct V3D33_VCM_CACHE_SIZE { + uint32_t opcode; + uint32_t number_of_16_vertex_batches_for_rendering; + uint32_t number_of_16_vertex_batches_for_binning; +}; + +static inline void +V3D33_VCM_CACHE_SIZE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_VCM_CACHE_SIZE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->number_of_16_vertex_batches_for_rendering, 4, 7) | + __gen_uint(values->number_of_16_vertex_batches_for_binning, 0, 3); + +} + +#define V3D33_VCM_CACHE_SIZE_length 2 +#ifdef __gen_unpack_address +static inline void +V3D33_VCM_CACHE_SIZE_unpack(const uint8_t * restrict cl, + struct V3D33_VCM_CACHE_SIZE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->number_of_16_vertex_batches_for_rendering = __gen_unpack_uint(cl, 12, 15); + values->number_of_16_vertex_batches_for_binning = __gen_unpack_uint(cl, 8, 11); +} +#endif + + #define V3D33_TRANSFORM_FEEDBACK_ENABLE_opcode 74 #define V3D33_TRANSFORM_FEEDBACK_ENABLE_header \ .opcode = 74 @@ -1449,7 +1627,7 @@ V3D33_FLUSH_TRANSFORM_FEEDBACK_DATA_unpack(const uint8_t * restrict cl, struct V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC { uint32_t first_shaded_vertex_value_to_output; - uint32_t number_of_consecutive_vertex_values_to_output_as_32_bit_values_minus_1; + uint32_t number_of_consecutive_vertex_values_to_output_as_32_bit_values; uint32_t output_buffer_to_write_to; }; @@ -1457,9 +1635,10 @@ static inline void V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_pack(__gen_user_data *data, uint8_t * restrict cl, const struct V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC * restrict values) { + assert(values->number_of_consecutive_vertex_values_to_output_as_32_bit_values >= 1); cl[ 0] = __gen_uint(values->first_shaded_vertex_value_to_output, 0, 7); - cl[ 1] = __gen_uint(values->number_of_consecutive_vertex_values_to_output_as_32_bit_values_minus_1, 0, 3) | + cl[ 1] = __gen_uint(values->number_of_consecutive_vertex_values_to_output_as_32_bit_values - 1, 0, 3) | __gen_uint(values->output_buffer_to_write_to, 4, 5); } @@ -1471,7 +1650,7 @@ V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_unpack(const uint8_t * restrict cl, struct V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC * restrict values) { values->first_shaded_vertex_value_to_output = __gen_unpack_uint(cl, 0, 7); - values->number_of_consecutive_vertex_values_to_output_as_32_bit_values_minus_1 = __gen_unpack_uint(cl, 8, 11); + values->number_of_consecutive_vertex_values_to_output_as_32_bit_values = __gen_unpack_uint(cl, 8, 11) + 1; values->output_buffer_to_write_to = __gen_unpack_uint(cl, 12, 13); } #endif @@ -1510,11 +1689,11 @@ V3D33_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_unpack(const uint8_t * restrict cl, #endif -#define V3D33_STENCIL_CONFIG_opcode 80 -#define V3D33_STENCIL_CONFIG_header \ +#define V3D33_STENCIL_CFG_opcode 80 +#define V3D33_STENCIL_CFG_header \ .opcode = 80 -struct V3D33_STENCIL_CONFIG { +struct V3D33_STENCIL_CFG { uint32_t opcode; uint32_t stencil_write_mask; bool back_config; @@ -1528,8 +1707,8 @@ struct V3D33_STENCIL_CONFIG { }; static inline void -V3D33_STENCIL_CONFIG_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_STENCIL_CONFIG * restrict values) +V3D33_STENCIL_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_STENCIL_CFG * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -1550,11 +1729,11 @@ V3D33_STENCIL_CONFIG_pack(__gen_user_data *data, uint8_t * restrict cl, } -#define V3D33_STENCIL_CONFIG_length 6 +#define V3D33_STENCIL_CFG_length 6 #ifdef __gen_unpack_address static inline void -V3D33_STENCIL_CONFIG_unpack(const uint8_t * restrict cl, - struct V3D33_STENCIL_CONFIG * restrict values) +V3D33_STENCIL_CFG_unpack(const uint8_t * restrict cl, + struct V3D33_STENCIL_CFG * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->stencil_write_mask = __gen_unpack_uint(cl, 40, 47); @@ -1570,51 +1749,47 @@ V3D33_STENCIL_CONFIG_unpack(const uint8_t * restrict cl, #endif -#define V3D33_BLEND_CONFIG_opcode 84 -#define V3D33_BLEND_CONFIG_header \ +#define V3D33_BLEND_CFG_opcode 84 +#define V3D33_BLEND_CFG_header \ .opcode = 84 -struct V3D33_BLEND_CONFIG { +struct V3D33_BLEND_CFG { uint32_t opcode; - uint32_t vg_coverage_modes; - enum V3D33_Blend_Factor colour_blend_dst_factor; - enum V3D33_Blend_Factor colour_blend_src_factor; - enum V3D33_Blend_Mode colour_blend_mode; + enum V3D33_Blend_Factor color_blend_dst_factor; + enum V3D33_Blend_Factor color_blend_src_factor; + enum V3D33_Blend_Mode color_blend_mode; enum V3D33_Blend_Factor alpha_blend_dst_factor; enum V3D33_Blend_Factor alpha_blend_src_factor; enum V3D33_Blend_Mode alpha_blend_mode; }; static inline void -V3D33_BLEND_CONFIG_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_BLEND_CONFIG * restrict values) +V3D33_BLEND_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_BLEND_CFG * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); cl[ 1] = __gen_uint(values->alpha_blend_src_factor, 4, 7) | __gen_uint(values->alpha_blend_mode, 0, 3); - cl[ 2] = __gen_uint(values->colour_blend_mode, 4, 7) | + cl[ 2] = __gen_uint(values->color_blend_mode, 4, 7) | __gen_uint(values->alpha_blend_dst_factor, 0, 3); - cl[ 3] = __gen_uint(values->colour_blend_dst_factor, 4, 7) | - __gen_uint(values->colour_blend_src_factor, 0, 3); - - cl[ 4] = __gen_uint(values->vg_coverage_modes, 4, 5); + cl[ 3] = __gen_uint(values->color_blend_dst_factor, 4, 7) | + __gen_uint(values->color_blend_src_factor, 0, 3); } -#define V3D33_BLEND_CONFIG_length 5 +#define V3D33_BLEND_CFG_length 4 #ifdef __gen_unpack_address static inline void -V3D33_BLEND_CONFIG_unpack(const uint8_t * restrict cl, - struct V3D33_BLEND_CONFIG * restrict values) +V3D33_BLEND_CFG_unpack(const uint8_t * restrict cl, + struct V3D33_BLEND_CFG * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); - values->vg_coverage_modes = __gen_unpack_uint(cl, 36, 37); - values->colour_blend_dst_factor = __gen_unpack_uint(cl, 28, 31); - values->colour_blend_src_factor = __gen_unpack_uint(cl, 24, 27); - values->colour_blend_mode = __gen_unpack_uint(cl, 20, 23); + values->color_blend_dst_factor = __gen_unpack_uint(cl, 28, 31); + values->color_blend_src_factor = __gen_unpack_uint(cl, 24, 27); + values->color_blend_mode = __gen_unpack_uint(cl, 20, 23); values->alpha_blend_dst_factor = __gen_unpack_uint(cl, 16, 19); values->alpha_blend_src_factor = __gen_unpack_uint(cl, 12, 15); values->alpha_blend_mode = __gen_unpack_uint(cl, 8, 11); @@ -1622,11 +1797,11 @@ V3D33_BLEND_CONFIG_unpack(const uint8_t * restrict cl, #endif -#define V3D33_BLEND_CONSTANT_COLOUR_opcode 86 -#define V3D33_BLEND_CONSTANT_COLOUR_header \ +#define V3D33_BLEND_CONSTANT_COLOR_opcode 86 +#define V3D33_BLEND_CONSTANT_COLOR_header \ .opcode = 86 -struct V3D33_BLEND_CONSTANT_COLOUR { +struct V3D33_BLEND_CONSTANT_COLOR { uint32_t opcode; uint32_t alpha_f16; uint32_t blue_f16; @@ -1635,8 +1810,8 @@ struct V3D33_BLEND_CONSTANT_COLOUR { }; static inline void -V3D33_BLEND_CONSTANT_COLOUR_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_BLEND_CONSTANT_COLOUR * restrict values) +V3D33_BLEND_CONSTANT_COLOR_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_BLEND_CONSTANT_COLOR * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -1658,11 +1833,11 @@ V3D33_BLEND_CONSTANT_COLOUR_pack(__gen_user_data *data, uint8_t * restrict cl, } -#define V3D33_BLEND_CONSTANT_COLOUR_length 9 +#define V3D33_BLEND_CONSTANT_COLOR_length 9 #ifdef __gen_unpack_address static inline void -V3D33_BLEND_CONSTANT_COLOUR_unpack(const uint8_t * restrict cl, - struct V3D33_BLEND_CONSTANT_COLOUR * restrict values) +V3D33_BLEND_CONSTANT_COLOR_unpack(const uint8_t * restrict cl, + struct V3D33_BLEND_CONSTANT_COLOR * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->alpha_f16 = __gen_unpack_uint(cl, 56, 71); @@ -1673,58 +1848,80 @@ V3D33_BLEND_CONSTANT_COLOUR_unpack(const uint8_t * restrict cl, #endif -#define V3D33_COLOUR_WRITE_MASKS_opcode 87 -#define V3D33_COLOUR_WRITE_MASKS_header \ +#define V3D33_COLOR_WRITE_MASKS_opcode 87 +#define V3D33_COLOR_WRITE_MASKS_header \ .opcode = 87 -struct V3D33_COLOUR_WRITE_MASKS { +struct V3D33_COLOR_WRITE_MASKS { + uint32_t opcode; + uint32_t mask; +}; + +static inline void +V3D33_COLOR_WRITE_MASKS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_COLOR_WRITE_MASKS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->mask, sizeof(values->mask)); +} + +#define V3D33_COLOR_WRITE_MASKS_length 5 +#ifdef __gen_unpack_address +static inline void +V3D33_COLOR_WRITE_MASKS_unpack(const uint8_t * restrict cl, + struct V3D33_COLOR_WRITE_MASKS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->mask = __gen_unpack_uint(cl, 8, 39); +} +#endif + + +#define V3D33_OCCLUSION_QUERY_COUNTER_opcode 92 +#define V3D33_OCCLUSION_QUERY_COUNTER_header \ + .opcode = 92 + +struct V3D33_OCCLUSION_QUERY_COUNTER { uint32_t opcode; - uint32_t reserved; - uint32_t render_target_3_per_colour_component_write_masks; - uint32_t render_target_2_per_colour_component_write_masks; - uint32_t render_target_1_per_colour_component_write_masks; - uint32_t render_target_0_per_colour_component_write_masks; + __gen_address_type address; }; static inline void -V3D33_COLOUR_WRITE_MASKS_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_COLOUR_WRITE_MASKS * restrict values) +V3D33_OCCLUSION_QUERY_COUNTER_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_OCCLUSION_QUERY_COUNTER * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); - cl[ 1] = __gen_uint(values->render_target_1_per_colour_component_write_masks, 4, 7) | - __gen_uint(values->render_target_0_per_colour_component_write_masks, 0, 3); + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); - cl[ 2] = __gen_uint(values->render_target_3_per_colour_component_write_masks, 4, 7) | - __gen_uint(values->render_target_2_per_colour_component_write_masks, 0, 3); + cl[ 2] = __gen_address_offset(&values->address) >> 8; - cl[ 3] = __gen_uint(values->reserved, 0, 15); + cl[ 3] = __gen_address_offset(&values->address) >> 16; - cl[ 4] = __gen_uint(values->reserved, 0, 15) >> 8; + cl[ 4] = __gen_address_offset(&values->address) >> 24; } -#define V3D33_COLOUR_WRITE_MASKS_length 5 +#define V3D33_OCCLUSION_QUERY_COUNTER_length 5 #ifdef __gen_unpack_address static inline void -V3D33_COLOUR_WRITE_MASKS_unpack(const uint8_t * restrict cl, - struct V3D33_COLOUR_WRITE_MASKS * restrict values) +V3D33_OCCLUSION_QUERY_COUNTER_unpack(const uint8_t * restrict cl, + struct V3D33_OCCLUSION_QUERY_COUNTER * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); - values->reserved = __gen_unpack_uint(cl, 24, 39); - values->render_target_3_per_colour_component_write_masks = __gen_unpack_uint(cl, 20, 23); - values->render_target_2_per_colour_component_write_masks = __gen_unpack_uint(cl, 16, 19); - values->render_target_1_per_colour_component_write_masks = __gen_unpack_uint(cl, 12, 15); - values->render_target_0_per_colour_component_write_masks = __gen_unpack_uint(cl, 8, 11); + values->address = __gen_unpack_address(cl, 8, 39); } #endif -#define V3D33_CONFIGURATION_BITS_opcode 96 -#define V3D33_CONFIGURATION_BITS_header \ +#define V3D33_CFG_BITS_opcode 96 +#define V3D33_CFG_BITS_header \ .opcode = 96 -struct V3D33_CONFIGURATION_BITS { +struct V3D33_CFG_BITS { uint32_t opcode; bool direct3d_provoking_vertex; bool direct3d_point_fill_mode; @@ -1735,8 +1932,6 @@ struct V3D33_CONFIGURATION_BITS { bool z_updates_enable; enum V3D33_Compare_Function depth_test_function; bool direct3d_wireframe_triangles_mode; - uint32_t coverage_update_mode; - bool coverage_pipe_select; uint32_t rasterizer_oversample_mode; uint32_t line_rasterization; bool enable_depth_offset; @@ -1746,8 +1941,8 @@ struct V3D33_CONFIGURATION_BITS { }; static inline void -V3D33_CONFIGURATION_BITS_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_CONFIGURATION_BITS * restrict values) +V3D33_CFG_BITS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_CFG_BITS * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -1760,9 +1955,7 @@ V3D33_CONFIGURATION_BITS_pack(__gen_user_data *data, uint8_t * restrict cl, cl[ 2] = __gen_uint(values->z_updates_enable, 7, 7) | __gen_uint(values->depth_test_function, 4, 6) | - __gen_uint(values->direct3d_wireframe_triangles_mode, 3, 3) | - __gen_uint(values->coverage_update_mode, 1, 2) | - __gen_uint(values->coverage_pipe_select, 0, 0); + __gen_uint(values->direct3d_wireframe_triangles_mode, 3, 3); cl[ 3] = __gen_uint(values->direct3d_provoking_vertex, 5, 5) | __gen_uint(values->direct3d_point_fill_mode, 4, 4) | @@ -1773,11 +1966,11 @@ V3D33_CONFIGURATION_BITS_pack(__gen_user_data *data, uint8_t * restrict cl, } -#define V3D33_CONFIGURATION_BITS_length 4 +#define V3D33_CFG_BITS_length 4 #ifdef __gen_unpack_address static inline void -V3D33_CONFIGURATION_BITS_unpack(const uint8_t * restrict cl, - struct V3D33_CONFIGURATION_BITS * restrict values) +V3D33_CFG_BITS_unpack(const uint8_t * restrict cl, + struct V3D33_CFG_BITS * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->direct3d_provoking_vertex = __gen_unpack_uint(cl, 29, 29); @@ -1789,8 +1982,6 @@ V3D33_CONFIGURATION_BITS_unpack(const uint8_t * restrict cl, values->z_updates_enable = __gen_unpack_uint(cl, 23, 23); values->depth_test_function = __gen_unpack_uint(cl, 20, 22); values->direct3d_wireframe_triangles_mode = __gen_unpack_uint(cl, 19, 19); - values->coverage_update_mode = __gen_unpack_uint(cl, 17, 18); - values->coverage_pipe_select = __gen_unpack_uint(cl, 16, 16); values->rasterizer_oversample_mode = __gen_unpack_uint(cl, 14, 15); values->line_rasterization = __gen_unpack_uint(cl, 12, 13); values->enable_depth_offset = __gen_unpack_uint(cl, 11, 11); @@ -1835,8 +2026,8 @@ V3D33_ZERO_ALL_FLAT_SHADE_FLAGS_unpack(const uint8_t * restrict cl, struct V3D33_FLAT_SHADE_FLAGS { uint32_t opcode; uint32_t flat_shade_flags_for_varyings_v024; - uint32_t action_for_flat_shade_flags_of_higher_numbered_varyings; - uint32_t action_for_flat_shade_flags_of_lower_numbered_varyings; + enum V3D33_Varying_Flags_Action action_for_flat_shade_flags_of_higher_numbered_varyings; + enum V3D33_Varying_Flags_Action action_for_flat_shade_flags_of_lower_numbered_varyings; uint32_t varying_offset_v0; }; @@ -1941,8 +2132,8 @@ V3D33_LINE_WIDTH_unpack(const uint8_t * restrict cl, struct V3D33_DEPTH_OFFSET { uint32_t opcode; - uint32_t depth_offset_units; - uint32_t depth_offset_factor; + float depth_offset_units; + float depth_offset_factor; }; static inline void @@ -1951,13 +2142,13 @@ V3D33_DEPTH_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl, { cl[ 0] = __gen_uint(values->opcode, 0, 7); - cl[ 1] = __gen_uint(values->depth_offset_factor, 0, 15); + cl[ 1] = __gen_uint(fui(values->depth_offset_factor) >> 16, 0, 15); - cl[ 2] = __gen_uint(values->depth_offset_factor, 0, 15) >> 8; + cl[ 2] = __gen_uint(fui(values->depth_offset_factor) >> 16, 0, 15) >> 8; - cl[ 3] = __gen_uint(values->depth_offset_units, 0, 15); + cl[ 3] = __gen_uint(fui(values->depth_offset_units) >> 16, 0, 15); - cl[ 4] = __gen_uint(values->depth_offset_units, 0, 15) >> 8; + cl[ 4] = __gen_uint(fui(values->depth_offset_units) >> 16, 0, 15) >> 8; } @@ -1968,8 +2159,8 @@ V3D33_DEPTH_OFFSET_unpack(const uint8_t * restrict cl, struct V3D33_DEPTH_OFFSET * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); - values->depth_offset_units = __gen_unpack_uint(cl, 24, 39); - values->depth_offset_factor = __gen_unpack_uint(cl, 8, 23); + values->depth_offset_units = __gen_unpack_f187(cl, 24, 39); + values->depth_offset_factor = __gen_unpack_f187(cl, 8, 23); } #endif @@ -2177,20 +2368,17 @@ V3D33_CLIPPER_Z_SCALE_AND_OFFSET_unpack(const uint8_t * restrict cl, #endif -#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_opcode 120 -#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_header\ +#define V3D33_TILE_BINNING_MODE_CFG_PART1_opcode 120 +#define V3D33_TILE_BINNING_MODE_CFG_PART1_header\ .opcode = 120, \ .auto_initialize_tile_state_data_array = 1, \ .sub_id = 0 -struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1 { +struct V3D33_TILE_BINNING_MODE_CFG_PART1 { uint32_t opcode; bool double_buffer_in_non_ms_mode; bool multisample_mode_4x; - uint32_t maximum_bpp_of_all_render_targets; -#define RENDER_TARGET_MAXIMUM_32BPP 0 -#define RENDER_TARGET_MAXIMUM_64BPP 1 -#define RENDER_TARGET_MAXIMUM_128BPP 2 + enum V3D33_Internal_BPP maximum_bpp_of_all_render_targets; uint32_t number_of_render_targets; uint32_t height_in_tiles; uint32_t width_in_tiles; @@ -2208,8 +2396,8 @@ struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1 { }; static inline void -V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1 * restrict values) +V3D33_TILE_BINNING_MODE_CFG_PART1_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TILE_BINNING_MODE_CFG_PART1 * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -2240,11 +2428,11 @@ V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_pack(__gen_user_data *data, uint8_t } -#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_length 9 +#define V3D33_TILE_BINNING_MODE_CFG_PART1_length 9 #ifdef __gen_unpack_address static inline void -V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_unpack(const uint8_t * restrict cl, - struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1 * restrict values) +V3D33_TILE_BINNING_MODE_CFG_PART1_unpack(const uint8_t * restrict cl, + struct V3D33_TILE_BINNING_MODE_CFG_PART1 * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->double_buffer_in_non_ms_mode = __gen_unpack_uint(cl, 71, 71); @@ -2253,7 +2441,7 @@ V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_unpack(const uint8_t * restrict cl, values->number_of_render_targets = __gen_unpack_uint(cl, 64, 67); values->height_in_tiles = __gen_unpack_uint(cl, 52, 63); values->width_in_tiles = __gen_unpack_uint(cl, 40, 51); - values->tile_state_data_array_base_address = __gen_unpack_address(cl, 8, 39); + values->tile_state_data_array_base_address = __gen_unpack_address(cl, 14, 39); values->tile_allocation_block_size = __gen_unpack_uint(cl, 12, 13); values->tile_allocation_initial_block_size = __gen_unpack_uint(cl, 10, 11); values->auto_initialize_tile_state_data_array = __gen_unpack_uint(cl, 9, 9); @@ -2262,12 +2450,12 @@ V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_unpack(const uint8_t * restrict cl, #endif -#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_opcode 120 -#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_header\ +#define V3D33_TILE_BINNING_MODE_CFG_PART2_opcode 120 +#define V3D33_TILE_BINNING_MODE_CFG_PART2_header\ .opcode = 120, \ .sub_id = 1 -struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2 { +struct V3D33_TILE_BINNING_MODE_CFG_PART2 { uint32_t opcode; __gen_address_type tile_allocation_memory_address; uint32_t tile_allocation_memory_size; @@ -2275,8 +2463,8 @@ struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2 { }; static inline void -V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2 * restrict values) +V3D33_TILE_BINNING_MODE_CFG_PART2_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TILE_BINNING_MODE_CFG_PART2 * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -2300,11 +2488,11 @@ V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_pack(__gen_user_data *data, uint8_t } -#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_length 9 +#define V3D33_TILE_BINNING_MODE_CFG_PART2_length 9 #ifdef __gen_unpack_address static inline void -V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_unpack(const uint8_t * restrict cl, - struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2 * restrict values) +V3D33_TILE_BINNING_MODE_CFG_PART2_unpack(const uint8_t * restrict cl, + struct V3D33_TILE_BINNING_MODE_CFG_PART2 * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->tile_allocation_memory_address = __gen_unpack_address(cl, 40, 71); @@ -2314,12 +2502,12 @@ V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_unpack(const uint8_t * restrict cl, #endif -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_opcode 121 -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_header\ +#define V3D33_TILE_RENDERING_MODE_CFG_COMMON_opcode 121 +#define V3D33_TILE_RENDERING_MODE_CFG_COMMON_header\ .opcode = 121, \ .sub_id = 0 -struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION { +struct V3D33_TILE_RENDERING_MODE_CFG_COMMON { uint32_t opcode; uint32_t disable_render_target_stores; bool enable_z_store; @@ -2328,7 +2516,6 @@ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION { uint32_t early_z_test_and_update_direction; #define EARLY_Z_DIRECTION_LT_LE 0 #define EARLY_Z_DIRECTION_GT_GE 1 - bool select_coverage_mode; bool double_buffer_in_non_ms_mode; bool multisample_mode_4x; uint32_t maximum_bpp_of_all_render_targets; @@ -2337,17 +2524,18 @@ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION { #define RENDER_TARGET_MAXIMUM_128BPP 2 uint32_t image_height_pixels; uint32_t image_width_pixels; - uint32_t number_of_render_targets_minus_1; + uint32_t number_of_render_targets; uint32_t sub_id; }; static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_COMMON_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TILE_RENDERING_MODE_CFG_COMMON * restrict values) { + assert(values->number_of_render_targets >= 1); cl[ 0] = __gen_uint(values->opcode, 0, 7); - cl[ 1] = __gen_uint(values->number_of_render_targets_minus_1, 4, 7) | + cl[ 1] = __gen_uint(values->number_of_render_targets - 1, 4, 7) | __gen_uint(values->sub_id, 0, 3); cl[ 2] = __gen_uint(values->image_width_pixels, 0, 15); @@ -2360,7 +2548,6 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_pack(__gen_user_dat cl[ 6] = __gen_uint(values->early_z_disable, 6, 6) | __gen_uint(values->early_z_test_and_update_direction, 5, 5) | - __gen_uint(values->select_coverage_mode, 4, 4) | __gen_uint(values->double_buffer_in_non_ms_mode, 3, 3) | __gen_uint(values->multisample_mode_4x, 2, 2) | __gen_uint(values->maximum_bpp_of_all_render_targets, 0, 1); @@ -2372,11 +2559,11 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_pack(__gen_user_dat } -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_length 9 +#define V3D33_TILE_RENDERING_MODE_CFG_COMMON_length 9 #ifdef __gen_unpack_address static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_unpack(const uint8_t * restrict cl, - struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_COMMON_unpack(const uint8_t * restrict cl, + struct V3D33_TILE_RENDERING_MODE_CFG_COMMON * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->disable_render_target_stores = __gen_unpack_uint(cl, 64, 71); @@ -2384,99 +2571,40 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_unpack(const uint8_ values->enable_stencil_store = __gen_unpack_uint(cl, 62, 62); values->early_z_disable = __gen_unpack_uint(cl, 54, 54); values->early_z_test_and_update_direction = __gen_unpack_uint(cl, 53, 53); - values->select_coverage_mode = __gen_unpack_uint(cl, 52, 52); values->double_buffer_in_non_ms_mode = __gen_unpack_uint(cl, 51, 51); values->multisample_mode_4x = __gen_unpack_uint(cl, 50, 50); values->maximum_bpp_of_all_render_targets = __gen_unpack_uint(cl, 48, 49); values->image_height_pixels = __gen_unpack_uint(cl, 32, 47); values->image_width_pixels = __gen_unpack_uint(cl, 16, 31); - values->number_of_render_targets_minus_1 = __gen_unpack_uint(cl, 12, 15); + values->number_of_render_targets = __gen_unpack_uint(cl, 12, 15) + 1; values->sub_id = __gen_unpack_uint(cl, 8, 11); } #endif -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_opcode 121 -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_header\ +#define V3D33_TILE_RENDERING_MODE_CFG_COLOR_opcode 121 +#define V3D33_TILE_RENDERING_MODE_CFG_COLOR_header\ .opcode = 121, \ .sub_id = 2 -struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG { +struct V3D33_TILE_RENDERING_MODE_CFG_COLOR { uint32_t opcode; __gen_address_type address; uint32_t pad; bool flip_y; - uint32_t memory_format; -#define MEMORY_FORMAT_RASTER 0 -#define MEMORY_FORMAT_LINEARTILE 1 -#define MEMORY_FORMAT_UB_LINEAR_1_UIF_BLOCK_WIDE 2 -#define MEMORY_FORMAT_UB_LINEAR_2_UIF_BLOCKS_WIDE 3 -#define MEMORY_FORMAT_UIF_NO_XOR 4 -#define MEMORY_FORMAT_UIF_XOR 5 - bool a_dithered; - bool bgr_dithered; - uint32_t output_image_format; -#define OUTPUT_IMAGE_FORMAT_SRGB8_ALPHA8 0 -#define OUTPUT_IMAGE_FORMAT_SRGB 1 -#define OUTPUT_IMAGE_FORMAT_RGB10_A2UI 2 -#define OUTPUT_IMAGE_FORMAT_RGB10_A2 3 -#define OUTPUT_IMAGE_FORMAT_ABGR1555 4 -#define OUTPUT_IMAGE_FORMAT_ALPHA_MASKED_ABGR1555 5 -#define OUTPUT_IMAGE_FORMAT_ABGR4444 6 -#define OUTPUT_IMAGE_FORMAT_BGR565 7 -#define OUTPUT_IMAGE_FORMAT_R11F_G11F_B10F 8 -#define OUTPUT_IMAGE_FORMAT_RGBA32F 9 -#define OUTPUT_IMAGE_FORMAT_RG32F 10 -#define OUTPUT_IMAGE_FORMAT_R32F 11 -#define OUTPUT_IMAGE_FORMAT_RGBA32I 12 -#define OUTPUT_IMAGE_FORMAT_RG32I 13 -#define OUTPUT_IMAGE_FORMAT_R32I 14 -#define OUTPUT_IMAGE_FORMAT_RGBA32UI 15 -#define OUTPUT_IMAGE_FORMAT_RG32UI 16 -#define OUTPUT_IMAGE_FORMAT_R32UI 17 -#define OUTPUT_IMAGE_FORMAT_RGBA16F 18 -#define OUTPUT_IMAGE_FORMAT_RG16F 19 -#define OUTPUT_IMAGE_FORMAT_R16F 20 -#define OUTPUT_IMAGE_FORMAT_RGBA16I 21 -#define OUTPUT_IMAGE_FORMAT_RG16I 22 -#define OUTPUT_IMAGE_FORMAT_R16I 23 -#define OUTPUT_IMAGE_FORMAT_RGBA16UI 24 -#define OUTPUT_IMAGE_FORMAT_RG16UI 25 -#define OUTPUT_IMAGE_FORMAT_R16UI 26 -#define OUTPUT_IMAGE_FORMAT_RGBA8 27 -#define OUTPUT_IMAGE_FORMAT_RGB8 28 -#define OUTPUT_IMAGE_FORMAT_RG8 29 -#define OUTPUT_IMAGE_FORMAT_R8 30 -#define OUTPUT_IMAGE_FORMAT_RGBA8I 31 -#define OUTPUT_IMAGE_FORMAT_RG8I 32 -#define OUTPUT_IMAGE_FORMAT_R8I 33 -#define OUTPUT_IMAGE_FORMAT_RGBA8UI 34 -#define OUTPUT_IMAGE_FORMAT_RG8UI 35 -#define OUTPUT_IMAGE_FORMAT_R8UI 36 -#define OUTPUT_IMAGE_FORMAT_SRGBX8 37 -#define OUTPUT_IMAGE_FORMAT_RGBX8 38 - uint32_t decimate_mode; - uint32_t internal_type; -#define INTERNAL_TYPE_8I 0 -#define INTERNAL_TYPE_8UI 1 -#define INTERNAL_TYPE_8 2 -#define INTERNAL_TYPE_16I 4 -#define INTERNAL_TYPE_16UI 5 -#define INTERNAL_TYPE_16F 6 -#define INTERNAL_TYPE_32I 8 -#define INTERNAL_TYPE_32UI 9 -#define INTERNAL_TYPE_32F 10 - uint32_t internal_bpp; -#define INTERNAL_BPP_32 0 -#define INTERNAL_BPP_64 1 -#define INTERNAL_BPP_128 2 + enum V3D33_Memory_Format memory_format; + enum V3D33_Dither_Mode dither_mode; + enum V3D33_Output_Image_Format output_image_format; + enum V3D33_Decimate_Mode decimate_mode; + enum V3D33_Internal_Type internal_type; + enum V3D33_Internal_BPP internal_bpp; uint32_t render_target_number; uint32_t sub_id; }; static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_COLOR_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TILE_RENDERING_MODE_CFG_COLOR * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -2487,8 +2615,7 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_pack(__gen_user_dat __gen_uint(values->internal_type, 2, 5) | __gen_uint(values->internal_bpp, 0, 1); - cl[ 3] = __gen_uint(values->a_dithered, 7, 7) | - __gen_uint(values->bgr_dithered, 6, 6) | + cl[ 3] = __gen_uint(values->dither_mode, 6, 7) | __gen_uint(values->output_image_format, 0, 5); cl[ 4] = __gen_uint(values->pad, 4, 7) | @@ -2506,19 +2633,18 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_pack(__gen_user_dat } -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_length 9 +#define V3D33_TILE_RENDERING_MODE_CFG_COLOR_length 9 #ifdef __gen_unpack_address static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_unpack(const uint8_t * restrict cl, - struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_COLOR_unpack(const uint8_t * restrict cl, + struct V3D33_TILE_RENDERING_MODE_CFG_COLOR * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->address = __gen_unpack_address(cl, 40, 71); values->pad = __gen_unpack_uint(cl, 36, 39); values->flip_y = __gen_unpack_uint(cl, 35, 35); values->memory_format = __gen_unpack_uint(cl, 32, 34); - values->a_dithered = __gen_unpack_uint(cl, 31, 31); - values->bgr_dithered = __gen_unpack_uint(cl, 30, 30); + values->dither_mode = __gen_unpack_uint(cl, 30, 31); values->output_image_format = __gen_unpack_uint(cl, 24, 29); values->decimate_mode = __gen_unpack_uint(cl, 22, 23); values->internal_type = __gen_unpack_uint(cl, 18, 21); @@ -2529,41 +2655,28 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_unpack(const uint8_ #endif -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_opcode 121 -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_header\ +#define V3D33_TILE_RENDERING_MODE_CFG_Z_STENCIL_opcode 121 +#define V3D33_TILE_RENDERING_MODE_CFG_Z_STENCIL_header\ .opcode = 121, \ .z_stencil_id = 0, \ .sub_id = 1 -struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG { +struct V3D33_TILE_RENDERING_MODE_CFG_Z_STENCIL { uint32_t opcode; __gen_address_type address; uint32_t padded_height_of_output_image_in_uif_blocks; - uint32_t memory_format; -#define MEMORY_FORMAT_RASTER 0 -#define MEMORY_FORMAT_LINEARTILE 1 -#define MEMORY_FORMAT_UB_LINEAR_1_UIF_BLOCK_WIDE 2 -#define MEMORY_FORMAT_UB_LINEAR_2_UIF_BLOCKS_WIDE 3 -#define MEMORY_FORMAT_UIF_NO_XOR 4 -#define MEMORY_FORMAT_UIF_XOR 5 - uint32_t output_image_format; -#define OUTPUT_IMAGE_FORMAT_DEPTH_COMPONENT32F 0 -#define OUTPUT_IMAGE_FORMAT_DEPTH_COMPONENT24 1 -#define OUTPUT_IMAGE_FORMAT_DEPTH_COMPONENT16 2 -#define OUTPUT_IMAGE_FORMAT_DEPTH24_STENCIL8 3 + enum V3D33_Memory_Format memory_format; + enum V3D33_Z_S_Output_Image_Format output_image_format; uint32_t decimate_mode; - uint32_t internal_type; -#define INTERNAL_TYPE_DEPTH_32F 0 -#define INTERNAL_TYPE_DEPTH_24 1 -#define INTERNAL_TYPE_DEPTH_16 2 + enum V3D33_Internal_Depth_Type internal_type; uint32_t internal_bpp_ignored; uint32_t z_stencil_id; uint32_t sub_id; }; static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_Z_STENCIL_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TILE_RENDERING_MODE_CFG_Z_STENCIL * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -2592,14 +2705,14 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_pack(__gen_user_data *d } -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_length 9 +#define V3D33_TILE_RENDERING_MODE_CFG_Z_STENCIL_length 9 #ifdef __gen_unpack_address static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_unpack(const uint8_t * restrict cl, - struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_Z_STENCIL_unpack(const uint8_t * restrict cl, + struct V3D33_TILE_RENDERING_MODE_CFG_Z_STENCIL * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); - values->address = __gen_unpack_address(cl, 40, 71); + values->address = __gen_unpack_address(cl, 46, 71); values->padded_height_of_output_image_in_uif_blocks = __gen_unpack_uint(cl, 33, 45); values->memory_format = __gen_unpack_uint(cl, 30, 32); values->output_image_format = __gen_unpack_uint(cl, 24, 29); @@ -2612,28 +2725,28 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_unpack(const uint8_t * #endif -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_opcode 121 -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_header\ +#define V3D33_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_opcode 121 +#define V3D33_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_header\ .opcode = 121, \ .sub_id = 3 -struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES { +struct V3D33_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES { uint32_t opcode; uint32_t unused; float z_clear_value; - uint32_t stencil_vg_mask_clear_value; + uint32_t stencil_clear_value; uint32_t sub_id; }; static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); cl[ 1] = __gen_uint(values->sub_id, 0, 3); - cl[ 2] = __gen_uint(values->stencil_vg_mask_clear_value, 0, 7); + cl[ 2] = __gen_uint(values->stencil_clear_value, 0, 7); memcpy(&cl[3], &values->z_clear_value, sizeof(values->z_clear_value)); @@ -2643,27 +2756,27 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_pack(__gen_user_d } -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_length 9 +#define V3D33_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_length 9 #ifdef __gen_unpack_address static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_unpack(const uint8_t * restrict cl, - struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_unpack(const uint8_t * restrict cl, + struct V3D33_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->unused = __gen_unpack_uint(cl, 56, 71); values->z_clear_value = __gen_unpack_float(cl, 24, 55); - values->stencil_vg_mask_clear_value = __gen_unpack_uint(cl, 16, 23); + values->stencil_clear_value = __gen_unpack_uint(cl, 16, 23); values->sub_id = __gen_unpack_uint(cl, 8, 11); } #endif -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_opcode 121 -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_header\ +#define V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_opcode 121 +#define V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_header\ .opcode = 121, \ .sub_id = 4 -struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1 { +struct V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1 { uint32_t opcode; uint32_t clear_color_next_24_bits; uint32_t clear_color_low_32_bits; @@ -2672,8 +2785,8 @@ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1 { }; static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1 * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1 * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -2690,11 +2803,11 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_pack(__gen_user_data } -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_length 9 +#define V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_length 9 #ifdef __gen_unpack_address static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_unpack(const uint8_t * restrict cl, - struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1 * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_unpack(const uint8_t * restrict cl, + struct V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1 * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->clear_color_next_24_bits = __gen_unpack_uint(cl, 48, 71); @@ -2705,12 +2818,12 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_unpack(const uint8_t #endif -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_opcode 121 -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_header\ +#define V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_opcode 121 +#define V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_header\ .opcode = 121, \ .sub_id = 5 -struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2 { +struct V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2 { uint32_t opcode; uint32_t clear_color_mid_high_24_bits; uint32_t clear_color_mid_low_32_bits; @@ -2719,8 +2832,8 @@ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2 { }; static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2 * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2 * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -2737,11 +2850,11 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_pack(__gen_user_data } -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_length 9 +#define V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_length 9 #ifdef __gen_unpack_address static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_unpack(const uint8_t * restrict cl, - struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2 * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_unpack(const uint8_t * restrict cl, + struct V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2 * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->clear_color_mid_high_24_bits = __gen_unpack_uint(cl, 48, 71); @@ -2752,12 +2865,12 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_unpack(const uint8_t #endif -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_opcode 121 -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_header\ +#define V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_opcode 121 +#define V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_header\ .opcode = 121, \ .sub_id = 6 -struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3 { +struct V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3 { uint32_t opcode; uint32_t pad; uint32_t uif_padded_height_in_uif_blocks; @@ -2768,8 +2881,8 @@ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3 { }; static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3 * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3 * restrict values) { cl[ 0] = __gen_uint(values->opcode, 0, 7); @@ -2793,11 +2906,11 @@ V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_pack(__gen_user_data } -#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_length 9 +#define V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_length 9 #ifdef __gen_unpack_address static inline void -V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_unpack(const uint8_t * restrict cl, - struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3 * restrict values) +V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_unpack(const uint8_t * restrict cl, + struct V3D33_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3 * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); values->pad = __gen_unpack_uint(cl, 61, 71); @@ -2848,31 +2961,35 @@ V3D33_TILE_COORDINATES_unpack(const uint8_t * restrict cl, #endif -#define V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_opcode 122 -#define V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_header\ +#define V3D33_MULTICORE_RENDERING_SUPERTILE_CFG_opcode 122 +#define V3D33_MULTICORE_RENDERING_SUPERTILE_CFG_header\ .opcode = 122 -struct V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION { +struct V3D33_MULTICORE_RENDERING_SUPERTILE_CFG { uint32_t opcode; + uint32_t number_of_bin_tile_lists; bool supertile_raster_order; bool multicore_enable; uint32_t total_frame_height_in_tiles; uint32_t total_frame_width_in_tiles; uint32_t total_frame_height_in_supertiles; uint32_t total_frame_width_in_supertiles; - uint32_t supertile_height_in_tiles_minus_1; - uint32_t supertile_width_in_tiles_minus_1; + uint32_t supertile_height_in_tiles; + uint32_t supertile_width_in_tiles; }; static inline void -V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_pack(__gen_user_data *data, uint8_t * restrict cl, - const struct V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION * restrict values) +V3D33_MULTICORE_RENDERING_SUPERTILE_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D33_MULTICORE_RENDERING_SUPERTILE_CFG * restrict values) { + assert(values->number_of_bin_tile_lists >= 1); + assert(values->supertile_height_in_tiles >= 1); + assert(values->supertile_width_in_tiles >= 1); cl[ 0] = __gen_uint(values->opcode, 0, 7); - cl[ 1] = __gen_uint(values->supertile_width_in_tiles_minus_1, 0, 7); + cl[ 1] = __gen_uint(values->supertile_width_in_tiles - 1, 0, 7); - cl[ 2] = __gen_uint(values->supertile_height_in_tiles_minus_1, 0, 7); + cl[ 2] = __gen_uint(values->supertile_height_in_tiles - 1, 0, 7); cl[ 3] = __gen_uint(values->total_frame_width_in_supertiles, 0, 7); @@ -2885,26 +3002,28 @@ V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_pack(__gen_user_data *data, ui cl[ 7] = __gen_uint(values->total_frame_height_in_tiles, 4, 15) >> 8; - cl[ 8] = __gen_uint(values->supertile_raster_order, 4, 4) | + cl[ 8] = __gen_uint(values->number_of_bin_tile_lists - 1, 5, 7) | + __gen_uint(values->supertile_raster_order, 4, 4) | __gen_uint(values->multicore_enable, 0, 0); } -#define V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_length 9 +#define V3D33_MULTICORE_RENDERING_SUPERTILE_CFG_length 9 #ifdef __gen_unpack_address static inline void -V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_unpack(const uint8_t * restrict cl, - struct V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION * restrict values) +V3D33_MULTICORE_RENDERING_SUPERTILE_CFG_unpack(const uint8_t * restrict cl, + struct V3D33_MULTICORE_RENDERING_SUPERTILE_CFG * restrict values) { values->opcode = __gen_unpack_uint(cl, 0, 7); + values->number_of_bin_tile_lists = __gen_unpack_uint(cl, 69, 71) + 1; values->supertile_raster_order = __gen_unpack_uint(cl, 68, 68); values->multicore_enable = __gen_unpack_uint(cl, 64, 64); values->total_frame_height_in_tiles = __gen_unpack_uint(cl, 52, 63); values->total_frame_width_in_tiles = __gen_unpack_uint(cl, 40, 51); values->total_frame_height_in_supertiles = __gen_unpack_uint(cl, 32, 39); values->total_frame_width_in_supertiles = __gen_unpack_uint(cl, 24, 31); - values->supertile_height_in_tiles_minus_1 = __gen_unpack_uint(cl, 16, 23); - values->supertile_width_in_tiles_minus_1 = __gen_unpack_uint(cl, 8, 15); + values->supertile_height_in_tiles = __gen_unpack_uint(cl, 16, 23) + 1; + values->supertile_width_in_tiles = __gen_unpack_uint(cl, 8, 15) + 1; } #endif @@ -3036,13 +3155,19 @@ struct V3D33_GL_SHADER_STATE_RECORD { uint32_t vertex_shader_input_vpm_segment_size; __gen_address_type address_of_default_attribute_values; __gen_address_type fragment_shader_code_address; - bool _2_way_threadable; - bool _4_way_threadable; - bool propagate_nans; + bool fragment_shader_2_way_threadable; + bool fragment_shader_4_way_threadable; + bool fragment_shader_propagate_nans; __gen_address_type fragment_shader_uniforms_address; __gen_address_type vertex_shader_code_address; + bool vertex_shader_2_way_threadable; + bool vertex_shader_4_way_threadable; + bool vertex_shader_propagate_nans; __gen_address_type vertex_shader_uniforms_address; __gen_address_type coordinate_shader_code_address; + bool coordinate_shader_2_way_threadable; + bool coordinate_shader_4_way_threadable; + bool coordinate_shader_propagate_nans; __gen_address_type coordinate_shader_uniforms_address; }; @@ -3085,9 +3210,9 @@ V3D33_GL_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, __gen_emit_reloc(data, &values->fragment_shader_code_address); cl[12] = __gen_address_offset(&values->fragment_shader_code_address) | - __gen_uint(values->_2_way_threadable, 0, 0) | - __gen_uint(values->_4_way_threadable, 1, 1) | - __gen_uint(values->propagate_nans, 2, 2); + __gen_uint(values->fragment_shader_2_way_threadable, 0, 0) | + __gen_uint(values->fragment_shader_4_way_threadable, 1, 1) | + __gen_uint(values->fragment_shader_propagate_nans, 2, 2); cl[13] = __gen_address_offset(&values->fragment_shader_code_address) >> 8; @@ -3105,7 +3230,10 @@ V3D33_GL_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, cl[19] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 24; __gen_emit_reloc(data, &values->vertex_shader_code_address); - cl[20] = __gen_address_offset(&values->vertex_shader_code_address); + cl[20] = __gen_address_offset(&values->vertex_shader_code_address) | + __gen_uint(values->vertex_shader_2_way_threadable, 0, 0) | + __gen_uint(values->vertex_shader_4_way_threadable, 1, 1) | + __gen_uint(values->vertex_shader_propagate_nans, 2, 2); cl[21] = __gen_address_offset(&values->vertex_shader_code_address) >> 8; @@ -3123,7 +3251,10 @@ V3D33_GL_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, cl[27] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 24; __gen_emit_reloc(data, &values->coordinate_shader_code_address); - cl[28] = __gen_address_offset(&values->coordinate_shader_code_address); + cl[28] = __gen_address_offset(&values->coordinate_shader_code_address) | + __gen_uint(values->coordinate_shader_2_way_threadable, 0, 0) | + __gen_uint(values->coordinate_shader_4_way_threadable, 1, 1) | + __gen_uint(values->coordinate_shader_propagate_nans, 2, 2); cl[29] = __gen_address_offset(&values->coordinate_shader_code_address) >> 8; @@ -3166,13 +3297,19 @@ V3D33_GL_SHADER_STATE_RECORD_unpack(const uint8_t * restrict cl, values->vertex_shader_input_vpm_segment_size = __gen_unpack_uint(cl, 56, 63); values->address_of_default_attribute_values = __gen_unpack_address(cl, 64, 95); values->fragment_shader_code_address = __gen_unpack_address(cl, 99, 127); - values->_2_way_threadable = __gen_unpack_uint(cl, 96, 96); - values->_4_way_threadable = __gen_unpack_uint(cl, 97, 97); - values->propagate_nans = __gen_unpack_uint(cl, 98, 98); + values->fragment_shader_2_way_threadable = __gen_unpack_uint(cl, 96, 96); + values->fragment_shader_4_way_threadable = __gen_unpack_uint(cl, 97, 97); + values->fragment_shader_propagate_nans = __gen_unpack_uint(cl, 98, 98); values->fragment_shader_uniforms_address = __gen_unpack_address(cl, 128, 159); values->vertex_shader_code_address = __gen_unpack_address(cl, 160, 191); + values->vertex_shader_2_way_threadable = __gen_unpack_uint(cl, 160, 160); + values->vertex_shader_4_way_threadable = __gen_unpack_uint(cl, 161, 161); + values->vertex_shader_propagate_nans = __gen_unpack_uint(cl, 162, 162); values->vertex_shader_uniforms_address = __gen_unpack_address(cl, 192, 223); values->coordinate_shader_code_address = __gen_unpack_address(cl, 224, 255); + values->coordinate_shader_2_way_threadable = __gen_unpack_uint(cl, 224, 224); + values->coordinate_shader_4_way_threadable = __gen_unpack_uint(cl, 225, 225); + values->coordinate_shader_propagate_nans = __gen_unpack_uint(cl, 226, 226); values->coordinate_shader_uniforms_address = __gen_unpack_address(cl, 256, 287); } #endif @@ -3396,7 +3533,7 @@ struct V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1 { bool bias_supplied; bool gather_sample_mode; bool fetch_sample_mode; - bool lookup_type; + uint32_t lookup_type; #define TEXTURE_2D 0 #define TEXTURE_2D_ARRAY 1 #define TEXTURE_3D 2 @@ -3462,10 +3599,7 @@ V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_unpack(const uint8_t * restrict cl, struct V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1 { __gen_address_type texture_state_record_base_address; - bool return_word_3_of_texture_data; - bool return_word_2_of_texture_data; - bool return_word_1_of_texture_data; - bool return_word_0_of_texture_data; + uint32_t return_words_of_texture_data; }; static inline void @@ -3474,10 +3608,7 @@ V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1_pack(__gen_user_data *data, uint8_t { __gen_emit_reloc(data, &values->texture_state_record_base_address); cl[ 0] = __gen_address_offset(&values->texture_state_record_base_address) | - __gen_uint(values->return_word_3_of_texture_data, 3, 3) | - __gen_uint(values->return_word_2_of_texture_data, 2, 2) | - __gen_uint(values->return_word_1_of_texture_data, 1, 1) | - __gen_uint(values->return_word_0_of_texture_data, 0, 0); + __gen_uint(values->return_words_of_texture_data, 0, 3); cl[ 1] = __gen_address_offset(&values->texture_state_record_base_address) >> 8; @@ -3493,11 +3624,8 @@ static inline void V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1_unpack(const uint8_t * restrict cl, struct V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1 * restrict values) { - values->texture_state_record_base_address = __gen_unpack_address(cl, 0, 31); - values->return_word_3_of_texture_data = __gen_unpack_uint(cl, 3, 3); - values->return_word_2_of_texture_data = __gen_unpack_uint(cl, 2, 2); - values->return_word_1_of_texture_data = __gen_unpack_uint(cl, 1, 1); - values->return_word_0_of_texture_data = __gen_unpack_uint(cl, 0, 0); + values->texture_state_record_base_address = __gen_unpack_address(cl, 4, 31); + values->return_words_of_texture_data = __gen_unpack_uint(cl, 0, 3); } #endif @@ -3506,9 +3634,12 @@ V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1_unpack(const uint8_t * restrict cl, .flip_etc_y = 1 struct V3D33_TEXTURE_SHADER_STATE { + bool uif_xor_disable; bool level_0_is_strictly_uif; bool level_0_xor_enable; uint32_t level_0_ub_pad; + bool output_32_bit; + uint32_t sample_number; uint32_t base_level; float fixed_bias; float max_level_of_detail; @@ -3539,8 +3670,7 @@ struct V3D33_TEXTURE_SHADER_STATE { uint32_t image_width; uint32_t array_stride_64_byte_aligned; __gen_address_type texture_base_pointer; - uint32_t minification_filter; - uint32_t magnification_filter; + enum V3D33_TMU_Filter filter; }; static inline void @@ -3549,8 +3679,7 @@ V3D33_TEXTURE_SHADER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, { __gen_emit_reloc(data, &values->texture_base_pointer); cl[ 0] = __gen_address_offset(&values->texture_base_pointer) | - __gen_uint(values->minification_filter, 1, 3) | - __gen_uint(values->magnification_filter, 0, 0); + __gen_uint(values->filter, 0, 3); cl[ 1] = __gen_address_offset(&values->texture_base_pointer) >> 8; @@ -3622,9 +3751,12 @@ V3D33_TEXTURE_SHADER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, cl[29] = __gen_sfixed(values->fixed_bias, 0, 15, 8) >> 8; - cl[30] = __gen_uint(values->base_level, 0, 3); + cl[30] = __gen_uint(values->output_32_bit, 6, 6) | + __gen_uint(values->sample_number, 4, 5) | + __gen_uint(values->base_level, 0, 3); - cl[31] = __gen_uint(values->level_0_is_strictly_uif, 6, 6) | + cl[31] = __gen_uint(values->uif_xor_disable, 7, 7) | + __gen_uint(values->level_0_is_strictly_uif, 6, 6) | __gen_uint(values->level_0_xor_enable, 4, 4) | __gen_uint(values->level_0_ub_pad, 0, 3); @@ -3636,9 +3768,12 @@ static inline void V3D33_TEXTURE_SHADER_STATE_unpack(const uint8_t * restrict cl, struct V3D33_TEXTURE_SHADER_STATE * restrict values) { + values->uif_xor_disable = __gen_unpack_uint(cl, 255, 255); values->level_0_is_strictly_uif = __gen_unpack_uint(cl, 254, 254); values->level_0_xor_enable = __gen_unpack_uint(cl, 252, 252); values->level_0_ub_pad = __gen_unpack_uint(cl, 248, 251); + values->output_32_bit = __gen_unpack_uint(cl, 246, 246); + values->sample_number = __gen_unpack_uint(cl, 244, 245); values->base_level = __gen_unpack_uint(cl, 240, 243); values->fixed_bias = __gen_unpack_sfixed(cl, 224, 239, 8); values->max_level_of_detail = __gen_unpack_sfixed(cl, 208, 223, 8); @@ -3662,9 +3797,8 @@ V3D33_TEXTURE_SHADER_STATE_unpack(const uint8_t * restrict cl, values->image_height = __gen_unpack_uint(cl, 72, 85); values->image_width = __gen_unpack_uint(cl, 58, 71); values->array_stride_64_byte_aligned = __gen_unpack_uint(cl, 32, 57); - values->texture_base_pointer = __gen_unpack_address(cl, 0, 31); - values->minification_filter = __gen_unpack_uint(cl, 1, 3); - values->magnification_filter = __gen_unpack_uint(cl, 0, 0); + values->texture_base_pointer = __gen_unpack_address(cl, 2, 31); + values->filter = __gen_unpack_uint(cl, 0, 3); } #endif @@ -3728,6 +3862,25 @@ enum V3D33_Texture_Data_Formats { TEXTURE_DATA_FORMAT_ASTC_10X10 = 75, TEXTURE_DATA_FORMAT_ASTC_12X10 = 76, TEXTURE_DATA_FORMAT_ASTC_12X12 = 77, + TEXTURE_DATA_FORMAT_R8I = 96, + TEXTURE_DATA_FORMAT_R8UI = 97, + TEXTURE_DATA_FORMAT_RG8I = 98, + TEXTURE_DATA_FORMAT_RG8UI = 99, + TEXTURE_DATA_FORMAT_RGBA8I = 100, + TEXTURE_DATA_FORMAT_RGBA8UI = 101, + TEXTURE_DATA_FORMAT_R16I = 102, + TEXTURE_DATA_FORMAT_R16UI = 103, + TEXTURE_DATA_FORMAT_RG16I = 104, + TEXTURE_DATA_FORMAT_RG16UI = 105, + TEXTURE_DATA_FORMAT_RGBA16I = 106, + TEXTURE_DATA_FORMAT_RGBA16UI = 107, + TEXTURE_DATA_FORMAT_R32I = 108, + TEXTURE_DATA_FORMAT_R32UI = 109, + TEXTURE_DATA_FORMAT_RG32I = 110, + TEXTURE_DATA_FORMAT_RG32UI = 111, + TEXTURE_DATA_FORMAT_RGBA32I = 112, + TEXTURE_DATA_FORMAT_RGBA32UI = 113, + TEXTURE_DATA_FORMAT_RGB10_A2UI = 114, }; #endif /* V3D33_PACK_H */ diff --git a/lib/mesa/src/broadcom/cle/v3d_packet_v41_pack.h b/lib/mesa/src/broadcom/cle/v3d_packet_v41_pack.h new file mode 100644 index 000000000..03094eb22 --- /dev/null +++ b/lib/mesa/src/broadcom/cle/v3d_packet_v41_pack.h @@ -0,0 +1,4399 @@ +/* Generated code, see packets.xml and gen_packet_header.py */ + + +/* Packets, enums and structures for V3D 4.1. + * + * This file has been generated, do not hand edit. + */ + +#ifndef V3D41_PACK_H +#define V3D41_PACK_H + +#include "cle/v3d_packet_helpers.h" + + +enum V3D41_Compare_Function { + V3D_COMPARE_FUNC_NEVER = 0, + V3D_COMPARE_FUNC_LESS = 1, + V3D_COMPARE_FUNC_EQUAL = 2, + V3D_COMPARE_FUNC_LEQUAL = 3, + V3D_COMPARE_FUNC_GREATER = 4, + V3D_COMPARE_FUNC_NOTEQUAL = 5, + V3D_COMPARE_FUNC_GEQUAL = 6, + V3D_COMPARE_FUNC_ALWAYS = 7, +}; + +enum V3D41_Blend_Factor { + V3D_BLEND_FACTOR_ZERO = 0, + V3D_BLEND_FACTOR_ONE = 1, + V3D_BLEND_FACTOR_SRC_COLOR = 2, + V3D_BLEND_FACTOR_INV_SRC_COLOR = 3, + V3D_BLEND_FACTOR_DST_COLOR = 4, + V3D_BLEND_FACTOR_INV_DST_COLOR = 5, + V3D_BLEND_FACTOR_SRC_ALPHA = 6, + V3D_BLEND_FACTOR_INV_SRC_ALPHA = 7, + V3D_BLEND_FACTOR_DST_ALPHA = 8, + V3D_BLEND_FACTOR_INV_DST_ALPHA = 9, + V3D_BLEND_FACTOR_CONST_COLOR = 10, + V3D_BLEND_FACTOR_INV_CONST_COLOR = 11, + V3D_BLEND_FACTOR_CONST_ALPHA = 12, + V3D_BLEND_FACTOR_INV_CONST_ALPHA = 13, + V3D_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, +}; + +enum V3D41_Blend_Mode { + V3D_BLEND_MODE_ADD = 0, + V3D_BLEND_MODE_SUB = 1, + V3D_BLEND_MODE_RSUB = 2, + V3D_BLEND_MODE_MIN = 3, + V3D_BLEND_MODE_MAX = 4, + V3D_BLEND_MODE_MUL = 5, + V3D_BLEND_MODE_SCREEN = 6, + V3D_BLEND_MODE_DARKEN = 7, + V3D_BLEND_MODE_LIGHTEN = 8, +}; + +enum V3D41_Stencil_Op { + V3D_STENCIL_OP_ZERO = 0, + V3D_STENCIL_OP_KEEP = 1, + V3D_STENCIL_OP_REPLACE = 2, + V3D_STENCIL_OP_INCR = 3, + V3D_STENCIL_OP_DECR = 4, + V3D_STENCIL_OP_INVERT = 5, + V3D_STENCIL_OP_INCWRAP = 6, + V3D_STENCIL_OP_DECWRAP = 7, +}; + +enum V3D41_Primitive { + V3D_PRIM_POINTS = 0, + V3D_PRIM_LINES = 1, + V3D_PRIM_LINE_LOOP = 2, + V3D_PRIM_LINE_STRIP = 3, + V3D_PRIM_TRIANGLES = 4, + V3D_PRIM_TRIANGLE_STRIP = 5, + V3D_PRIM_TRIANGLE_FAN = 6, + V3D_PRIM_POINTS_TF = 16, + V3D_PRIM_LINES_TF = 17, + V3D_PRIM_LINE_LOOP_TF = 18, + V3D_PRIM_LINE_STRIP_TF = 19, + V3D_PRIM_TRIANGLES_TF = 20, + V3D_PRIM_TRIANGLE_STRIP_TF = 21, + V3D_PRIM_TRIANGLE_FAN_TF = 22, +}; + +enum V3D41_Border_Color_Mode { + V3D_BORDER_COLOR_0000 = 0, + V3D_BORDER_COLOR_0001 = 1, + V3D_BORDER_COLOR_1111 = 2, + V3D_BORDER_COLOR_FOLLOWS = 7, +}; + +enum V3D41_Wrap_Mode { + V3D_WRAP_MODE_WRAP_MODE_REPEAT = 0, + V3D_WRAP_MODE_WRAP_MODE_CLAMP = 1, + V3D_WRAP_MODE_WRAP_MODE_MIRROR = 2, + V3D_WRAP_MODE_WRAP_MODE_BORDER = 3, + V3D_WRAP_MODE_WRAP_MODE_MIRROR_ONCE = 4, +}; + +enum V3D41_TMU_Op { + V3D_TMU_OP_WRITE_ADD_READ_PREFETCH = 0, + V3D_TMU_OP_WRITE_SUB_READ_CLEAR = 1, + V3D_TMU_OP_WRITE_XCHG_READ_FLUSH = 2, + V3D_TMU_OP_WRITE_CMPXCHG_READ_FLUSH = 3, + V3D_TMU_OP_WRITE_UMIN_FULL_L1_CLEAR = 4, + V3D_TMU_OP_WRITE_UMAX = 5, + V3D_TMU_OP_WRITE_SMIN = 6, + V3D_TMU_OP_WRITE_SMAX = 7, + V3D_TMU_OP_WRITE_AND_READ_INC = 8, + V3D_TMU_OP_WRITE_OR_READ_DEC = 9, + V3D_TMU_OP_WRITE_XOR_READ_NOT = 10, + V3D_TMU_OP_REGULAR = 15, +}; + +enum V3D41_Varying_Flags_Action { + V3D_VARYING_FLAGS_ACTION_UNCHANGED = 0, + V3D_VARYING_FLAGS_ACTION_ZEROED = 1, + V3D_VARYING_FLAGS_ACTION_SET = 2, +}; + +enum V3D41_Memory_Format { + V3D_MEMORY_FORMAT_RASTER = 0, + V3D_MEMORY_FORMAT_LINEARTILE = 1, + V3D_MEMORY_FORMAT_UB_LINEAR_1_UIF_BLOCK_WIDE = 2, + V3D_MEMORY_FORMAT_UB_LINEAR_2_UIF_BLOCKS_WIDE = 3, + V3D_MEMORY_FORMAT_UIF_NO_XOR = 4, + V3D_MEMORY_FORMAT_UIF_XOR = 5, +}; + +enum V3D41_Decimate_Mode { + V3D_DECIMATE_MODE_SAMPLE_0 = 0, + V3D_DECIMATE_MODE_4X = 1, + V3D_DECIMATE_MODE_ALL_SAMPLES = 3, +}; + +enum V3D41_Internal_Type { + V3D_INTERNAL_TYPE_8I = 0, + V3D_INTERNAL_TYPE_8UI = 1, + V3D_INTERNAL_TYPE_8 = 2, + V3D_INTERNAL_TYPE_16I = 4, + V3D_INTERNAL_TYPE_16UI = 5, + V3D_INTERNAL_TYPE_16F = 6, + V3D_INTERNAL_TYPE_32I = 8, + V3D_INTERNAL_TYPE_32UI = 9, + V3D_INTERNAL_TYPE_32F = 10, +}; + +enum V3D41_Internal_BPP { + V3D_INTERNAL_BPP_32 = 0, + V3D_INTERNAL_BPP_64 = 1, + V3D_INTERNAL_BPP_128 = 2, +}; + +enum V3D41_Internal_Depth_Type { + V3D_INTERNAL_TYPE_DEPTH_32F = 0, + V3D_INTERNAL_TYPE_DEPTH_24 = 1, + V3D_INTERNAL_TYPE_DEPTH_16 = 2, +}; + +enum V3D41_Render_Target_Clamp { + V3D_RENDER_TARGET_CLAMP_NONE = 0, + V3D_RENDER_TARGET_CLAMP_NORM = 1, + V3D_RENDER_TARGET_CLAMP_POS = 2, +}; + +enum V3D41_Output_Image_Format { + V3D_OUTPUT_IMAGE_FORMAT_SRGB8_ALPHA8 = 0, + V3D_OUTPUT_IMAGE_FORMAT_SRGB = 1, + V3D_OUTPUT_IMAGE_FORMAT_RGB10_A2UI = 2, + V3D_OUTPUT_IMAGE_FORMAT_RGB10_A2 = 3, + V3D_OUTPUT_IMAGE_FORMAT_ABGR1555 = 4, + V3D_OUTPUT_IMAGE_FORMAT_ALPHA_MASKED_ABGR1555 = 5, + V3D_OUTPUT_IMAGE_FORMAT_ABGR4444 = 6, + V3D_OUTPUT_IMAGE_FORMAT_BGR565 = 7, + V3D_OUTPUT_IMAGE_FORMAT_R11F_G11F_B10F = 8, + V3D_OUTPUT_IMAGE_FORMAT_RGBA32F = 9, + V3D_OUTPUT_IMAGE_FORMAT_RG32F = 10, + V3D_OUTPUT_IMAGE_FORMAT_R32F = 11, + V3D_OUTPUT_IMAGE_FORMAT_RGBA32I = 12, + V3D_OUTPUT_IMAGE_FORMAT_RG32I = 13, + V3D_OUTPUT_IMAGE_FORMAT_R32I = 14, + V3D_OUTPUT_IMAGE_FORMAT_RGBA32UI = 15, + V3D_OUTPUT_IMAGE_FORMAT_RG32UI = 16, + V3D_OUTPUT_IMAGE_FORMAT_R32UI = 17, + V3D_OUTPUT_IMAGE_FORMAT_RGBA16F = 18, + V3D_OUTPUT_IMAGE_FORMAT_RG16F = 19, + V3D_OUTPUT_IMAGE_FORMAT_R16F = 20, + V3D_OUTPUT_IMAGE_FORMAT_RGBA16I = 21, + V3D_OUTPUT_IMAGE_FORMAT_RG16I = 22, + V3D_OUTPUT_IMAGE_FORMAT_R16I = 23, + V3D_OUTPUT_IMAGE_FORMAT_RGBA16UI = 24, + V3D_OUTPUT_IMAGE_FORMAT_RG16UI = 25, + V3D_OUTPUT_IMAGE_FORMAT_R16UI = 26, + V3D_OUTPUT_IMAGE_FORMAT_RGBA8 = 27, + V3D_OUTPUT_IMAGE_FORMAT_RGB8 = 28, + V3D_OUTPUT_IMAGE_FORMAT_RG8 = 29, + V3D_OUTPUT_IMAGE_FORMAT_R8 = 30, + V3D_OUTPUT_IMAGE_FORMAT_RGBA8I = 31, + V3D_OUTPUT_IMAGE_FORMAT_RG8I = 32, + V3D_OUTPUT_IMAGE_FORMAT_R8I = 33, + V3D_OUTPUT_IMAGE_FORMAT_RGBA8UI = 34, + V3D_OUTPUT_IMAGE_FORMAT_RG8UI = 35, + V3D_OUTPUT_IMAGE_FORMAT_R8UI = 36, + V3D_OUTPUT_IMAGE_FORMAT_BSTC = 39, + V3D_OUTPUT_IMAGE_FORMAT_D32F = 40, + V3D_OUTPUT_IMAGE_FORMAT_D24 = 41, + V3D_OUTPUT_IMAGE_FORMAT_D16 = 42, + V3D_OUTPUT_IMAGE_FORMAT_D24S8 = 43, + V3D_OUTPUT_IMAGE_FORMAT_S8 = 44, +}; + +enum V3D41_Dither_Mode { + V3D_DITHER_MODE_NONE = 0, + V3D_DITHER_MODE_RGB = 1, + V3D_DITHER_MODE_A = 2, + V3D_DITHER_MODE_RGBA = 3, +}; + +#define V3D41_HALT_opcode 0 +#define V3D41_HALT_header \ + .opcode = 0 + +struct V3D41_HALT { + uint32_t opcode; +}; + +static inline void +V3D41_HALT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_HALT * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_HALT_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_HALT_unpack(const uint8_t * restrict cl, + struct V3D41_HALT * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_NOP_opcode 1 +#define V3D41_NOP_header \ + .opcode = 1 + +struct V3D41_NOP { + uint32_t opcode; +}; + +static inline void +V3D41_NOP_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_NOP * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_NOP_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_NOP_unpack(const uint8_t * restrict cl, + struct V3D41_NOP * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_FLUSH_opcode 4 +#define V3D41_FLUSH_header \ + .opcode = 4 + +struct V3D41_FLUSH { + uint32_t opcode; +}; + +static inline void +V3D41_FLUSH_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_FLUSH * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_FLUSH_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_FLUSH_unpack(const uint8_t * restrict cl, + struct V3D41_FLUSH * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_FLUSH_ALL_STATE_opcode 5 +#define V3D41_FLUSH_ALL_STATE_header \ + .opcode = 5 + +struct V3D41_FLUSH_ALL_STATE { + uint32_t opcode; +}; + +static inline void +V3D41_FLUSH_ALL_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_FLUSH_ALL_STATE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_FLUSH_ALL_STATE_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_FLUSH_ALL_STATE_unpack(const uint8_t * restrict cl, + struct V3D41_FLUSH_ALL_STATE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_START_TILE_BINNING_opcode 6 +#define V3D41_START_TILE_BINNING_header \ + .opcode = 6 + +struct V3D41_START_TILE_BINNING { + uint32_t opcode; +}; + +static inline void +V3D41_START_TILE_BINNING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_START_TILE_BINNING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_START_TILE_BINNING_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_START_TILE_BINNING_unpack(const uint8_t * restrict cl, + struct V3D41_START_TILE_BINNING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_INCREMENT_SEMAPHORE_opcode 7 +#define V3D41_INCREMENT_SEMAPHORE_header \ + .opcode = 7 + +struct V3D41_INCREMENT_SEMAPHORE { + uint32_t opcode; +}; + +static inline void +V3D41_INCREMENT_SEMAPHORE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_INCREMENT_SEMAPHORE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_INCREMENT_SEMAPHORE_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_INCREMENT_SEMAPHORE_unpack(const uint8_t * restrict cl, + struct V3D41_INCREMENT_SEMAPHORE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_WAIT_ON_SEMAPHORE_opcode 8 +#define V3D41_WAIT_ON_SEMAPHORE_header \ + .opcode = 8 + +struct V3D41_WAIT_ON_SEMAPHORE { + uint32_t opcode; +}; + +static inline void +V3D41_WAIT_ON_SEMAPHORE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_WAIT_ON_SEMAPHORE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_WAIT_ON_SEMAPHORE_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_WAIT_ON_SEMAPHORE_unpack(const uint8_t * restrict cl, + struct V3D41_WAIT_ON_SEMAPHORE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_WAIT_FOR_PREVIOUS_FRAME_opcode 9 +#define V3D41_WAIT_FOR_PREVIOUS_FRAME_header \ + .opcode = 9 + +struct V3D41_WAIT_FOR_PREVIOUS_FRAME { + uint32_t opcode; +}; + +static inline void +V3D41_WAIT_FOR_PREVIOUS_FRAME_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_WAIT_FOR_PREVIOUS_FRAME * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_WAIT_FOR_PREVIOUS_FRAME_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_WAIT_FOR_PREVIOUS_FRAME_unpack(const uint8_t * restrict cl, + struct V3D41_WAIT_FOR_PREVIOUS_FRAME * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_ENABLE_Z_ONLY_RENDERING_opcode 10 +#define V3D41_ENABLE_Z_ONLY_RENDERING_header \ + .opcode = 10 + +struct V3D41_ENABLE_Z_ONLY_RENDERING { + uint32_t opcode; +}; + +static inline void +V3D41_ENABLE_Z_ONLY_RENDERING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_ENABLE_Z_ONLY_RENDERING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_ENABLE_Z_ONLY_RENDERING_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_ENABLE_Z_ONLY_RENDERING_unpack(const uint8_t * restrict cl, + struct V3D41_ENABLE_Z_ONLY_RENDERING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_DISABLE_Z_ONLY_RENDERING_opcode 11 +#define V3D41_DISABLE_Z_ONLY_RENDERING_header \ + .opcode = 11 + +struct V3D41_DISABLE_Z_ONLY_RENDERING { + uint32_t opcode; +}; + +static inline void +V3D41_DISABLE_Z_ONLY_RENDERING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_DISABLE_Z_ONLY_RENDERING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_DISABLE_Z_ONLY_RENDERING_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_DISABLE_Z_ONLY_RENDERING_unpack(const uint8_t * restrict cl, + struct V3D41_DISABLE_Z_ONLY_RENDERING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_END_OF_Z_ONLY_RENDERING_IN_FRAME_opcode 12 +#define V3D41_END_OF_Z_ONLY_RENDERING_IN_FRAME_header\ + .opcode = 12 + +struct V3D41_END_OF_Z_ONLY_RENDERING_IN_FRAME { + uint32_t opcode; +}; + +static inline void +V3D41_END_OF_Z_ONLY_RENDERING_IN_FRAME_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_END_OF_Z_ONLY_RENDERING_IN_FRAME * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_END_OF_Z_ONLY_RENDERING_IN_FRAME_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_END_OF_Z_ONLY_RENDERING_IN_FRAME_unpack(const uint8_t * restrict cl, + struct V3D41_END_OF_Z_ONLY_RENDERING_IN_FRAME * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_END_OF_RENDERING_opcode 13 +#define V3D41_END_OF_RENDERING_header \ + .opcode = 13 + +struct V3D41_END_OF_RENDERING { + uint32_t opcode; +}; + +static inline void +V3D41_END_OF_RENDERING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_END_OF_RENDERING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_END_OF_RENDERING_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_END_OF_RENDERING_unpack(const uint8_t * restrict cl, + struct V3D41_END_OF_RENDERING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_WAIT_FOR_TRANSFORM_FEEDBACK_opcode 14 +#define V3D41_WAIT_FOR_TRANSFORM_FEEDBACK_header\ + .opcode = 14 + +struct V3D41_WAIT_FOR_TRANSFORM_FEEDBACK { + uint32_t opcode; + uint32_t block_count; +}; + +static inline void +V3D41_WAIT_FOR_TRANSFORM_FEEDBACK_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_WAIT_FOR_TRANSFORM_FEEDBACK * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->block_count, 0, 7); + +} + +#define V3D41_WAIT_FOR_TRANSFORM_FEEDBACK_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_WAIT_FOR_TRANSFORM_FEEDBACK_unpack(const uint8_t * restrict cl, + struct V3D41_WAIT_FOR_TRANSFORM_FEEDBACK * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->block_count = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D41_BRANCH_TO_AUTO_CHAINED_SUB_LIST_opcode 15 +#define V3D41_BRANCH_TO_AUTO_CHAINED_SUB_LIST_header\ + .opcode = 15 + +struct V3D41_BRANCH_TO_AUTO_CHAINED_SUB_LIST { + uint32_t opcode; + __gen_address_type address; +}; + +static inline void +V3D41_BRANCH_TO_AUTO_CHAINED_SUB_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_BRANCH_TO_AUTO_CHAINED_SUB_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D41_BRANCH_TO_AUTO_CHAINED_SUB_LIST_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_BRANCH_TO_AUTO_CHAINED_SUB_LIST_unpack(const uint8_t * restrict cl, + struct V3D41_BRANCH_TO_AUTO_CHAINED_SUB_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); +} +#endif + + +#define V3D41_BRANCH_opcode 16 +#define V3D41_BRANCH_header \ + .opcode = 16 + +struct V3D41_BRANCH { + uint32_t opcode; + __gen_address_type address; +}; + +static inline void +V3D41_BRANCH_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_BRANCH * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D41_BRANCH_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_BRANCH_unpack(const uint8_t * restrict cl, + struct V3D41_BRANCH * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); +} +#endif + + +#define V3D41_BRANCH_TO_SUB_LIST_opcode 17 +#define V3D41_BRANCH_TO_SUB_LIST_header \ + .opcode = 17 + +struct V3D41_BRANCH_TO_SUB_LIST { + uint32_t opcode; + __gen_address_type address; +}; + +static inline void +V3D41_BRANCH_TO_SUB_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_BRANCH_TO_SUB_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D41_BRANCH_TO_SUB_LIST_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_BRANCH_TO_SUB_LIST_unpack(const uint8_t * restrict cl, + struct V3D41_BRANCH_TO_SUB_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); +} +#endif + + +#define V3D41_RETURN_FROM_SUB_LIST_opcode 18 +#define V3D41_RETURN_FROM_SUB_LIST_header \ + .opcode = 18 + +struct V3D41_RETURN_FROM_SUB_LIST { + uint32_t opcode; +}; + +static inline void +V3D41_RETURN_FROM_SUB_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_RETURN_FROM_SUB_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_RETURN_FROM_SUB_LIST_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_RETURN_FROM_SUB_LIST_unpack(const uint8_t * restrict cl, + struct V3D41_RETURN_FROM_SUB_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_FLUSH_VCD_CACHE_opcode 19 +#define V3D41_FLUSH_VCD_CACHE_header \ + .opcode = 19 + +struct V3D41_FLUSH_VCD_CACHE { + uint32_t opcode; +}; + +static inline void +V3D41_FLUSH_VCD_CACHE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_FLUSH_VCD_CACHE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_FLUSH_VCD_CACHE_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_FLUSH_VCD_CACHE_unpack(const uint8_t * restrict cl, + struct V3D41_FLUSH_VCD_CACHE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_START_ADDRESS_OF_GENERIC_TILE_LIST_opcode 20 +#define V3D41_START_ADDRESS_OF_GENERIC_TILE_LIST_header\ + .opcode = 20 + +struct V3D41_START_ADDRESS_OF_GENERIC_TILE_LIST { + uint32_t opcode; + __gen_address_type start; + __gen_address_type end; +}; + +static inline void +V3D41_START_ADDRESS_OF_GENERIC_TILE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_START_ADDRESS_OF_GENERIC_TILE_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->start); + cl[ 1] = __gen_address_offset(&values->start); + + cl[ 2] = __gen_address_offset(&values->start) >> 8; + + cl[ 3] = __gen_address_offset(&values->start) >> 16; + + cl[ 4] = __gen_address_offset(&values->start) >> 24; + + __gen_emit_reloc(data, &values->end); + cl[ 5] = __gen_address_offset(&values->end); + + cl[ 6] = __gen_address_offset(&values->end) >> 8; + + cl[ 7] = __gen_address_offset(&values->end) >> 16; + + cl[ 8] = __gen_address_offset(&values->end) >> 24; + +} + +#define V3D41_START_ADDRESS_OF_GENERIC_TILE_LIST_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_START_ADDRESS_OF_GENERIC_TILE_LIST_unpack(const uint8_t * restrict cl, + struct V3D41_START_ADDRESS_OF_GENERIC_TILE_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->start = __gen_unpack_address(cl, 8, 39); + values->end = __gen_unpack_address(cl, 40, 71); +} +#endif + + +#define V3D41_BRANCH_TO_IMPLICIT_TILE_LIST_opcode 21 +#define V3D41_BRANCH_TO_IMPLICIT_TILE_LIST_header\ + .opcode = 21 + +struct V3D41_BRANCH_TO_IMPLICIT_TILE_LIST { + uint32_t opcode; + uint32_t tile_list_set_number; +}; + +static inline void +V3D41_BRANCH_TO_IMPLICIT_TILE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_BRANCH_TO_IMPLICIT_TILE_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->tile_list_set_number, 0, 7); + +} + +#define V3D41_BRANCH_TO_IMPLICIT_TILE_LIST_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_BRANCH_TO_IMPLICIT_TILE_LIST_unpack(const uint8_t * restrict cl, + struct V3D41_BRANCH_TO_IMPLICIT_TILE_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->tile_list_set_number = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D41_BRANCH_TO_EXPLICIT_SUPERTILE_opcode 22 +#define V3D41_BRANCH_TO_EXPLICIT_SUPERTILE_header\ + .opcode = 22 + +struct V3D41_BRANCH_TO_EXPLICIT_SUPERTILE { + uint32_t opcode; + __gen_address_type absolute_address_of_explicit_supertile_render_list; + uint32_t explicit_supertile_number; + uint32_t row_number; + uint32_t column_number; +}; + +static inline void +V3D41_BRANCH_TO_EXPLICIT_SUPERTILE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_BRANCH_TO_EXPLICIT_SUPERTILE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->column_number, 0, 7); + + cl[ 2] = __gen_uint(values->row_number, 0, 7); + + cl[ 3] = __gen_uint(values->explicit_supertile_number, 0, 7); + + __gen_emit_reloc(data, &values->absolute_address_of_explicit_supertile_render_list); + cl[ 4] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list); + + cl[ 5] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list) >> 8; + + cl[ 6] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list) >> 16; + + cl[ 7] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list) >> 24; + +} + +#define V3D41_BRANCH_TO_EXPLICIT_SUPERTILE_length 8 +#ifdef __gen_unpack_address +static inline void +V3D41_BRANCH_TO_EXPLICIT_SUPERTILE_unpack(const uint8_t * restrict cl, + struct V3D41_BRANCH_TO_EXPLICIT_SUPERTILE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->absolute_address_of_explicit_supertile_render_list = __gen_unpack_address(cl, 32, 63); + values->explicit_supertile_number = __gen_unpack_uint(cl, 24, 31); + values->row_number = __gen_unpack_uint(cl, 16, 23); + values->column_number = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D41_SUPERTILE_COORDINATES_opcode 23 +#define V3D41_SUPERTILE_COORDINATES_header \ + .opcode = 23 + +struct V3D41_SUPERTILE_COORDINATES { + uint32_t opcode; + uint32_t row_number_in_supertiles; + uint32_t column_number_in_supertiles; +}; + +static inline void +V3D41_SUPERTILE_COORDINATES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_SUPERTILE_COORDINATES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->column_number_in_supertiles, 0, 7); + + cl[ 2] = __gen_uint(values->row_number_in_supertiles, 0, 7); + +} + +#define V3D41_SUPERTILE_COORDINATES_length 3 +#ifdef __gen_unpack_address +static inline void +V3D41_SUPERTILE_COORDINATES_unpack(const uint8_t * restrict cl, + struct V3D41_SUPERTILE_COORDINATES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->row_number_in_supertiles = __gen_unpack_uint(cl, 16, 23); + values->column_number_in_supertiles = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D41_CLEAR_TILE_BUFFERS_opcode 25 +#define V3D41_CLEAR_TILE_BUFFERS_header \ + .opcode = 25 + +struct V3D41_CLEAR_TILE_BUFFERS { + uint32_t opcode; + bool clear_z_stencil_buffer; + bool clear_all_render_targets; +}; + +static inline void +V3D41_CLEAR_TILE_BUFFERS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_CLEAR_TILE_BUFFERS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->clear_z_stencil_buffer, 1, 1) | + __gen_uint(values->clear_all_render_targets, 0, 0); + +} + +#define V3D41_CLEAR_TILE_BUFFERS_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_CLEAR_TILE_BUFFERS_unpack(const uint8_t * restrict cl, + struct V3D41_CLEAR_TILE_BUFFERS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->clear_z_stencil_buffer = __gen_unpack_uint(cl, 9, 9); + values->clear_all_render_targets = __gen_unpack_uint(cl, 8, 8); +} +#endif + + +#define V3D41_END_OF_LOADS_opcode 26 +#define V3D41_END_OF_LOADS_header \ + .opcode = 26 + +struct V3D41_END_OF_LOADS { + uint32_t opcode; +}; + +static inline void +V3D41_END_OF_LOADS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_END_OF_LOADS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_END_OF_LOADS_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_END_OF_LOADS_unpack(const uint8_t * restrict cl, + struct V3D41_END_OF_LOADS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_END_OF_TILE_MARKER_opcode 27 +#define V3D41_END_OF_TILE_MARKER_header \ + .opcode = 27 + +struct V3D41_END_OF_TILE_MARKER { + uint32_t opcode; +}; + +static inline void +V3D41_END_OF_TILE_MARKER_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_END_OF_TILE_MARKER * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_END_OF_TILE_MARKER_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_END_OF_TILE_MARKER_unpack(const uint8_t * restrict cl, + struct V3D41_END_OF_TILE_MARKER * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_STORE_TILE_BUFFER_GENERAL_opcode 29 +#define V3D41_STORE_TILE_BUFFER_GENERAL_header \ + .opcode = 29 + +struct V3D41_STORE_TILE_BUFFER_GENERAL { + uint32_t opcode; + __gen_address_type address; + uint32_t height; + uint32_t height_in_ub_or_stride; + bool r_b_swap; + bool channel_reverse; + bool clear_buffer_being_stored; + enum V3D41_Output_Image_Format output_image_format; + enum V3D41_Decimate_Mode decimate_mode; + enum V3D41_Dither_Mode dither_mode; + bool flip_y; + enum V3D41_Memory_Format memory_format; + uint32_t buffer_to_store; +#define RENDER_TARGET_0 0 +#define RENDER_TARGET_1 1 +#define RENDER_TARGET_2 2 +#define RENDER_TARGET_3 3 +#define NONE 8 +#define Z 9 +#define STENCIL 10 +#define ZSTENCIL 11 +}; + +static inline void +V3D41_STORE_TILE_BUFFER_GENERAL_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_STORE_TILE_BUFFER_GENERAL * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->flip_y, 7, 7) | + __gen_uint(values->memory_format, 4, 6) | + __gen_uint(values->buffer_to_store, 0, 3); + + cl[ 2] = __gen_uint(values->output_image_format, 4, 9) | + __gen_uint(values->decimate_mode, 2, 3) | + __gen_uint(values->dither_mode, 0, 1); + + cl[ 3] = __gen_uint(values->r_b_swap, 4, 4) | + __gen_uint(values->channel_reverse, 3, 3) | + __gen_uint(values->clear_buffer_being_stored, 2, 2) | + __gen_uint(values->output_image_format, 4, 9) >> 8; + + cl[ 4] = __gen_uint(values->height_in_ub_or_stride, 4, 23); + + cl[ 5] = __gen_uint(values->height_in_ub_or_stride, 4, 23) >> 8; + + cl[ 6] = __gen_uint(values->height_in_ub_or_stride, 4, 23) >> 16; + + cl[ 7] = __gen_uint(values->height, 0, 15); + + cl[ 8] = __gen_uint(values->height, 0, 15) >> 8; + + __gen_emit_reloc(data, &values->address); + cl[ 9] = __gen_address_offset(&values->address); + + cl[10] = __gen_address_offset(&values->address) >> 8; + + cl[11] = __gen_address_offset(&values->address) >> 16; + + cl[12] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D41_STORE_TILE_BUFFER_GENERAL_length 13 +#ifdef __gen_unpack_address +static inline void +V3D41_STORE_TILE_BUFFER_GENERAL_unpack(const uint8_t * restrict cl, + struct V3D41_STORE_TILE_BUFFER_GENERAL * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 72, 103); + values->height = __gen_unpack_uint(cl, 56, 71); + values->height_in_ub_or_stride = __gen_unpack_uint(cl, 36, 55); + values->r_b_swap = __gen_unpack_uint(cl, 28, 28); + values->channel_reverse = __gen_unpack_uint(cl, 27, 27); + values->clear_buffer_being_stored = __gen_unpack_uint(cl, 26, 26); + values->output_image_format = __gen_unpack_uint(cl, 20, 25); + values->decimate_mode = __gen_unpack_uint(cl, 18, 19); + values->dither_mode = __gen_unpack_uint(cl, 16, 17); + values->flip_y = __gen_unpack_uint(cl, 15, 15); + values->memory_format = __gen_unpack_uint(cl, 12, 14); + values->buffer_to_store = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_LOAD_TILE_BUFFER_GENERAL_opcode 30 +#define V3D41_LOAD_TILE_BUFFER_GENERAL_header \ + .opcode = 30 + +struct V3D41_LOAD_TILE_BUFFER_GENERAL { + uint32_t opcode; + __gen_address_type address; + uint32_t height; + uint32_t height_in_ub_or_stride; + bool r_b_swap; + bool channel_reverse; + enum V3D41_Output_Image_Format input_image_format; + enum V3D41_Decimate_Mode decimate_mode; + bool flip_y; + enum V3D41_Memory_Format memory_format; + uint32_t buffer_to_load; +#define RENDER_TARGET_0 0 +#define RENDER_TARGET_1 1 +#define RENDER_TARGET_2 2 +#define RENDER_TARGET_3 3 +#define NONE 8 +#define Z 9 +#define STENCIL 10 +#define ZSTENCIL 11 +}; + +static inline void +V3D41_LOAD_TILE_BUFFER_GENERAL_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_LOAD_TILE_BUFFER_GENERAL * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->flip_y, 7, 7) | + __gen_uint(values->memory_format, 4, 6) | + __gen_uint(values->buffer_to_load, 0, 3); + + cl[ 2] = __gen_uint(values->input_image_format, 4, 9) | + __gen_uint(values->decimate_mode, 2, 3); + + cl[ 3] = __gen_uint(values->r_b_swap, 4, 4) | + __gen_uint(values->channel_reverse, 3, 3) | + __gen_uint(values->input_image_format, 4, 9) >> 8; + + cl[ 4] = __gen_uint(values->height_in_ub_or_stride, 4, 23); + + cl[ 5] = __gen_uint(values->height_in_ub_or_stride, 4, 23) >> 8; + + cl[ 6] = __gen_uint(values->height_in_ub_or_stride, 4, 23) >> 16; + + cl[ 7] = __gen_uint(values->height, 0, 15); + + cl[ 8] = __gen_uint(values->height, 0, 15) >> 8; + + __gen_emit_reloc(data, &values->address); + cl[ 9] = __gen_address_offset(&values->address); + + cl[10] = __gen_address_offset(&values->address) >> 8; + + cl[11] = __gen_address_offset(&values->address) >> 16; + + cl[12] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D41_LOAD_TILE_BUFFER_GENERAL_length 13 +#ifdef __gen_unpack_address +static inline void +V3D41_LOAD_TILE_BUFFER_GENERAL_unpack(const uint8_t * restrict cl, + struct V3D41_LOAD_TILE_BUFFER_GENERAL * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 72, 103); + values->height = __gen_unpack_uint(cl, 56, 71); + values->height_in_ub_or_stride = __gen_unpack_uint(cl, 36, 55); + values->r_b_swap = __gen_unpack_uint(cl, 28, 28); + values->channel_reverse = __gen_unpack_uint(cl, 27, 27); + values->input_image_format = __gen_unpack_uint(cl, 20, 25); + values->decimate_mode = __gen_unpack_uint(cl, 18, 19); + values->flip_y = __gen_unpack_uint(cl, 15, 15); + values->memory_format = __gen_unpack_uint(cl, 12, 14); + values->buffer_to_load = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_opcode 31 +#define V3D41_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_header\ + .opcode = 31 + +struct V3D41_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT { + uint32_t opcode; +}; + +static inline void +V3D41_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_unpack(const uint8_t * restrict cl, + struct V3D41_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_INDEXED_PRIM_LIST_opcode 32 +#define V3D41_INDEXED_PRIM_LIST_header \ + .opcode = 32 + +struct V3D41_INDEXED_PRIM_LIST { + uint32_t opcode; + uint32_t index_offset; + bool enable_primitive_restarts; + uint32_t length; + uint32_t index_type; +#define INDEX_TYPE_8_BIT 0 +#define INDEX_TYPE_16_BIT 1 +#define INDEX_TYPE_32_BIT 2 + enum V3D41_Primitive mode; +}; + +static inline void +V3D41_INDEXED_PRIM_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_INDEXED_PRIM_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->index_type, 6, 7) | + __gen_uint(values->mode, 0, 5); + + cl[ 2] = __gen_uint(values->length, 0, 30); + + cl[ 3] = __gen_uint(values->length, 0, 30) >> 8; + + cl[ 4] = __gen_uint(values->length, 0, 30) >> 16; + + cl[ 5] = __gen_uint(values->enable_primitive_restarts, 7, 7) | + __gen_uint(values->length, 0, 30) >> 24; + + + memcpy(&cl[6], &values->index_offset, sizeof(values->index_offset)); +} + +#define V3D41_INDEXED_PRIM_LIST_length 10 +#ifdef __gen_unpack_address +static inline void +V3D41_INDEXED_PRIM_LIST_unpack(const uint8_t * restrict cl, + struct V3D41_INDEXED_PRIM_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->index_offset = __gen_unpack_uint(cl, 48, 79); + values->enable_primitive_restarts = __gen_unpack_uint(cl, 47, 47); + values->length = __gen_unpack_uint(cl, 16, 46); + values->index_type = __gen_unpack_uint(cl, 14, 15); + values->mode = __gen_unpack_uint(cl, 8, 13); +} +#endif + + +#define V3D41_INDEXED_INSTANCED_PRIM_LIST_opcode 34 +#define V3D41_INDEXED_INSTANCED_PRIM_LIST_header\ + .opcode = 34 + +struct V3D41_INDEXED_INSTANCED_PRIM_LIST { + uint32_t opcode; + uint32_t index_offset; + uint32_t number_of_instances; + bool enable_primitive_restarts; + uint32_t instance_length; + uint32_t index_type; +#define INDEX_TYPE_8_BIT 0 +#define INDEX_TYPE_16_BIT 1 +#define INDEX_TYPE_32_BIT 2 + enum V3D41_Primitive mode; +}; + +static inline void +V3D41_INDEXED_INSTANCED_PRIM_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_INDEXED_INSTANCED_PRIM_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->index_type, 6, 7) | + __gen_uint(values->mode, 0, 5); + + cl[ 2] = __gen_uint(values->instance_length, 0, 30); + + cl[ 3] = __gen_uint(values->instance_length, 0, 30) >> 8; + + cl[ 4] = __gen_uint(values->instance_length, 0, 30) >> 16; + + cl[ 5] = __gen_uint(values->enable_primitive_restarts, 7, 7) | + __gen_uint(values->instance_length, 0, 30) >> 24; + + + memcpy(&cl[6], &values->number_of_instances, sizeof(values->number_of_instances)); + + memcpy(&cl[10], &values->index_offset, sizeof(values->index_offset)); +} + +#define V3D41_INDEXED_INSTANCED_PRIM_LIST_length 14 +#ifdef __gen_unpack_address +static inline void +V3D41_INDEXED_INSTANCED_PRIM_LIST_unpack(const uint8_t * restrict cl, + struct V3D41_INDEXED_INSTANCED_PRIM_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->index_offset = __gen_unpack_uint(cl, 80, 111); + values->number_of_instances = __gen_unpack_uint(cl, 48, 79); + values->enable_primitive_restarts = __gen_unpack_uint(cl, 47, 47); + values->instance_length = __gen_unpack_uint(cl, 16, 46); + values->index_type = __gen_unpack_uint(cl, 14, 15); + values->mode = __gen_unpack_uint(cl, 8, 13); +} +#endif + + +#define V3D41_VERTEX_ARRAY_PRIMS_opcode 36 +#define V3D41_VERTEX_ARRAY_PRIMS_header \ + .opcode = 36 + +struct V3D41_VERTEX_ARRAY_PRIMS { + uint32_t opcode; + uint32_t index_of_first_vertex; + uint32_t length; + enum V3D41_Primitive mode; +}; + +static inline void +V3D41_VERTEX_ARRAY_PRIMS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_VERTEX_ARRAY_PRIMS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->mode, 0, 7); + + + memcpy(&cl[2], &values->length, sizeof(values->length)); + + memcpy(&cl[6], &values->index_of_first_vertex, sizeof(values->index_of_first_vertex)); +} + +#define V3D41_VERTEX_ARRAY_PRIMS_length 10 +#ifdef __gen_unpack_address +static inline void +V3D41_VERTEX_ARRAY_PRIMS_unpack(const uint8_t * restrict cl, + struct V3D41_VERTEX_ARRAY_PRIMS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->index_of_first_vertex = __gen_unpack_uint(cl, 48, 79); + values->length = __gen_unpack_uint(cl, 16, 47); + values->mode = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D41_VERTEX_ARRAY_INSTANCED_PRIMS_opcode 38 +#define V3D41_VERTEX_ARRAY_INSTANCED_PRIMS_header\ + .opcode = 38 + +struct V3D41_VERTEX_ARRAY_INSTANCED_PRIMS { + uint32_t opcode; + uint32_t index_of_first_vertex; + uint32_t number_of_instances; + uint32_t instance_length; + enum V3D41_Primitive mode; +}; + +static inline void +V3D41_VERTEX_ARRAY_INSTANCED_PRIMS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_VERTEX_ARRAY_INSTANCED_PRIMS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->mode, 0, 7); + + + memcpy(&cl[2], &values->instance_length, sizeof(values->instance_length)); + + memcpy(&cl[6], &values->number_of_instances, sizeof(values->number_of_instances)); + + memcpy(&cl[10], &values->index_of_first_vertex, sizeof(values->index_of_first_vertex)); +} + +#define V3D41_VERTEX_ARRAY_INSTANCED_PRIMS_length 14 +#ifdef __gen_unpack_address +static inline void +V3D41_VERTEX_ARRAY_INSTANCED_PRIMS_unpack(const uint8_t * restrict cl, + struct V3D41_VERTEX_ARRAY_INSTANCED_PRIMS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->index_of_first_vertex = __gen_unpack_uint(cl, 80, 111); + values->number_of_instances = __gen_unpack_uint(cl, 48, 79); + values->instance_length = __gen_unpack_uint(cl, 16, 47); + values->mode = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D41_BASE_VERTEX_BASE_INSTANCE_opcode 43 +#define V3D41_BASE_VERTEX_BASE_INSTANCE_header \ + .opcode = 43 + +struct V3D41_BASE_VERTEX_BASE_INSTANCE { + uint32_t opcode; + uint32_t base_instance; + uint32_t base_vertex; +}; + +static inline void +V3D41_BASE_VERTEX_BASE_INSTANCE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_BASE_VERTEX_BASE_INSTANCE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->base_vertex, sizeof(values->base_vertex)); + + memcpy(&cl[5], &values->base_instance, sizeof(values->base_instance)); +} + +#define V3D41_BASE_VERTEX_BASE_INSTANCE_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_BASE_VERTEX_BASE_INSTANCE_unpack(const uint8_t * restrict cl, + struct V3D41_BASE_VERTEX_BASE_INSTANCE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->base_instance = __gen_unpack_uint(cl, 40, 71); + values->base_vertex = __gen_unpack_uint(cl, 8, 39); +} +#endif + + +#define V3D41_INDEX_BUFFER_SETUP_opcode 44 +#define V3D41_INDEX_BUFFER_SETUP_header \ + .opcode = 44 + +struct V3D41_INDEX_BUFFER_SETUP { + uint32_t opcode; + __gen_address_type address; + uint32_t size; +}; + +static inline void +V3D41_INDEX_BUFFER_SETUP_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_INDEX_BUFFER_SETUP * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + + + memcpy(&cl[5], &values->size, sizeof(values->size)); +} + +#define V3D41_INDEX_BUFFER_SETUP_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_INDEX_BUFFER_SETUP_unpack(const uint8_t * restrict cl, + struct V3D41_INDEX_BUFFER_SETUP * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); + values->size = __gen_unpack_uint(cl, 40, 71); +} +#endif + + +#define V3D41_PRIM_LIST_FORMAT_opcode 56 +#define V3D41_PRIM_LIST_FORMAT_header \ + .opcode = 56 + +struct V3D41_PRIM_LIST_FORMAT { + uint32_t opcode; + bool tri_strip_or_fan; + uint32_t primitive_type; +#define LIST_POINTS 0 +#define LIST_LINES 1 +#define LIST_TRIANGLES 2 +}; + +static inline void +V3D41_PRIM_LIST_FORMAT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_PRIM_LIST_FORMAT * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->tri_strip_or_fan, 7, 7) | + __gen_uint(values->primitive_type, 0, 5); + +} + +#define V3D41_PRIM_LIST_FORMAT_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_PRIM_LIST_FORMAT_unpack(const uint8_t * restrict cl, + struct V3D41_PRIM_LIST_FORMAT * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->tri_strip_or_fan = __gen_unpack_uint(cl, 15, 15); + values->primitive_type = __gen_unpack_uint(cl, 8, 13); +} +#endif + + +#define V3D41_GL_SHADER_STATE_opcode 64 +#define V3D41_GL_SHADER_STATE_header \ + .opcode = 64 + +struct V3D41_GL_SHADER_STATE { + uint32_t opcode; + __gen_address_type address; + uint32_t number_of_attribute_arrays; +}; + +static inline void +V3D41_GL_SHADER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_GL_SHADER_STATE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address) | + __gen_uint(values->number_of_attribute_arrays, 0, 4); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D41_GL_SHADER_STATE_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_GL_SHADER_STATE_unpack(const uint8_t * restrict cl, + struct V3D41_GL_SHADER_STATE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 13, 39); + values->number_of_attribute_arrays = __gen_unpack_uint(cl, 8, 12); +} +#endif + + +#define V3D41_VCM_CACHE_SIZE_opcode 71 +#define V3D41_VCM_CACHE_SIZE_header \ + .opcode = 71 + +struct V3D41_VCM_CACHE_SIZE { + uint32_t opcode; + uint32_t number_of_16_vertex_batches_for_rendering; + uint32_t number_of_16_vertex_batches_for_binning; +}; + +static inline void +V3D41_VCM_CACHE_SIZE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_VCM_CACHE_SIZE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->number_of_16_vertex_batches_for_rendering, 4, 7) | + __gen_uint(values->number_of_16_vertex_batches_for_binning, 0, 3); + +} + +#define V3D41_VCM_CACHE_SIZE_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_VCM_CACHE_SIZE_unpack(const uint8_t * restrict cl, + struct V3D41_VCM_CACHE_SIZE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->number_of_16_vertex_batches_for_rendering = __gen_unpack_uint(cl, 12, 15); + values->number_of_16_vertex_batches_for_binning = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_TRANSFORM_FEEDBACK_BUFFER_opcode 73 +#define V3D41_TRANSFORM_FEEDBACK_BUFFER_header \ + .opcode = 73 + +struct V3D41_TRANSFORM_FEEDBACK_BUFFER { + uint32_t opcode; + __gen_address_type buffer_address; + uint32_t buffer_size_in_32_bit_words; + uint32_t buffer_number; +}; + +static inline void +V3D41_TRANSFORM_FEEDBACK_BUFFER_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TRANSFORM_FEEDBACK_BUFFER * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->buffer_size_in_32_bit_words, 2, 31) | + __gen_uint(values->buffer_number, 0, 1); + + cl[ 2] = __gen_uint(values->buffer_size_in_32_bit_words, 2, 31) >> 8; + + cl[ 3] = __gen_uint(values->buffer_size_in_32_bit_words, 2, 31) >> 16; + + cl[ 4] = __gen_uint(values->buffer_size_in_32_bit_words, 2, 31) >> 24; + + __gen_emit_reloc(data, &values->buffer_address); + cl[ 5] = __gen_address_offset(&values->buffer_address); + + cl[ 6] = __gen_address_offset(&values->buffer_address) >> 8; + + cl[ 7] = __gen_address_offset(&values->buffer_address) >> 16; + + cl[ 8] = __gen_address_offset(&values->buffer_address) >> 24; + +} + +#define V3D41_TRANSFORM_FEEDBACK_BUFFER_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_TRANSFORM_FEEDBACK_BUFFER_unpack(const uint8_t * restrict cl, + struct V3D41_TRANSFORM_FEEDBACK_BUFFER * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->buffer_address = __gen_unpack_address(cl, 40, 71); + values->buffer_size_in_32_bit_words = __gen_unpack_uint(cl, 10, 39); + values->buffer_number = __gen_unpack_uint(cl, 8, 9); +} +#endif + + +#define V3D41_TRANSFORM_FEEDBACK_SPECS_opcode 74 +#define V3D41_TRANSFORM_FEEDBACK_SPECS_header \ + .opcode = 74 + +struct V3D41_TRANSFORM_FEEDBACK_SPECS { + uint32_t opcode; + bool enable; + uint32_t number_of_16_bit_output_data_specs_following; +}; + +static inline void +V3D41_TRANSFORM_FEEDBACK_SPECS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TRANSFORM_FEEDBACK_SPECS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->enable, 7, 7) | + __gen_uint(values->number_of_16_bit_output_data_specs_following, 0, 4); + +} + +#define V3D41_TRANSFORM_FEEDBACK_SPECS_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_TRANSFORM_FEEDBACK_SPECS_unpack(const uint8_t * restrict cl, + struct V3D41_TRANSFORM_FEEDBACK_SPECS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->enable = __gen_unpack_uint(cl, 15, 15); + values->number_of_16_bit_output_data_specs_following = __gen_unpack_uint(cl, 8, 12); +} +#endif + + +#define V3D41_FLUSH_TRANSFORM_FEEDBACK_DATA_opcode 75 +#define V3D41_FLUSH_TRANSFORM_FEEDBACK_DATA_header\ + .opcode = 75 + +struct V3D41_FLUSH_TRANSFORM_FEEDBACK_DATA { + uint32_t opcode; +}; + +static inline void +V3D41_FLUSH_TRANSFORM_FEEDBACK_DATA_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_FLUSH_TRANSFORM_FEEDBACK_DATA * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_FLUSH_TRANSFORM_FEEDBACK_DATA_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_FLUSH_TRANSFORM_FEEDBACK_DATA_unpack(const uint8_t * restrict cl, + struct V3D41_FLUSH_TRANSFORM_FEEDBACK_DATA * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_header\ + + +struct V3D41_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC { + uint32_t first_shaded_vertex_value_to_output; + uint32_t number_of_consecutive_vertex_values_to_output_as_32_bit_values; + uint32_t output_buffer_to_write_to; + uint32_t stream_number; +}; + +static inline void +V3D41_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC * restrict values) +{ + assert(values->number_of_consecutive_vertex_values_to_output_as_32_bit_values >= 1); + cl[ 0] = __gen_uint(values->first_shaded_vertex_value_to_output, 0, 7); + + cl[ 1] = __gen_uint(values->number_of_consecutive_vertex_values_to_output_as_32_bit_values - 1, 0, 3) | + __gen_uint(values->output_buffer_to_write_to, 4, 5) | + __gen_uint(values->stream_number, 6, 7); + +} + +#define V3D41_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_unpack(const uint8_t * restrict cl, + struct V3D41_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC * restrict values) +{ + values->first_shaded_vertex_value_to_output = __gen_unpack_uint(cl, 0, 7); + values->number_of_consecutive_vertex_values_to_output_as_32_bit_values = __gen_unpack_uint(cl, 8, 11) + 1; + values->output_buffer_to_write_to = __gen_unpack_uint(cl, 12, 13); + values->stream_number = __gen_unpack_uint(cl, 14, 15); +} +#endif + + +#define V3D41_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_header\ + + +struct V3D41_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS { + __gen_address_type address; +}; + +static inline void +V3D41_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS * restrict values) +{ + __gen_emit_reloc(data, &values->address); + cl[ 0] = __gen_address_offset(&values->address); + + cl[ 1] = __gen_address_offset(&values->address) >> 8; + + cl[ 2] = __gen_address_offset(&values->address) >> 16; + + cl[ 3] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D41_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_length 4 +#ifdef __gen_unpack_address +static inline void +V3D41_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_unpack(const uint8_t * restrict cl, + struct V3D41_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS * restrict values) +{ + values->address = __gen_unpack_address(cl, 0, 31); +} +#endif + + +#define V3D41_STENCIL_CFG_opcode 80 +#define V3D41_STENCIL_CFG_header \ + .opcode = 80 + +struct V3D41_STENCIL_CFG { + uint32_t opcode; + uint32_t stencil_write_mask; + bool back_config; + bool front_config; + enum V3D41_Stencil_Op stencil_pass_op; + enum V3D41_Stencil_Op depth_test_fail_op; + enum V3D41_Stencil_Op stencil_test_fail_op; + enum V3D41_Compare_Function stencil_test_function; + uint32_t stencil_test_mask; + uint32_t stencil_ref_value; +}; + +static inline void +V3D41_STENCIL_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_STENCIL_CFG * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->stencil_ref_value, 0, 7); + + cl[ 2] = __gen_uint(values->stencil_test_mask, 0, 7); + + cl[ 3] = __gen_uint(values->depth_test_fail_op, 6, 8) | + __gen_uint(values->stencil_test_fail_op, 3, 5) | + __gen_uint(values->stencil_test_function, 0, 2); + + cl[ 4] = __gen_uint(values->back_config, 5, 5) | + __gen_uint(values->front_config, 4, 4) | + __gen_uint(values->stencil_pass_op, 1, 3) | + __gen_uint(values->depth_test_fail_op, 6, 8) >> 8; + + cl[ 5] = __gen_uint(values->stencil_write_mask, 0, 7); + +} + +#define V3D41_STENCIL_CFG_length 6 +#ifdef __gen_unpack_address +static inline void +V3D41_STENCIL_CFG_unpack(const uint8_t * restrict cl, + struct V3D41_STENCIL_CFG * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->stencil_write_mask = __gen_unpack_uint(cl, 40, 47); + values->back_config = __gen_unpack_uint(cl, 37, 37); + values->front_config = __gen_unpack_uint(cl, 36, 36); + values->stencil_pass_op = __gen_unpack_uint(cl, 33, 35); + values->depth_test_fail_op = __gen_unpack_uint(cl, 30, 32); + values->stencil_test_fail_op = __gen_unpack_uint(cl, 27, 29); + values->stencil_test_function = __gen_unpack_uint(cl, 24, 26); + values->stencil_test_mask = __gen_unpack_uint(cl, 16, 23); + values->stencil_ref_value = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D41_BLEND_ENABLES_opcode 83 +#define V3D41_BLEND_ENABLES_header \ + .opcode = 83 + +struct V3D41_BLEND_ENABLES { + uint32_t opcode; + uint32_t mask; +}; + +static inline void +V3D41_BLEND_ENABLES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_BLEND_ENABLES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->mask, 0, 7); + +} + +#define V3D41_BLEND_ENABLES_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_BLEND_ENABLES_unpack(const uint8_t * restrict cl, + struct V3D41_BLEND_ENABLES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->mask = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D41_BLEND_CFG_opcode 84 +#define V3D41_BLEND_CFG_header \ + .opcode = 84 + +struct V3D41_BLEND_CFG { + uint32_t opcode; + uint32_t render_target_mask; + enum V3D41_Blend_Factor color_blend_dst_factor; + enum V3D41_Blend_Factor color_blend_src_factor; + enum V3D41_Blend_Mode color_blend_mode; + enum V3D41_Blend_Factor alpha_blend_dst_factor; + enum V3D41_Blend_Factor alpha_blend_src_factor; + enum V3D41_Blend_Mode alpha_blend_mode; +}; + +static inline void +V3D41_BLEND_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_BLEND_CFG * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->alpha_blend_src_factor, 4, 7) | + __gen_uint(values->alpha_blend_mode, 0, 3); + + cl[ 2] = __gen_uint(values->color_blend_mode, 4, 7) | + __gen_uint(values->alpha_blend_dst_factor, 0, 3); + + cl[ 3] = __gen_uint(values->color_blend_dst_factor, 4, 7) | + __gen_uint(values->color_blend_src_factor, 0, 3); + + cl[ 4] = __gen_uint(values->render_target_mask, 0, 3); + +} + +#define V3D41_BLEND_CFG_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_BLEND_CFG_unpack(const uint8_t * restrict cl, + struct V3D41_BLEND_CFG * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->render_target_mask = __gen_unpack_uint(cl, 32, 35); + values->color_blend_dst_factor = __gen_unpack_uint(cl, 28, 31); + values->color_blend_src_factor = __gen_unpack_uint(cl, 24, 27); + values->color_blend_mode = __gen_unpack_uint(cl, 20, 23); + values->alpha_blend_dst_factor = __gen_unpack_uint(cl, 16, 19); + values->alpha_blend_src_factor = __gen_unpack_uint(cl, 12, 15); + values->alpha_blend_mode = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_BLEND_CONSTANT_COLOR_opcode 86 +#define V3D41_BLEND_CONSTANT_COLOR_header \ + .opcode = 86 + +struct V3D41_BLEND_CONSTANT_COLOR { + uint32_t opcode; + uint32_t alpha_f16; + uint32_t blue_f16; + uint32_t green_f16; + uint32_t red_f16; +}; + +static inline void +V3D41_BLEND_CONSTANT_COLOR_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_BLEND_CONSTANT_COLOR * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->red_f16, 0, 15); + + cl[ 2] = __gen_uint(values->red_f16, 0, 15) >> 8; + + cl[ 3] = __gen_uint(values->green_f16, 0, 15); + + cl[ 4] = __gen_uint(values->green_f16, 0, 15) >> 8; + + cl[ 5] = __gen_uint(values->blue_f16, 0, 15); + + cl[ 6] = __gen_uint(values->blue_f16, 0, 15) >> 8; + + cl[ 7] = __gen_uint(values->alpha_f16, 0, 15); + + cl[ 8] = __gen_uint(values->alpha_f16, 0, 15) >> 8; + +} + +#define V3D41_BLEND_CONSTANT_COLOR_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_BLEND_CONSTANT_COLOR_unpack(const uint8_t * restrict cl, + struct V3D41_BLEND_CONSTANT_COLOR * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->alpha_f16 = __gen_unpack_uint(cl, 56, 71); + values->blue_f16 = __gen_unpack_uint(cl, 40, 55); + values->green_f16 = __gen_unpack_uint(cl, 24, 39); + values->red_f16 = __gen_unpack_uint(cl, 8, 23); +} +#endif + + +#define V3D41_COLOR_WRITE_MASKS_opcode 87 +#define V3D41_COLOR_WRITE_MASKS_header \ + .opcode = 87 + +struct V3D41_COLOR_WRITE_MASKS { + uint32_t opcode; + uint32_t mask; +}; + +static inline void +V3D41_COLOR_WRITE_MASKS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_COLOR_WRITE_MASKS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->mask, sizeof(values->mask)); +} + +#define V3D41_COLOR_WRITE_MASKS_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_COLOR_WRITE_MASKS_unpack(const uint8_t * restrict cl, + struct V3D41_COLOR_WRITE_MASKS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->mask = __gen_unpack_uint(cl, 8, 39); +} +#endif + + +#define V3D41_ZERO_ALL_CENTROID_FLAGS_opcode 88 +#define V3D41_ZERO_ALL_CENTROID_FLAGS_header \ + .opcode = 88 + +struct V3D41_ZERO_ALL_CENTROID_FLAGS { + uint32_t opcode; +}; + +static inline void +V3D41_ZERO_ALL_CENTROID_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_ZERO_ALL_CENTROID_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_ZERO_ALL_CENTROID_FLAGS_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_ZERO_ALL_CENTROID_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D41_ZERO_ALL_CENTROID_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_CENTROID_FLAGS_opcode 89 +#define V3D41_CENTROID_FLAGS_header \ + .opcode = 89 + +struct V3D41_CENTROID_FLAGS { + uint32_t opcode; + uint32_t centroid_flags_for_varyings_v024; + enum V3D41_Varying_Flags_Action action_for_centroid_flags_of_higher_numbered_varyings; + enum V3D41_Varying_Flags_Action action_for_centroid_flags_of_lower_numbered_varyings; + uint32_t varying_offset_v0; +}; + +static inline void +V3D41_CENTROID_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_CENTROID_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->action_for_centroid_flags_of_higher_numbered_varyings, 6, 7) | + __gen_uint(values->action_for_centroid_flags_of_lower_numbered_varyings, 4, 5) | + __gen_uint(values->varying_offset_v0, 0, 3); + + cl[ 2] = __gen_uint(values->centroid_flags_for_varyings_v024, 0, 23); + + cl[ 3] = __gen_uint(values->centroid_flags_for_varyings_v024, 0, 23) >> 8; + + cl[ 4] = __gen_uint(values->centroid_flags_for_varyings_v024, 0, 23) >> 16; + +} + +#define V3D41_CENTROID_FLAGS_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_CENTROID_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D41_CENTROID_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->centroid_flags_for_varyings_v024 = __gen_unpack_uint(cl, 16, 39); + values->action_for_centroid_flags_of_higher_numbered_varyings = __gen_unpack_uint(cl, 14, 15); + values->action_for_centroid_flags_of_lower_numbered_varyings = __gen_unpack_uint(cl, 12, 13); + values->varying_offset_v0 = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_SAMPLE_STATE_opcode 91 +#define V3D41_SAMPLE_STATE_header \ + .opcode = 91 + +struct V3D41_SAMPLE_STATE { + uint32_t opcode; + float coverage; + uint32_t mask; +}; + +static inline void +V3D41_SAMPLE_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_SAMPLE_STATE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->mask, 0, 3); + + cl[ 2] = 0; + cl[ 3] = __gen_uint(fui(values->coverage) >> 16, 0, 15); + + cl[ 4] = __gen_uint(fui(values->coverage) >> 16, 0, 15) >> 8; + +} + +#define V3D41_SAMPLE_STATE_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_SAMPLE_STATE_unpack(const uint8_t * restrict cl, + struct V3D41_SAMPLE_STATE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->coverage = __gen_unpack_f187(cl, 24, 39); + values->mask = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_OCCLUSION_QUERY_COUNTER_opcode 92 +#define V3D41_OCCLUSION_QUERY_COUNTER_header \ + .opcode = 92 + +struct V3D41_OCCLUSION_QUERY_COUNTER { + uint32_t opcode; + __gen_address_type address; +}; + +static inline void +V3D41_OCCLUSION_QUERY_COUNTER_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_OCCLUSION_QUERY_COUNTER * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D41_OCCLUSION_QUERY_COUNTER_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_OCCLUSION_QUERY_COUNTER_unpack(const uint8_t * restrict cl, + struct V3D41_OCCLUSION_QUERY_COUNTER * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); +} +#endif + + +#define V3D41_CFG_BITS_opcode 96 +#define V3D41_CFG_BITS_header \ + .opcode = 96 + +struct V3D41_CFG_BITS { + uint32_t opcode; + bool direct3d_provoking_vertex; + bool direct3d_point_fill_mode; + bool blend_enable; + bool stencil_enable; + bool early_z_updates_enable; + bool early_z_enable; + bool z_updates_enable; + enum V3D41_Compare_Function depth_test_function; + bool direct3d_wireframe_triangles_mode; + uint32_t rasterizer_oversample_mode; + uint32_t line_rasterization; + bool enable_depth_offset; + bool clockwise_primitives; + bool enable_reverse_facing_primitive; + bool enable_forward_facing_primitive; +}; + +static inline void +V3D41_CFG_BITS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_CFG_BITS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->rasterizer_oversample_mode, 6, 7) | + __gen_uint(values->line_rasterization, 4, 5) | + __gen_uint(values->enable_depth_offset, 3, 3) | + __gen_uint(values->clockwise_primitives, 2, 2) | + __gen_uint(values->enable_reverse_facing_primitive, 1, 1) | + __gen_uint(values->enable_forward_facing_primitive, 0, 0); + + cl[ 2] = __gen_uint(values->z_updates_enable, 7, 7) | + __gen_uint(values->depth_test_function, 4, 6) | + __gen_uint(values->direct3d_wireframe_triangles_mode, 3, 3); + + cl[ 3] = __gen_uint(values->direct3d_provoking_vertex, 5, 5) | + __gen_uint(values->direct3d_point_fill_mode, 4, 4) | + __gen_uint(values->blend_enable, 3, 3) | + __gen_uint(values->stencil_enable, 2, 2) | + __gen_uint(values->early_z_updates_enable, 1, 1) | + __gen_uint(values->early_z_enable, 0, 0); + +} + +#define V3D41_CFG_BITS_length 4 +#ifdef __gen_unpack_address +static inline void +V3D41_CFG_BITS_unpack(const uint8_t * restrict cl, + struct V3D41_CFG_BITS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->direct3d_provoking_vertex = __gen_unpack_uint(cl, 29, 29); + values->direct3d_point_fill_mode = __gen_unpack_uint(cl, 28, 28); + values->blend_enable = __gen_unpack_uint(cl, 27, 27); + values->stencil_enable = __gen_unpack_uint(cl, 26, 26); + values->early_z_updates_enable = __gen_unpack_uint(cl, 25, 25); + values->early_z_enable = __gen_unpack_uint(cl, 24, 24); + values->z_updates_enable = __gen_unpack_uint(cl, 23, 23); + values->depth_test_function = __gen_unpack_uint(cl, 20, 22); + values->direct3d_wireframe_triangles_mode = __gen_unpack_uint(cl, 19, 19); + values->rasterizer_oversample_mode = __gen_unpack_uint(cl, 14, 15); + values->line_rasterization = __gen_unpack_uint(cl, 12, 13); + values->enable_depth_offset = __gen_unpack_uint(cl, 11, 11); + values->clockwise_primitives = __gen_unpack_uint(cl, 10, 10); + values->enable_reverse_facing_primitive = __gen_unpack_uint(cl, 9, 9); + values->enable_forward_facing_primitive = __gen_unpack_uint(cl, 8, 8); +} +#endif + + +#define V3D41_ZERO_ALL_FLAT_SHADE_FLAGS_opcode 97 +#define V3D41_ZERO_ALL_FLAT_SHADE_FLAGS_header \ + .opcode = 97 + +struct V3D41_ZERO_ALL_FLAT_SHADE_FLAGS { + uint32_t opcode; +}; + +static inline void +V3D41_ZERO_ALL_FLAT_SHADE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_ZERO_ALL_FLAT_SHADE_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_ZERO_ALL_FLAT_SHADE_FLAGS_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_ZERO_ALL_FLAT_SHADE_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D41_ZERO_ALL_FLAT_SHADE_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_FLAT_SHADE_FLAGS_opcode 98 +#define V3D41_FLAT_SHADE_FLAGS_header \ + .opcode = 98 + +struct V3D41_FLAT_SHADE_FLAGS { + uint32_t opcode; + uint32_t flat_shade_flags_for_varyings_v024; + enum V3D41_Varying_Flags_Action action_for_flat_shade_flags_of_higher_numbered_varyings; + enum V3D41_Varying_Flags_Action action_for_flat_shade_flags_of_lower_numbered_varyings; + uint32_t varying_offset_v0; +}; + +static inline void +V3D41_FLAT_SHADE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_FLAT_SHADE_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->action_for_flat_shade_flags_of_higher_numbered_varyings, 6, 7) | + __gen_uint(values->action_for_flat_shade_flags_of_lower_numbered_varyings, 4, 5) | + __gen_uint(values->varying_offset_v0, 0, 3); + + cl[ 2] = __gen_uint(values->flat_shade_flags_for_varyings_v024, 0, 23); + + cl[ 3] = __gen_uint(values->flat_shade_flags_for_varyings_v024, 0, 23) >> 8; + + cl[ 4] = __gen_uint(values->flat_shade_flags_for_varyings_v024, 0, 23) >> 16; + +} + +#define V3D41_FLAT_SHADE_FLAGS_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_FLAT_SHADE_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D41_FLAT_SHADE_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->flat_shade_flags_for_varyings_v024 = __gen_unpack_uint(cl, 16, 39); + values->action_for_flat_shade_flags_of_higher_numbered_varyings = __gen_unpack_uint(cl, 14, 15); + values->action_for_flat_shade_flags_of_lower_numbered_varyings = __gen_unpack_uint(cl, 12, 13); + values->varying_offset_v0 = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_ZERO_ALL_NON_PERSPECTIVE_FLAGS_opcode 99 +#define V3D41_ZERO_ALL_NON_PERSPECTIVE_FLAGS_header\ + .opcode = 99 + +struct V3D41_ZERO_ALL_NON_PERSPECTIVE_FLAGS { + uint32_t opcode; +}; + +static inline void +V3D41_ZERO_ALL_NON_PERSPECTIVE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_ZERO_ALL_NON_PERSPECTIVE_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_ZERO_ALL_NON_PERSPECTIVE_FLAGS_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_ZERO_ALL_NON_PERSPECTIVE_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D41_ZERO_ALL_NON_PERSPECTIVE_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_NON_PERSPECTIVE_FLAGS_opcode 100 +#define V3D41_NON_PERSPECTIVE_FLAGS_header \ + .opcode = 100 + +struct V3D41_NON_PERSPECTIVE_FLAGS { + uint32_t opcode; + uint32_t non_perspective_flags_for_varyings_v024; + enum V3D41_Varying_Flags_Action action_for_non_perspective_flags_of_higher_numbered_varyings; + enum V3D41_Varying_Flags_Action action_for_non_perspective_flags_of_lower_numbered_varyings; + uint32_t varying_offset_v0; +}; + +static inline void +V3D41_NON_PERSPECTIVE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_NON_PERSPECTIVE_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->action_for_non_perspective_flags_of_higher_numbered_varyings, 6, 7) | + __gen_uint(values->action_for_non_perspective_flags_of_lower_numbered_varyings, 4, 5) | + __gen_uint(values->varying_offset_v0, 0, 3); + + cl[ 2] = __gen_uint(values->non_perspective_flags_for_varyings_v024, 0, 23); + + cl[ 3] = __gen_uint(values->non_perspective_flags_for_varyings_v024, 0, 23) >> 8; + + cl[ 4] = __gen_uint(values->non_perspective_flags_for_varyings_v024, 0, 23) >> 16; + +} + +#define V3D41_NON_PERSPECTIVE_FLAGS_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_NON_PERSPECTIVE_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D41_NON_PERSPECTIVE_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->non_perspective_flags_for_varyings_v024 = __gen_unpack_uint(cl, 16, 39); + values->action_for_non_perspective_flags_of_higher_numbered_varyings = __gen_unpack_uint(cl, 14, 15); + values->action_for_non_perspective_flags_of_lower_numbered_varyings = __gen_unpack_uint(cl, 12, 13); + values->varying_offset_v0 = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_POINT_SIZE_opcode 104 +#define V3D41_POINT_SIZE_header \ + .opcode = 104 + +struct V3D41_POINT_SIZE { + uint32_t opcode; + float point_size; +}; + +static inline void +V3D41_POINT_SIZE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_POINT_SIZE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->point_size, sizeof(values->point_size)); +} + +#define V3D41_POINT_SIZE_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_POINT_SIZE_unpack(const uint8_t * restrict cl, + struct V3D41_POINT_SIZE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->point_size = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D41_LINE_WIDTH_opcode 105 +#define V3D41_LINE_WIDTH_header \ + .opcode = 105 + +struct V3D41_LINE_WIDTH { + uint32_t opcode; + float line_width; +}; + +static inline void +V3D41_LINE_WIDTH_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_LINE_WIDTH * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->line_width, sizeof(values->line_width)); +} + +#define V3D41_LINE_WIDTH_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_LINE_WIDTH_unpack(const uint8_t * restrict cl, + struct V3D41_LINE_WIDTH * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->line_width = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D41_DEPTH_OFFSET_opcode 106 +#define V3D41_DEPTH_OFFSET_header \ + .opcode = 106 + +struct V3D41_DEPTH_OFFSET { + uint32_t opcode; + float limit; + float depth_offset_units; + float depth_offset_factor; +}; + +static inline void +V3D41_DEPTH_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_DEPTH_OFFSET * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(fui(values->depth_offset_factor) >> 16, 0, 15); + + cl[ 2] = __gen_uint(fui(values->depth_offset_factor) >> 16, 0, 15) >> 8; + + cl[ 3] = __gen_uint(fui(values->depth_offset_units) >> 16, 0, 15); + + cl[ 4] = __gen_uint(fui(values->depth_offset_units) >> 16, 0, 15) >> 8; + + + memcpy(&cl[5], &values->limit, sizeof(values->limit)); +} + +#define V3D41_DEPTH_OFFSET_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_DEPTH_OFFSET_unpack(const uint8_t * restrict cl, + struct V3D41_DEPTH_OFFSET * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->limit = __gen_unpack_float(cl, 40, 71); + values->depth_offset_units = __gen_unpack_f187(cl, 24, 39); + values->depth_offset_factor = __gen_unpack_f187(cl, 8, 23); +} +#endif + + +#define V3D41_CLIP_WINDOW_opcode 107 +#define V3D41_CLIP_WINDOW_header \ + .opcode = 107 + +struct V3D41_CLIP_WINDOW { + uint32_t opcode; + uint32_t clip_window_height_in_pixels; + uint32_t clip_window_width_in_pixels; + uint32_t clip_window_bottom_pixel_coordinate; + uint32_t clip_window_left_pixel_coordinate; +}; + +static inline void +V3D41_CLIP_WINDOW_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_CLIP_WINDOW * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->clip_window_left_pixel_coordinate, 0, 15); + + cl[ 2] = __gen_uint(values->clip_window_left_pixel_coordinate, 0, 15) >> 8; + + cl[ 3] = __gen_uint(values->clip_window_bottom_pixel_coordinate, 0, 15); + + cl[ 4] = __gen_uint(values->clip_window_bottom_pixel_coordinate, 0, 15) >> 8; + + cl[ 5] = __gen_uint(values->clip_window_width_in_pixels, 0, 15); + + cl[ 6] = __gen_uint(values->clip_window_width_in_pixels, 0, 15) >> 8; + + cl[ 7] = __gen_uint(values->clip_window_height_in_pixels, 0, 15); + + cl[ 8] = __gen_uint(values->clip_window_height_in_pixels, 0, 15) >> 8; + +} + +#define V3D41_CLIP_WINDOW_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_CLIP_WINDOW_unpack(const uint8_t * restrict cl, + struct V3D41_CLIP_WINDOW * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->clip_window_height_in_pixels = __gen_unpack_uint(cl, 56, 71); + values->clip_window_width_in_pixels = __gen_unpack_uint(cl, 40, 55); + values->clip_window_bottom_pixel_coordinate = __gen_unpack_uint(cl, 24, 39); + values->clip_window_left_pixel_coordinate = __gen_unpack_uint(cl, 8, 23); +} +#endif + + +#define V3D41_VIEWPORT_OFFSET_opcode 108 +#define V3D41_VIEWPORT_OFFSET_header \ + .opcode = 108 + +struct V3D41_VIEWPORT_OFFSET { + uint32_t opcode; + uint32_t coarse_y; + float viewport_centre_y_coordinate; + uint32_t coarse_x; + float viewport_centre_x_coordinate; +}; + +static inline void +V3D41_VIEWPORT_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_VIEWPORT_OFFSET * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_sfixed(values->viewport_centre_x_coordinate, 0, 21, 8); + + cl[ 2] = __gen_sfixed(values->viewport_centre_x_coordinate, 0, 21, 8) >> 8; + + cl[ 3] = __gen_uint(values->coarse_x, 6, 15) | + __gen_sfixed(values->viewport_centre_x_coordinate, 0, 21, 8) >> 16; + + cl[ 4] = __gen_uint(values->coarse_x, 6, 15) >> 8; + + cl[ 5] = __gen_sfixed(values->viewport_centre_y_coordinate, 0, 21, 8); + + cl[ 6] = __gen_sfixed(values->viewport_centre_y_coordinate, 0, 21, 8) >> 8; + + cl[ 7] = __gen_uint(values->coarse_y, 6, 15) | + __gen_sfixed(values->viewport_centre_y_coordinate, 0, 21, 8) >> 16; + + cl[ 8] = __gen_uint(values->coarse_y, 6, 15) >> 8; + +} + +#define V3D41_VIEWPORT_OFFSET_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_VIEWPORT_OFFSET_unpack(const uint8_t * restrict cl, + struct V3D41_VIEWPORT_OFFSET * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->coarse_y = __gen_unpack_uint(cl, 62, 71); + values->viewport_centre_y_coordinate = __gen_unpack_sfixed(cl, 40, 61, 8); + values->coarse_x = __gen_unpack_uint(cl, 30, 39); + values->viewport_centre_x_coordinate = __gen_unpack_sfixed(cl, 8, 29, 8); +} +#endif + + +#define V3D41_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_opcode 109 +#define V3D41_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_header\ + .opcode = 109 + +struct V3D41_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES { + uint32_t opcode; + float maximum_zw; + float minimum_zw; +}; + +static inline void +V3D41_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->minimum_zw, sizeof(values->minimum_zw)); + + memcpy(&cl[5], &values->maximum_zw, sizeof(values->maximum_zw)); +} + +#define V3D41_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_unpack(const uint8_t * restrict cl, + struct V3D41_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->maximum_zw = __gen_unpack_float(cl, 40, 71); + values->minimum_zw = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D41_CLIPPER_XY_SCALING_opcode 110 +#define V3D41_CLIPPER_XY_SCALING_header \ + .opcode = 110 + +struct V3D41_CLIPPER_XY_SCALING { + uint32_t opcode; + float viewport_half_height_in_1_256th_of_pixel; + float viewport_half_width_in_1_256th_of_pixel; +}; + +static inline void +V3D41_CLIPPER_XY_SCALING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_CLIPPER_XY_SCALING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->viewport_half_width_in_1_256th_of_pixel, sizeof(values->viewport_half_width_in_1_256th_of_pixel)); + + memcpy(&cl[5], &values->viewport_half_height_in_1_256th_of_pixel, sizeof(values->viewport_half_height_in_1_256th_of_pixel)); +} + +#define V3D41_CLIPPER_XY_SCALING_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_CLIPPER_XY_SCALING_unpack(const uint8_t * restrict cl, + struct V3D41_CLIPPER_XY_SCALING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->viewport_half_height_in_1_256th_of_pixel = __gen_unpack_float(cl, 40, 71); + values->viewport_half_width_in_1_256th_of_pixel = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D41_CLIPPER_Z_SCALE_AND_OFFSET_opcode 111 +#define V3D41_CLIPPER_Z_SCALE_AND_OFFSET_header \ + .opcode = 111 + +struct V3D41_CLIPPER_Z_SCALE_AND_OFFSET { + uint32_t opcode; + float viewport_z_offset_zc_to_zs; + float viewport_z_scale_zc_to_zs; +}; + +static inline void +V3D41_CLIPPER_Z_SCALE_AND_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_CLIPPER_Z_SCALE_AND_OFFSET * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->viewport_z_scale_zc_to_zs, sizeof(values->viewport_z_scale_zc_to_zs)); + + memcpy(&cl[5], &values->viewport_z_offset_zc_to_zs, sizeof(values->viewport_z_offset_zc_to_zs)); +} + +#define V3D41_CLIPPER_Z_SCALE_AND_OFFSET_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_CLIPPER_Z_SCALE_AND_OFFSET_unpack(const uint8_t * restrict cl, + struct V3D41_CLIPPER_Z_SCALE_AND_OFFSET * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->viewport_z_offset_zc_to_zs = __gen_unpack_float(cl, 40, 71); + values->viewport_z_scale_zc_to_zs = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D41_NUMBER_OF_LAYERS_opcode 119 +#define V3D41_NUMBER_OF_LAYERS_header \ + .opcode = 119 + +struct V3D41_NUMBER_OF_LAYERS { + uint32_t opcode; + uint32_t number_of_layers; +}; + +static inline void +V3D41_NUMBER_OF_LAYERS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_NUMBER_OF_LAYERS * restrict values) +{ + assert(values->number_of_layers >= 1); + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->number_of_layers - 1, 0, 7); + +} + +#define V3D41_NUMBER_OF_LAYERS_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_NUMBER_OF_LAYERS_unpack(const uint8_t * restrict cl, + struct V3D41_NUMBER_OF_LAYERS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->number_of_layers = __gen_unpack_uint(cl, 8, 15) + 1; +} +#endif + + +#define V3D41_TILE_BINNING_MODE_CFG_opcode 120 +#define V3D41_TILE_BINNING_MODE_CFG_header \ + .opcode = 120 + +struct V3D41_TILE_BINNING_MODE_CFG { + uint32_t opcode; + uint32_t height_in_pixels; + uint32_t width_in_pixels; + bool double_buffer_in_non_ms_mode; + bool multisample_mode_4x; + uint32_t maximum_bpp_of_all_render_targets; +#define RENDER_TARGET_MAXIMUM_32BPP 0 +#define RENDER_TARGET_MAXIMUM_64BPP 1 +#define RENDER_TARGET_MAXIMUM_128BPP 2 + uint32_t number_of_render_targets; + uint32_t tile_allocation_block_size; +#define TILE_ALLOCATION_BLOCK_SIZE_64B 0 +#define TILE_ALLOCATION_BLOCK_SIZE_128B 1 +#define TILE_ALLOCATION_BLOCK_SIZE_256B 2 + uint32_t tile_allocation_initial_block_size; +#define TILE_ALLOCATION_INITIAL_BLOCK_SIZE_64B 0 +#define TILE_ALLOCATION_INITIAL_BLOCK_SIZE_128B 1 +#define TILE_ALLOCATION_INITIAL_BLOCK_SIZE_256B 2 +}; + +static inline void +V3D41_TILE_BINNING_MODE_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_BINNING_MODE_CFG * restrict values) +{ + assert(values->height_in_pixels >= 1); + assert(values->width_in_pixels >= 1); + assert(values->number_of_render_targets >= 1); + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->tile_allocation_block_size, 4, 5) | + __gen_uint(values->tile_allocation_initial_block_size, 2, 3); + + cl[ 2] = __gen_uint(values->double_buffer_in_non_ms_mode, 7, 7) | + __gen_uint(values->multisample_mode_4x, 6, 6) | + __gen_uint(values->maximum_bpp_of_all_render_targets, 4, 5) | + __gen_uint(values->number_of_render_targets - 1, 0, 3); + + cl[ 3] = 0; + cl[ 4] = 0; + cl[ 5] = __gen_uint(values->width_in_pixels - 1, 0, 11); + + cl[ 6] = __gen_uint(values->width_in_pixels - 1, 0, 11) >> 8; + + cl[ 7] = __gen_uint(values->height_in_pixels - 1, 0, 11); + + cl[ 8] = __gen_uint(values->height_in_pixels - 1, 0, 11) >> 8; + +} + +#define V3D41_TILE_BINNING_MODE_CFG_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_BINNING_MODE_CFG_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_BINNING_MODE_CFG * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->height_in_pixels = __gen_unpack_uint(cl, 56, 67) + 1; + values->width_in_pixels = __gen_unpack_uint(cl, 40, 51) + 1; + values->double_buffer_in_non_ms_mode = __gen_unpack_uint(cl, 23, 23); + values->multisample_mode_4x = __gen_unpack_uint(cl, 22, 22); + values->maximum_bpp_of_all_render_targets = __gen_unpack_uint(cl, 20, 21); + values->number_of_render_targets = __gen_unpack_uint(cl, 16, 19) + 1; + values->tile_allocation_block_size = __gen_unpack_uint(cl, 12, 13); + values->tile_allocation_initial_block_size = __gen_unpack_uint(cl, 10, 11); +} +#endif + + +#define V3D41_TILE_RENDERING_MODE_CFG_COMMON_opcode 121 +#define V3D41_TILE_RENDERING_MODE_CFG_COMMON_header\ + .opcode = 121, \ + .sub_id = 0 + +struct V3D41_TILE_RENDERING_MODE_CFG_COMMON { + uint32_t opcode; + uint32_t pad; + bool early_depth_stencil_clear; + enum V3D41_Internal_Depth_Type internal_depth_type; + bool early_z_disable; + uint32_t early_z_test_and_update_direction; +#define EARLY_Z_DIRECTION_LT_LE 0 +#define EARLY_Z_DIRECTION_GT_GE 1 + bool double_buffer_in_non_ms_mode; + bool multisample_mode_4x; + enum V3D41_Internal_BPP maximum_bpp_of_all_render_targets; + uint32_t image_height_pixels; + uint32_t image_width_pixels; + uint32_t number_of_render_targets; + uint32_t sub_id; +}; + +static inline void +V3D41_TILE_RENDERING_MODE_CFG_COMMON_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_RENDERING_MODE_CFG_COMMON * restrict values) +{ + assert(values->number_of_render_targets >= 1); + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->number_of_render_targets - 1, 4, 7) | + __gen_uint(values->sub_id, 0, 3); + + cl[ 2] = __gen_uint(values->image_width_pixels, 0, 15); + + cl[ 3] = __gen_uint(values->image_width_pixels, 0, 15) >> 8; + + cl[ 4] = __gen_uint(values->image_height_pixels, 0, 15); + + cl[ 5] = __gen_uint(values->image_height_pixels, 0, 15) >> 8; + + cl[ 6] = __gen_uint(values->internal_depth_type, 7, 10) | + __gen_uint(values->early_z_disable, 6, 6) | + __gen_uint(values->early_z_test_and_update_direction, 5, 5) | + __gen_uint(values->double_buffer_in_non_ms_mode, 3, 3) | + __gen_uint(values->multisample_mode_4x, 2, 2) | + __gen_uint(values->maximum_bpp_of_all_render_targets, 0, 1); + + cl[ 7] = __gen_uint(values->pad, 4, 15) | + __gen_uint(values->early_depth_stencil_clear, 3, 3) | + __gen_uint(values->internal_depth_type, 7, 10) >> 8; + + cl[ 8] = __gen_uint(values->pad, 4, 15) >> 8; + +} + +#define V3D41_TILE_RENDERING_MODE_CFG_COMMON_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_RENDERING_MODE_CFG_COMMON_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_RENDERING_MODE_CFG_COMMON * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->pad = __gen_unpack_uint(cl, 60, 71); + values->early_depth_stencil_clear = __gen_unpack_uint(cl, 59, 59); + values->internal_depth_type = __gen_unpack_uint(cl, 55, 58); + values->early_z_disable = __gen_unpack_uint(cl, 54, 54); + values->early_z_test_and_update_direction = __gen_unpack_uint(cl, 53, 53); + values->double_buffer_in_non_ms_mode = __gen_unpack_uint(cl, 51, 51); + values->multisample_mode_4x = __gen_unpack_uint(cl, 50, 50); + values->maximum_bpp_of_all_render_targets = __gen_unpack_uint(cl, 48, 49); + values->image_height_pixels = __gen_unpack_uint(cl, 32, 47); + values->image_width_pixels = __gen_unpack_uint(cl, 16, 31); + values->number_of_render_targets = __gen_unpack_uint(cl, 12, 15) + 1; + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_TILE_RENDERING_MODE_CFG_COLOR_opcode 121 +#define V3D41_TILE_RENDERING_MODE_CFG_COLOR_header\ + .opcode = 121, \ + .sub_id = 1 + +struct V3D41_TILE_RENDERING_MODE_CFG_COLOR { + uint32_t opcode; + uint32_t pad; + enum V3D41_Render_Target_Clamp render_target_3_clamp; + enum V3D41_Internal_Type render_target_3_internal_type; + enum V3D41_Internal_BPP render_target_3_internal_bpp; + enum V3D41_Render_Target_Clamp render_target_2_clamp; + enum V3D41_Internal_Type render_target_2_internal_type; + enum V3D41_Internal_BPP render_target_2_internal_bpp; + enum V3D41_Render_Target_Clamp render_target_1_clamp; + enum V3D41_Internal_Type render_target_1_internal_type; + enum V3D41_Internal_BPP render_target_1_internal_bpp; + enum V3D41_Render_Target_Clamp render_target_0_clamp; + enum V3D41_Internal_Type render_target_0_internal_type; + enum V3D41_Internal_BPP render_target_0_internal_bpp; + uint32_t sub_id; +}; + +static inline void +V3D41_TILE_RENDERING_MODE_CFG_COLOR_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_RENDERING_MODE_CFG_COLOR * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->render_target_0_internal_type, 6, 9) | + __gen_uint(values->render_target_0_internal_bpp, 4, 5) | + __gen_uint(values->sub_id, 0, 3); + + cl[ 2] = __gen_uint(values->render_target_1_internal_type, 6, 9) | + __gen_uint(values->render_target_1_internal_bpp, 4, 5) | + __gen_uint(values->render_target_0_clamp, 2, 3) | + __gen_uint(values->render_target_0_internal_type, 6, 9) >> 8; + + cl[ 3] = __gen_uint(values->render_target_2_internal_type, 6, 9) | + __gen_uint(values->render_target_2_internal_bpp, 4, 5) | + __gen_uint(values->render_target_1_clamp, 2, 3) | + __gen_uint(values->render_target_1_internal_type, 6, 9) >> 8; + + cl[ 4] = __gen_uint(values->render_target_3_internal_type, 6, 9) | + __gen_uint(values->render_target_3_internal_bpp, 4, 5) | + __gen_uint(values->render_target_2_clamp, 2, 3) | + __gen_uint(values->render_target_2_internal_type, 6, 9) >> 8; + + cl[ 5] = __gen_uint(values->pad, 2, 29) | + __gen_uint(values->render_target_3_clamp, 0, 1) | + __gen_uint(values->render_target_3_internal_type, 6, 9) >> 8; + + cl[ 6] = __gen_uint(values->pad, 2, 29) >> 8; + + cl[ 7] = __gen_uint(values->pad, 2, 29) >> 16; + + cl[ 8] = __gen_uint(values->pad, 2, 29) >> 24; + +} + +#define V3D41_TILE_RENDERING_MODE_CFG_COLOR_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_RENDERING_MODE_CFG_COLOR_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_RENDERING_MODE_CFG_COLOR * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->pad = __gen_unpack_uint(cl, 42, 69); + values->render_target_3_clamp = __gen_unpack_uint(cl, 40, 41); + values->render_target_3_internal_type = __gen_unpack_uint(cl, 38, 41); + values->render_target_3_internal_bpp = __gen_unpack_uint(cl, 36, 37); + values->render_target_2_clamp = __gen_unpack_uint(cl, 34, 35); + values->render_target_2_internal_type = __gen_unpack_uint(cl, 30, 33); + values->render_target_2_internal_bpp = __gen_unpack_uint(cl, 28, 29); + values->render_target_1_clamp = __gen_unpack_uint(cl, 26, 27); + values->render_target_1_internal_type = __gen_unpack_uint(cl, 22, 25); + values->render_target_1_internal_bpp = __gen_unpack_uint(cl, 20, 21); + values->render_target_0_clamp = __gen_unpack_uint(cl, 18, 19); + values->render_target_0_internal_type = __gen_unpack_uint(cl, 14, 17); + values->render_target_0_internal_bpp = __gen_unpack_uint(cl, 12, 13); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_opcode 121 +#define V3D41_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_header\ + .opcode = 121, \ + .sub_id = 2 + +struct V3D41_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES { + uint32_t opcode; + uint32_t unused; + float z_clear_value; + uint32_t stencil_clear_value; + uint32_t sub_id; +}; + +static inline void +V3D41_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->sub_id, 0, 3); + + cl[ 2] = __gen_uint(values->stencil_clear_value, 0, 7); + + + memcpy(&cl[3], &values->z_clear_value, sizeof(values->z_clear_value)); + cl[ 7] = __gen_uint(values->unused, 0, 15); + + cl[ 8] = __gen_uint(values->unused, 0, 15) >> 8; + +} + +#define V3D41_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->unused = __gen_unpack_uint(cl, 56, 71); + values->z_clear_value = __gen_unpack_float(cl, 24, 55); + values->stencil_clear_value = __gen_unpack_uint(cl, 16, 23); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_opcode 121 +#define V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_header\ + .opcode = 121, \ + .sub_id = 3 + +struct V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1 { + uint32_t opcode; + uint32_t clear_color_next_24_bits; + uint32_t clear_color_low_32_bits; + uint32_t render_target_number; + uint32_t sub_id; +}; + +static inline void +V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1 * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->render_target_number, 4, 7) | + __gen_uint(values->sub_id, 0, 3); + + + memcpy(&cl[2], &values->clear_color_low_32_bits, sizeof(values->clear_color_low_32_bits)); + cl[ 6] = __gen_uint(values->clear_color_next_24_bits, 0, 23); + + cl[ 7] = __gen_uint(values->clear_color_next_24_bits, 0, 23) >> 8; + + cl[ 8] = __gen_uint(values->clear_color_next_24_bits, 0, 23) >> 16; + +} + +#define V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1 * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->clear_color_next_24_bits = __gen_unpack_uint(cl, 48, 71); + values->clear_color_low_32_bits = __gen_unpack_uint(cl, 16, 47); + values->render_target_number = __gen_unpack_uint(cl, 12, 15); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_opcode 121 +#define V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_header\ + .opcode = 121, \ + .sub_id = 4 + +struct V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2 { + uint32_t opcode; + uint32_t clear_color_mid_high_24_bits; + uint32_t clear_color_mid_low_32_bits; + uint32_t render_target_number; + uint32_t sub_id; +}; + +static inline void +V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2 * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->render_target_number, 4, 7) | + __gen_uint(values->sub_id, 0, 3); + + + memcpy(&cl[2], &values->clear_color_mid_low_32_bits, sizeof(values->clear_color_mid_low_32_bits)); + cl[ 6] = __gen_uint(values->clear_color_mid_high_24_bits, 0, 23); + + cl[ 7] = __gen_uint(values->clear_color_mid_high_24_bits, 0, 23) >> 8; + + cl[ 8] = __gen_uint(values->clear_color_mid_high_24_bits, 0, 23) >> 16; + +} + +#define V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2 * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->clear_color_mid_high_24_bits = __gen_unpack_uint(cl, 48, 71); + values->clear_color_mid_low_32_bits = __gen_unpack_uint(cl, 16, 47); + values->render_target_number = __gen_unpack_uint(cl, 12, 15); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_opcode 121 +#define V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_header\ + .opcode = 121, \ + .sub_id = 5 + +struct V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3 { + uint32_t opcode; + uint32_t pad; + uint32_t uif_padded_height_in_uif_blocks; + uint32_t raster_row_stride_or_image_height_in_pixels; + uint32_t clear_color_high_16_bits; + uint32_t render_target_number; + uint32_t sub_id; +}; + +static inline void +V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3 * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->render_target_number, 4, 7) | + __gen_uint(values->sub_id, 0, 3); + + cl[ 2] = __gen_uint(values->clear_color_high_16_bits, 0, 15); + + cl[ 3] = __gen_uint(values->clear_color_high_16_bits, 0, 15) >> 8; + + cl[ 4] = __gen_uint(values->raster_row_stride_or_image_height_in_pixels, 0, 15); + + cl[ 5] = __gen_uint(values->raster_row_stride_or_image_height_in_pixels, 0, 15) >> 8; + + cl[ 6] = __gen_uint(values->uif_padded_height_in_uif_blocks, 0, 12); + + cl[ 7] = __gen_uint(values->pad, 5, 15) | + __gen_uint(values->uif_padded_height_in_uif_blocks, 0, 12) >> 8; + + cl[ 8] = __gen_uint(values->pad, 5, 15) >> 8; + +} + +#define V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3 * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->pad = __gen_unpack_uint(cl, 61, 71); + values->uif_padded_height_in_uif_blocks = __gen_unpack_uint(cl, 48, 60); + values->raster_row_stride_or_image_height_in_pixels = __gen_unpack_uint(cl, 32, 47); + values->clear_color_high_16_bits = __gen_unpack_uint(cl, 16, 31); + values->render_target_number = __gen_unpack_uint(cl, 12, 15); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_TILE_COORDINATES_opcode 124 +#define V3D41_TILE_COORDINATES_header \ + .opcode = 124 + +struct V3D41_TILE_COORDINATES { + uint32_t opcode; + uint32_t tile_row_number; + uint32_t tile_column_number; +}; + +static inline void +V3D41_TILE_COORDINATES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_COORDINATES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->tile_column_number, 0, 11); + + cl[ 2] = __gen_uint(values->tile_row_number, 4, 15) | + __gen_uint(values->tile_column_number, 0, 11) >> 8; + + cl[ 3] = __gen_uint(values->tile_row_number, 4, 15) >> 8; + +} + +#define V3D41_TILE_COORDINATES_length 4 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_COORDINATES_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_COORDINATES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->tile_row_number = __gen_unpack_uint(cl, 20, 31); + values->tile_column_number = __gen_unpack_uint(cl, 8, 19); +} +#endif + + +#define V3D41_MULTICORE_RENDERING_SUPERTILE_CFG_opcode 122 +#define V3D41_MULTICORE_RENDERING_SUPERTILE_CFG_header\ + .opcode = 122 + +struct V3D41_MULTICORE_RENDERING_SUPERTILE_CFG { + uint32_t opcode; + uint32_t number_of_bin_tile_lists; + bool supertile_raster_order; + bool multicore_enable; + uint32_t total_frame_height_in_tiles; + uint32_t total_frame_width_in_tiles; + uint32_t total_frame_height_in_supertiles; + uint32_t total_frame_width_in_supertiles; + uint32_t supertile_height_in_tiles; + uint32_t supertile_width_in_tiles; +}; + +static inline void +V3D41_MULTICORE_RENDERING_SUPERTILE_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_MULTICORE_RENDERING_SUPERTILE_CFG * restrict values) +{ + assert(values->number_of_bin_tile_lists >= 1); + assert(values->supertile_height_in_tiles >= 1); + assert(values->supertile_width_in_tiles >= 1); + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->supertile_width_in_tiles - 1, 0, 7); + + cl[ 2] = __gen_uint(values->supertile_height_in_tiles - 1, 0, 7); + + cl[ 3] = __gen_uint(values->total_frame_width_in_supertiles, 0, 7); + + cl[ 4] = __gen_uint(values->total_frame_height_in_supertiles, 0, 7); + + cl[ 5] = __gen_uint(values->total_frame_width_in_tiles, 0, 11); + + cl[ 6] = __gen_uint(values->total_frame_height_in_tiles, 4, 15) | + __gen_uint(values->total_frame_width_in_tiles, 0, 11) >> 8; + + cl[ 7] = __gen_uint(values->total_frame_height_in_tiles, 4, 15) >> 8; + + cl[ 8] = __gen_uint(values->number_of_bin_tile_lists - 1, 5, 7) | + __gen_uint(values->supertile_raster_order, 4, 4) | + __gen_uint(values->multicore_enable, 0, 0); + +} + +#define V3D41_MULTICORE_RENDERING_SUPERTILE_CFG_length 9 +#ifdef __gen_unpack_address +static inline void +V3D41_MULTICORE_RENDERING_SUPERTILE_CFG_unpack(const uint8_t * restrict cl, + struct V3D41_MULTICORE_RENDERING_SUPERTILE_CFG * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->number_of_bin_tile_lists = __gen_unpack_uint(cl, 69, 71) + 1; + values->supertile_raster_order = __gen_unpack_uint(cl, 68, 68); + values->multicore_enable = __gen_unpack_uint(cl, 64, 64); + values->total_frame_height_in_tiles = __gen_unpack_uint(cl, 52, 63); + values->total_frame_width_in_tiles = __gen_unpack_uint(cl, 40, 51); + values->total_frame_height_in_supertiles = __gen_unpack_uint(cl, 32, 39); + values->total_frame_width_in_supertiles = __gen_unpack_uint(cl, 24, 31); + values->supertile_height_in_tiles = __gen_unpack_uint(cl, 16, 23) + 1; + values->supertile_width_in_tiles = __gen_unpack_uint(cl, 8, 15) + 1; +} +#endif + + +#define V3D41_MULTICORE_RENDERING_TILE_LIST_SET_BASE_opcode 123 +#define V3D41_MULTICORE_RENDERING_TILE_LIST_SET_BASE_header\ + .opcode = 123 + +struct V3D41_MULTICORE_RENDERING_TILE_LIST_SET_BASE { + uint32_t opcode; + __gen_address_type address; + uint32_t tile_list_set_number; +}; + +static inline void +V3D41_MULTICORE_RENDERING_TILE_LIST_SET_BASE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_MULTICORE_RENDERING_TILE_LIST_SET_BASE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address) | + __gen_uint(values->tile_list_set_number, 0, 3); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D41_MULTICORE_RENDERING_TILE_LIST_SET_BASE_length 5 +#ifdef __gen_unpack_address +static inline void +V3D41_MULTICORE_RENDERING_TILE_LIST_SET_BASE_unpack(const uint8_t * restrict cl, + struct V3D41_MULTICORE_RENDERING_TILE_LIST_SET_BASE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 14, 39); + values->tile_list_set_number = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D41_TILE_COORDINATES_IMPLICIT_opcode 125 +#define V3D41_TILE_COORDINATES_IMPLICIT_header \ + .opcode = 125 + +struct V3D41_TILE_COORDINATES_IMPLICIT { + uint32_t opcode; +}; + +static inline void +V3D41_TILE_COORDINATES_IMPLICIT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_COORDINATES_IMPLICIT * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D41_TILE_COORDINATES_IMPLICIT_length 1 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_COORDINATES_IMPLICIT_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_COORDINATES_IMPLICIT * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D41_TILE_LIST_INITIAL_BLOCK_SIZE_opcode 126 +#define V3D41_TILE_LIST_INITIAL_BLOCK_SIZE_header\ + .opcode = 126 + +struct V3D41_TILE_LIST_INITIAL_BLOCK_SIZE { + uint32_t opcode; + bool use_auto_chained_tile_lists; + uint32_t size_of_first_block_in_chained_tile_lists; +#define TILE_ALLOCATION_BLOCK_SIZE_64B 0 +#define TILE_ALLOCATION_BLOCK_SIZE_128B 1 +#define TILE_ALLOCATION_BLOCK_SIZE_256B 2 +}; + +static inline void +V3D41_TILE_LIST_INITIAL_BLOCK_SIZE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TILE_LIST_INITIAL_BLOCK_SIZE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->use_auto_chained_tile_lists, 2, 2) | + __gen_uint(values->size_of_first_block_in_chained_tile_lists, 0, 1); + +} + +#define V3D41_TILE_LIST_INITIAL_BLOCK_SIZE_length 2 +#ifdef __gen_unpack_address +static inline void +V3D41_TILE_LIST_INITIAL_BLOCK_SIZE_unpack(const uint8_t * restrict cl, + struct V3D41_TILE_LIST_INITIAL_BLOCK_SIZE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->use_auto_chained_tile_lists = __gen_unpack_uint(cl, 10, 10); + values->size_of_first_block_in_chained_tile_lists = __gen_unpack_uint(cl, 8, 9); +} +#endif + + +#define V3D41_GL_SHADER_STATE_RECORD_header \ + + +struct V3D41_GL_SHADER_STATE_RECORD { + bool point_size_in_shaded_vertex_data; + bool enable_clipping; + bool vertex_id_read_by_coordinate_shader; + bool instance_id_read_by_coordinate_shader; + bool base_instance_id_read_by_coordinate_shader; + bool vertex_id_read_by_vertex_shader; + bool instance_id_read_by_vertex_shader; + bool base_instance_id_read_by_vertex_shader; + bool fragment_shader_does_z_writes; + bool turn_off_early_z_test; + bool coordinate_shader_has_separate_input_and_output_vpm_blocks; + bool vertex_shader_has_separate_input_and_output_vpm_blocks; + bool fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2; + bool enable_sample_rate_shading; + bool any_shader_reads_hardware_written_primitive_id; + bool insert_primitive_id_as_first_varying_to_fragment_shader; + bool turn_off_scoreboard; + bool do_scoreboard_wait_on_first_thread_switch; + bool disable_implicit_point_line_varyings; + bool no_prim_pack; + uint32_t number_of_varyings_in_fragment_shader; + uint32_t coordinate_shader_output_vpm_segment_size; + uint32_t min_coord_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size; + uint32_t coordinate_shader_input_vpm_segment_size; + uint32_t min_coord_shader_input_segments_required_in_play; + uint32_t vertex_shader_output_vpm_segment_size; + uint32_t min_vertex_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size; + uint32_t vertex_shader_input_vpm_segment_size; + uint32_t min_vertex_shader_input_segments_required_in_play; + __gen_address_type address_of_default_attribute_values; + __gen_address_type fragment_shader_code_address; + bool fragment_shader_4_way_threadable; + bool fragment_shader_start_in_final_thread_section; + bool fragment_shader_propagate_nans; + __gen_address_type fragment_shader_uniforms_address; + __gen_address_type vertex_shader_code_address; + bool vertex_shader_4_way_threadable; + bool vertex_shader_start_in_final_thread_section; + bool vertex_shader_propagate_nans; + __gen_address_type vertex_shader_uniforms_address; + __gen_address_type coordinate_shader_code_address; + bool coordinate_shader_4_way_threadable; + bool coordinate_shader_start_in_final_thread_section; + bool coordinate_shader_propagate_nans; + __gen_address_type coordinate_shader_uniforms_address; +}; + +static inline void +V3D41_GL_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_GL_SHADER_STATE_RECORD * restrict values) +{ + assert(values->min_coord_shader_input_segments_required_in_play >= 1); + assert(values->min_vertex_shader_input_segments_required_in_play >= 1); + cl[ 0] = __gen_uint(values->point_size_in_shaded_vertex_data, 0, 0) | + __gen_uint(values->enable_clipping, 1, 1) | + __gen_uint(values->vertex_id_read_by_coordinate_shader, 2, 2) | + __gen_uint(values->instance_id_read_by_coordinate_shader, 3, 3) | + __gen_uint(values->base_instance_id_read_by_coordinate_shader, 4, 4) | + __gen_uint(values->vertex_id_read_by_vertex_shader, 5, 5) | + __gen_uint(values->instance_id_read_by_vertex_shader, 6, 6) | + __gen_uint(values->base_instance_id_read_by_vertex_shader, 7, 7); + + cl[ 1] = __gen_uint(values->fragment_shader_does_z_writes, 0, 0) | + __gen_uint(values->turn_off_early_z_test, 1, 1) | + __gen_uint(values->coordinate_shader_has_separate_input_and_output_vpm_blocks, 2, 2) | + __gen_uint(values->vertex_shader_has_separate_input_and_output_vpm_blocks, 3, 3) | + __gen_uint(values->fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2, 4, 4) | + __gen_uint(values->enable_sample_rate_shading, 5, 5) | + __gen_uint(values->any_shader_reads_hardware_written_primitive_id, 6, 6) | + __gen_uint(values->insert_primitive_id_as_first_varying_to_fragment_shader, 7, 7); + + cl[ 2] = __gen_uint(values->turn_off_scoreboard, 0, 0) | + __gen_uint(values->do_scoreboard_wait_on_first_thread_switch, 1, 1) | + __gen_uint(values->disable_implicit_point_line_varyings, 2, 2) | + __gen_uint(values->no_prim_pack, 3, 3); + + cl[ 3] = __gen_uint(values->number_of_varyings_in_fragment_shader, 0, 7); + + cl[ 4] = __gen_uint(values->coordinate_shader_output_vpm_segment_size, 0, 3) | + __gen_uint(values->min_coord_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size, 4, 7); + + cl[ 5] = __gen_uint(values->coordinate_shader_input_vpm_segment_size, 0, 3) | + __gen_uint(values->min_coord_shader_input_segments_required_in_play - 1, 4, 7); + + cl[ 6] = __gen_uint(values->vertex_shader_output_vpm_segment_size, 0, 3) | + __gen_uint(values->min_vertex_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size, 4, 7); + + cl[ 7] = __gen_uint(values->vertex_shader_input_vpm_segment_size, 0, 3) | + __gen_uint(values->min_vertex_shader_input_segments_required_in_play - 1, 4, 7); + + __gen_emit_reloc(data, &values->address_of_default_attribute_values); + cl[ 8] = __gen_address_offset(&values->address_of_default_attribute_values); + + cl[ 9] = __gen_address_offset(&values->address_of_default_attribute_values) >> 8; + + cl[10] = __gen_address_offset(&values->address_of_default_attribute_values) >> 16; + + cl[11] = __gen_address_offset(&values->address_of_default_attribute_values) >> 24; + + __gen_emit_reloc(data, &values->fragment_shader_code_address); + cl[12] = __gen_address_offset(&values->fragment_shader_code_address) | + __gen_uint(values->fragment_shader_4_way_threadable, 0, 0) | + __gen_uint(values->fragment_shader_start_in_final_thread_section, 1, 1) | + __gen_uint(values->fragment_shader_propagate_nans, 2, 2); + + cl[13] = __gen_address_offset(&values->fragment_shader_code_address) >> 8; + + cl[14] = __gen_address_offset(&values->fragment_shader_code_address) >> 16; + + cl[15] = __gen_address_offset(&values->fragment_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->fragment_shader_uniforms_address); + cl[16] = __gen_address_offset(&values->fragment_shader_uniforms_address); + + cl[17] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 8; + + cl[18] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 16; + + cl[19] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->vertex_shader_code_address); + cl[20] = __gen_address_offset(&values->vertex_shader_code_address) | + __gen_uint(values->vertex_shader_4_way_threadable, 0, 0) | + __gen_uint(values->vertex_shader_start_in_final_thread_section, 1, 1) | + __gen_uint(values->vertex_shader_propagate_nans, 2, 2); + + cl[21] = __gen_address_offset(&values->vertex_shader_code_address) >> 8; + + cl[22] = __gen_address_offset(&values->vertex_shader_code_address) >> 16; + + cl[23] = __gen_address_offset(&values->vertex_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->vertex_shader_uniforms_address); + cl[24] = __gen_address_offset(&values->vertex_shader_uniforms_address); + + cl[25] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 8; + + cl[26] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 16; + + cl[27] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->coordinate_shader_code_address); + cl[28] = __gen_address_offset(&values->coordinate_shader_code_address) | + __gen_uint(values->coordinate_shader_4_way_threadable, 0, 0) | + __gen_uint(values->coordinate_shader_start_in_final_thread_section, 1, 1) | + __gen_uint(values->coordinate_shader_propagate_nans, 2, 2); + + cl[29] = __gen_address_offset(&values->coordinate_shader_code_address) >> 8; + + cl[30] = __gen_address_offset(&values->coordinate_shader_code_address) >> 16; + + cl[31] = __gen_address_offset(&values->coordinate_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->coordinate_shader_uniforms_address); + cl[32] = __gen_address_offset(&values->coordinate_shader_uniforms_address); + + cl[33] = __gen_address_offset(&values->coordinate_shader_uniforms_address) >> 8; + + cl[34] = __gen_address_offset(&values->coordinate_shader_uniforms_address) >> 16; + + cl[35] = __gen_address_offset(&values->coordinate_shader_uniforms_address) >> 24; + +} + +#define V3D41_GL_SHADER_STATE_RECORD_length 36 +#ifdef __gen_unpack_address +static inline void +V3D41_GL_SHADER_STATE_RECORD_unpack(const uint8_t * restrict cl, + struct V3D41_GL_SHADER_STATE_RECORD * restrict values) +{ + values->point_size_in_shaded_vertex_data = __gen_unpack_uint(cl, 0, 0); + values->enable_clipping = __gen_unpack_uint(cl, 1, 1); + values->vertex_id_read_by_coordinate_shader = __gen_unpack_uint(cl, 2, 2); + values->instance_id_read_by_coordinate_shader = __gen_unpack_uint(cl, 3, 3); + values->base_instance_id_read_by_coordinate_shader = __gen_unpack_uint(cl, 4, 4); + values->vertex_id_read_by_vertex_shader = __gen_unpack_uint(cl, 5, 5); + values->instance_id_read_by_vertex_shader = __gen_unpack_uint(cl, 6, 6); + values->base_instance_id_read_by_vertex_shader = __gen_unpack_uint(cl, 7, 7); + values->fragment_shader_does_z_writes = __gen_unpack_uint(cl, 8, 8); + values->turn_off_early_z_test = __gen_unpack_uint(cl, 9, 9); + values->coordinate_shader_has_separate_input_and_output_vpm_blocks = __gen_unpack_uint(cl, 10, 10); + values->vertex_shader_has_separate_input_and_output_vpm_blocks = __gen_unpack_uint(cl, 11, 11); + values->fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2 = __gen_unpack_uint(cl, 12, 12); + values->enable_sample_rate_shading = __gen_unpack_uint(cl, 13, 13); + values->any_shader_reads_hardware_written_primitive_id = __gen_unpack_uint(cl, 14, 14); + values->insert_primitive_id_as_first_varying_to_fragment_shader = __gen_unpack_uint(cl, 15, 15); + values->turn_off_scoreboard = __gen_unpack_uint(cl, 16, 16); + values->do_scoreboard_wait_on_first_thread_switch = __gen_unpack_uint(cl, 17, 17); + values->disable_implicit_point_line_varyings = __gen_unpack_uint(cl, 18, 18); + values->no_prim_pack = __gen_unpack_uint(cl, 19, 19); + values->number_of_varyings_in_fragment_shader = __gen_unpack_uint(cl, 24, 31); + values->coordinate_shader_output_vpm_segment_size = __gen_unpack_uint(cl, 32, 35); + values->min_coord_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size = __gen_unpack_uint(cl, 36, 39); + values->coordinate_shader_input_vpm_segment_size = __gen_unpack_uint(cl, 40, 43); + values->min_coord_shader_input_segments_required_in_play = __gen_unpack_uint(cl, 44, 47) + 1; + values->vertex_shader_output_vpm_segment_size = __gen_unpack_uint(cl, 48, 51); + values->min_vertex_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size = __gen_unpack_uint(cl, 52, 55); + values->vertex_shader_input_vpm_segment_size = __gen_unpack_uint(cl, 56, 59); + values->min_vertex_shader_input_segments_required_in_play = __gen_unpack_uint(cl, 60, 63) + 1; + values->address_of_default_attribute_values = __gen_unpack_address(cl, 64, 95); + values->fragment_shader_code_address = __gen_unpack_address(cl, 99, 127); + values->fragment_shader_4_way_threadable = __gen_unpack_uint(cl, 96, 96); + values->fragment_shader_start_in_final_thread_section = __gen_unpack_uint(cl, 97, 97); + values->fragment_shader_propagate_nans = __gen_unpack_uint(cl, 98, 98); + values->fragment_shader_uniforms_address = __gen_unpack_address(cl, 128, 159); + values->vertex_shader_code_address = __gen_unpack_address(cl, 163, 191); + values->vertex_shader_4_way_threadable = __gen_unpack_uint(cl, 160, 160); + values->vertex_shader_start_in_final_thread_section = __gen_unpack_uint(cl, 161, 161); + values->vertex_shader_propagate_nans = __gen_unpack_uint(cl, 162, 162); + values->vertex_shader_uniforms_address = __gen_unpack_address(cl, 192, 223); + values->coordinate_shader_code_address = __gen_unpack_address(cl, 227, 255); + values->coordinate_shader_4_way_threadable = __gen_unpack_uint(cl, 224, 224); + values->coordinate_shader_start_in_final_thread_section = __gen_unpack_uint(cl, 225, 225); + values->coordinate_shader_propagate_nans = __gen_unpack_uint(cl, 226, 226); + values->coordinate_shader_uniforms_address = __gen_unpack_address(cl, 256, 287); +} +#endif + + +#define V3D41_GEOMETRY_SHADER_STATE_RECORD_header\ + + +struct V3D41_GEOMETRY_SHADER_STATE_RECORD { + __gen_address_type geometry_bin_mode_shader_code_address; + bool _4_way_threadable; + bool start_in_final_thread_section; + bool propagate_nans; + __gen_address_type geometry_bin_mode_shader_uniforms_address; + __gen_address_type geometry_render_mode_shader_code_address; + __gen_address_type geometry_render_mode_shader_uniforms_address; +}; + +static inline void +V3D41_GEOMETRY_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_GEOMETRY_SHADER_STATE_RECORD * restrict values) +{ + __gen_emit_reloc(data, &values->geometry_bin_mode_shader_code_address); + cl[ 0] = __gen_address_offset(&values->geometry_bin_mode_shader_code_address) | + __gen_uint(values->_4_way_threadable, 0, 0) | + __gen_uint(values->start_in_final_thread_section, 1, 1) | + __gen_uint(values->propagate_nans, 2, 2); + + cl[ 1] = __gen_address_offset(&values->geometry_bin_mode_shader_code_address) >> 8; + + cl[ 2] = __gen_address_offset(&values->geometry_bin_mode_shader_code_address) >> 16; + + cl[ 3] = __gen_address_offset(&values->geometry_bin_mode_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->geometry_bin_mode_shader_uniforms_address); + cl[ 4] = __gen_address_offset(&values->geometry_bin_mode_shader_uniforms_address); + + cl[ 5] = __gen_address_offset(&values->geometry_bin_mode_shader_uniforms_address) >> 8; + + cl[ 6] = __gen_address_offset(&values->geometry_bin_mode_shader_uniforms_address) >> 16; + + cl[ 7] = __gen_address_offset(&values->geometry_bin_mode_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->geometry_render_mode_shader_code_address); + cl[ 8] = __gen_address_offset(&values->geometry_render_mode_shader_code_address); + + cl[ 9] = __gen_address_offset(&values->geometry_render_mode_shader_code_address) >> 8; + + cl[10] = __gen_address_offset(&values->geometry_render_mode_shader_code_address) >> 16; + + cl[11] = __gen_address_offset(&values->geometry_render_mode_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->geometry_render_mode_shader_uniforms_address); + cl[12] = __gen_address_offset(&values->geometry_render_mode_shader_uniforms_address); + + cl[13] = __gen_address_offset(&values->geometry_render_mode_shader_uniforms_address) >> 8; + + cl[14] = __gen_address_offset(&values->geometry_render_mode_shader_uniforms_address) >> 16; + + cl[15] = __gen_address_offset(&values->geometry_render_mode_shader_uniforms_address) >> 24; + +} + +#define V3D41_GEOMETRY_SHADER_STATE_RECORD_length 16 +#ifdef __gen_unpack_address +static inline void +V3D41_GEOMETRY_SHADER_STATE_RECORD_unpack(const uint8_t * restrict cl, + struct V3D41_GEOMETRY_SHADER_STATE_RECORD * restrict values) +{ + values->geometry_bin_mode_shader_code_address = __gen_unpack_address(cl, 0, 31); + values->_4_way_threadable = __gen_unpack_uint(cl, 0, 0); + values->start_in_final_thread_section = __gen_unpack_uint(cl, 1, 1); + values->propagate_nans = __gen_unpack_uint(cl, 2, 2); + values->geometry_bin_mode_shader_uniforms_address = __gen_unpack_address(cl, 32, 63); + values->geometry_render_mode_shader_code_address = __gen_unpack_address(cl, 64, 95); + values->geometry_render_mode_shader_uniforms_address = __gen_unpack_address(cl, 96, 127); +} +#endif + + +#define V3D41_TESSELLATION_SHADER_STATE_RECORD_header\ + + +struct V3D41_TESSELLATION_SHADER_STATE_RECORD { + __gen_address_type tessellation_bin_mode_control_shader_code_address; + __gen_address_type tessellation_bin_mode_control_shader_uniforms_address; + __gen_address_type tessellation_render_mode_control_shader_code_address; + __gen_address_type tessellation_render_mode_control_shader_uniforms_address; + __gen_address_type tessellation_bin_mode_evaluation_shader_code_address; + __gen_address_type tessellation_bin_mode_evaluation_shader_uniforms_address; + __gen_address_type tessellation_render_mode_evaluation_shader_code_address; + __gen_address_type tessellation_render_mode_evaluation_shader_uniforms_address; +}; + +static inline void +V3D41_TESSELLATION_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TESSELLATION_SHADER_STATE_RECORD * restrict values) +{ + __gen_emit_reloc(data, &values->tessellation_bin_mode_control_shader_code_address); + cl[ 0] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_code_address); + + cl[ 1] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_code_address) >> 8; + + cl[ 2] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_code_address) >> 16; + + cl[ 3] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_bin_mode_control_shader_uniforms_address); + cl[ 4] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_uniforms_address); + + cl[ 5] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_uniforms_address) >> 8; + + cl[ 6] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_uniforms_address) >> 16; + + cl[ 7] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_render_mode_control_shader_code_address); + cl[ 8] = __gen_address_offset(&values->tessellation_render_mode_control_shader_code_address); + + cl[ 9] = __gen_address_offset(&values->tessellation_render_mode_control_shader_code_address) >> 8; + + cl[10] = __gen_address_offset(&values->tessellation_render_mode_control_shader_code_address) >> 16; + + cl[11] = __gen_address_offset(&values->tessellation_render_mode_control_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_render_mode_control_shader_uniforms_address); + cl[12] = __gen_address_offset(&values->tessellation_render_mode_control_shader_uniforms_address); + + cl[13] = __gen_address_offset(&values->tessellation_render_mode_control_shader_uniforms_address) >> 8; + + cl[14] = __gen_address_offset(&values->tessellation_render_mode_control_shader_uniforms_address) >> 16; + + cl[15] = __gen_address_offset(&values->tessellation_render_mode_control_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_bin_mode_evaluation_shader_code_address); + cl[16] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_code_address); + + cl[17] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_code_address) >> 8; + + cl[18] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_code_address) >> 16; + + cl[19] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_bin_mode_evaluation_shader_uniforms_address); + cl[20] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_uniforms_address); + + cl[21] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_uniforms_address) >> 8; + + cl[22] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_uniforms_address) >> 16; + + cl[23] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_render_mode_evaluation_shader_code_address); + cl[24] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_code_address); + + cl[25] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_code_address) >> 8; + + cl[26] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_code_address) >> 16; + + cl[27] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_render_mode_evaluation_shader_uniforms_address); + cl[28] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_uniforms_address); + + cl[29] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_uniforms_address) >> 8; + + cl[30] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_uniforms_address) >> 16; + + cl[31] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_uniforms_address) >> 24; + +} + +#define V3D41_TESSELLATION_SHADER_STATE_RECORD_length 32 +#ifdef __gen_unpack_address +static inline void +V3D41_TESSELLATION_SHADER_STATE_RECORD_unpack(const uint8_t * restrict cl, + struct V3D41_TESSELLATION_SHADER_STATE_RECORD * restrict values) +{ + values->tessellation_bin_mode_control_shader_code_address = __gen_unpack_address(cl, 0, 31); + values->tessellation_bin_mode_control_shader_uniforms_address = __gen_unpack_address(cl, 32, 63); + values->tessellation_render_mode_control_shader_code_address = __gen_unpack_address(cl, 64, 95); + values->tessellation_render_mode_control_shader_uniforms_address = __gen_unpack_address(cl, 96, 127); + values->tessellation_bin_mode_evaluation_shader_code_address = __gen_unpack_address(cl, 128, 159); + values->tessellation_bin_mode_evaluation_shader_uniforms_address = __gen_unpack_address(cl, 160, 191); + values->tessellation_render_mode_evaluation_shader_code_address = __gen_unpack_address(cl, 192, 223); + values->tessellation_render_mode_evaluation_shader_uniforms_address = __gen_unpack_address(cl, 224, 255); +} +#endif + + +#define V3D41_GL_SHADER_STATE_ATTRIBUTE_RECORD_header\ + + +struct V3D41_GL_SHADER_STATE_ATTRIBUTE_RECORD { + __gen_address_type address; + uint32_t vec_size; + uint32_t type; +#define ATTRIBUTE_HALF_FLOAT 1 +#define ATTRIBUTE_FLOAT 2 +#define ATTRIBUTE_FIXED 3 +#define ATTRIBUTE_BYTE 4 +#define ATTRIBUTE_SHORT 5 +#define ATTRIBUTE_INT 6 +#define ATTRIBUTE_INT2_10_10_10 7 + bool signed_int_type; + bool normalized_int_type; + bool read_as_int_uint; + uint32_t number_of_values_read_by_coordinate_shader; + uint32_t number_of_values_read_by_vertex_shader; + uint32_t instance_divisor; + uint32_t stride; + uint32_t maximum_index; +}; + +static inline void +V3D41_GL_SHADER_STATE_ATTRIBUTE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_GL_SHADER_STATE_ATTRIBUTE_RECORD * restrict values) +{ + __gen_emit_reloc(data, &values->address); + cl[ 0] = __gen_address_offset(&values->address); + + cl[ 1] = __gen_address_offset(&values->address) >> 8; + + cl[ 2] = __gen_address_offset(&values->address) >> 16; + + cl[ 3] = __gen_address_offset(&values->address) >> 24; + + cl[ 4] = __gen_uint(values->vec_size, 0, 1) | + __gen_uint(values->type, 2, 4) | + __gen_uint(values->signed_int_type, 5, 5) | + __gen_uint(values->normalized_int_type, 6, 6) | + __gen_uint(values->read_as_int_uint, 7, 7); + + cl[ 5] = __gen_uint(values->number_of_values_read_by_coordinate_shader, 0, 3) | + __gen_uint(values->number_of_values_read_by_vertex_shader, 4, 7); + + cl[ 6] = __gen_uint(values->instance_divisor, 0, 15); + + cl[ 7] = __gen_uint(values->instance_divisor, 0, 15) >> 8; + + + memcpy(&cl[8], &values->stride, sizeof(values->stride)); + + memcpy(&cl[12], &values->maximum_index, sizeof(values->maximum_index)); +} + +#define V3D41_GL_SHADER_STATE_ATTRIBUTE_RECORD_length 16 +#ifdef __gen_unpack_address +static inline void +V3D41_GL_SHADER_STATE_ATTRIBUTE_RECORD_unpack(const uint8_t * restrict cl, + struct V3D41_GL_SHADER_STATE_ATTRIBUTE_RECORD * restrict values) +{ + values->address = __gen_unpack_address(cl, 0, 31); + values->vec_size = __gen_unpack_uint(cl, 32, 33); + values->type = __gen_unpack_uint(cl, 34, 36); + values->signed_int_type = __gen_unpack_uint(cl, 37, 37); + values->normalized_int_type = __gen_unpack_uint(cl, 38, 38); + values->read_as_int_uint = __gen_unpack_uint(cl, 39, 39); + values->number_of_values_read_by_coordinate_shader = __gen_unpack_uint(cl, 40, 43); + values->number_of_values_read_by_vertex_shader = __gen_unpack_uint(cl, 44, 47); + values->instance_divisor = __gen_unpack_uint(cl, 48, 63); + values->stride = __gen_unpack_uint(cl, 64, 95); + values->maximum_index = __gen_unpack_uint(cl, 96, 127); +} +#endif + + +#define V3D41_VPM_GENERIC_BLOCK_WRITE_SETUP_header\ + .id = 0, \ + .id0 = 0 + +struct V3D41_VPM_GENERIC_BLOCK_WRITE_SETUP { + uint32_t id; + uint32_t id0; + bool horiz; + bool laned; + bool segs; + int32_t stride; + uint32_t size; +#define VPM_SETUP_SIZE_8_BIT 0 +#define VPM_SETUP_SIZE_16_BIT 1 +#define VPM_SETUP_SIZE_32_BIT 2 + uint32_t addr; +}; + +static inline void +V3D41_VPM_GENERIC_BLOCK_WRITE_SETUP_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_VPM_GENERIC_BLOCK_WRITE_SETUP * restrict values) +{ + cl[ 0] = __gen_uint(values->addr, 0, 12); + + cl[ 1] = __gen_sint(values->stride, 7, 13) | + __gen_uint(values->size, 5, 6) | + __gen_uint(values->addr, 0, 12) >> 8; + + cl[ 2] = __gen_uint(values->laned, 7, 7) | + __gen_uint(values->segs, 6, 6) | + __gen_sint(values->stride, 7, 13) >> 8; + + cl[ 3] = __gen_uint(values->id, 6, 7) | + __gen_uint(values->id0, 3, 5) | + __gen_uint(values->horiz, 0, 0); + +} + +#define V3D41_VPM_GENERIC_BLOCK_WRITE_SETUP_length 4 +#ifdef __gen_unpack_address +static inline void +V3D41_VPM_GENERIC_BLOCK_WRITE_SETUP_unpack(const uint8_t * restrict cl, + struct V3D41_VPM_GENERIC_BLOCK_WRITE_SETUP * restrict values) +{ + values->id = __gen_unpack_uint(cl, 30, 31); + values->id0 = __gen_unpack_uint(cl, 27, 29); + values->horiz = __gen_unpack_uint(cl, 24, 24); + values->laned = __gen_unpack_uint(cl, 23, 23); + values->segs = __gen_unpack_uint(cl, 22, 22); + values->stride = __gen_unpack_sint(cl, 15, 21); + values->size = __gen_unpack_uint(cl, 13, 14); + values->addr = __gen_unpack_uint(cl, 0, 12); +} +#endif + + +#define V3D41_VPM_GENERIC_BLOCK_READ_SETUP_header\ + .id = 1 + +struct V3D41_VPM_GENERIC_BLOCK_READ_SETUP { + uint32_t id; + bool horiz; + bool laned; + bool segs; + uint32_t num; + int32_t stride; + uint32_t size; +#define VPM_SETUP_SIZE_8_BIT 0 +#define VPM_SETUP_SIZE_16_BIT 1 +#define VPM_SETUP_SIZE_32_BIT 2 + uint32_t addr; +}; + +static inline void +V3D41_VPM_GENERIC_BLOCK_READ_SETUP_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_VPM_GENERIC_BLOCK_READ_SETUP * restrict values) +{ + cl[ 0] = __gen_uint(values->addr, 0, 12); + + cl[ 1] = __gen_sint(values->stride, 7, 13) | + __gen_uint(values->size, 5, 6) | + __gen_uint(values->addr, 0, 12) >> 8; + + cl[ 2] = __gen_uint(values->num, 6, 10) | + __gen_sint(values->stride, 7, 13) >> 8; + + cl[ 3] = __gen_uint(values->id, 6, 7) | + __gen_uint(values->horiz, 5, 5) | + __gen_uint(values->laned, 4, 4) | + __gen_uint(values->segs, 3, 3) | + __gen_uint(values->num, 6, 10) >> 8; + +} + +#define V3D41_VPM_GENERIC_BLOCK_READ_SETUP_length 4 +#ifdef __gen_unpack_address +static inline void +V3D41_VPM_GENERIC_BLOCK_READ_SETUP_unpack(const uint8_t * restrict cl, + struct V3D41_VPM_GENERIC_BLOCK_READ_SETUP * restrict values) +{ + values->id = __gen_unpack_uint(cl, 30, 31); + values->horiz = __gen_unpack_uint(cl, 29, 29); + values->laned = __gen_unpack_uint(cl, 28, 28); + values->segs = __gen_unpack_uint(cl, 27, 27); + values->num = __gen_unpack_uint(cl, 22, 26); + values->stride = __gen_unpack_sint(cl, 15, 21); + values->size = __gen_unpack_uint(cl, 13, 14); + values->addr = __gen_unpack_uint(cl, 0, 12); +} +#endif + + +#define V3D41_TMU_CONFIG_PARAMETER_0_header \ + + +struct V3D41_TMU_CONFIG_PARAMETER_0 { + __gen_address_type texture_state_address; + uint32_t return_words_of_texture_data; +}; + +static inline void +V3D41_TMU_CONFIG_PARAMETER_0_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TMU_CONFIG_PARAMETER_0 * restrict values) +{ + __gen_emit_reloc(data, &values->texture_state_address); + cl[ 0] = __gen_address_offset(&values->texture_state_address) | + __gen_uint(values->return_words_of_texture_data, 0, 3); + + cl[ 1] = __gen_address_offset(&values->texture_state_address) >> 8; + + cl[ 2] = __gen_address_offset(&values->texture_state_address) >> 16; + + cl[ 3] = __gen_address_offset(&values->texture_state_address) >> 24; + +} + +#define V3D41_TMU_CONFIG_PARAMETER_0_length 4 +#ifdef __gen_unpack_address +static inline void +V3D41_TMU_CONFIG_PARAMETER_0_unpack(const uint8_t * restrict cl, + struct V3D41_TMU_CONFIG_PARAMETER_0 * restrict values) +{ + values->texture_state_address = __gen_unpack_address(cl, 0, 31); + values->return_words_of_texture_data = __gen_unpack_uint(cl, 0, 3); +} +#endif + + +#define V3D41_TMU_CONFIG_PARAMETER_1_header \ + + +struct V3D41_TMU_CONFIG_PARAMETER_1 { + __gen_address_type sampler_state_address; + bool per_pixel_mask_enable; + bool unnormalized_coordinates; + bool output_type_32_bit; +}; + +static inline void +V3D41_TMU_CONFIG_PARAMETER_1_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TMU_CONFIG_PARAMETER_1 * restrict values) +{ + __gen_emit_reloc(data, &values->sampler_state_address); + cl[ 0] = __gen_address_offset(&values->sampler_state_address) | + __gen_uint(values->per_pixel_mask_enable, 2, 2) | + __gen_uint(values->unnormalized_coordinates, 1, 1) | + __gen_uint(values->output_type_32_bit, 0, 0); + + cl[ 1] = __gen_address_offset(&values->sampler_state_address) >> 8; + + cl[ 2] = __gen_address_offset(&values->sampler_state_address) >> 16; + + cl[ 3] = __gen_address_offset(&values->sampler_state_address) >> 24; + +} + +#define V3D41_TMU_CONFIG_PARAMETER_1_length 4 +#ifdef __gen_unpack_address +static inline void +V3D41_TMU_CONFIG_PARAMETER_1_unpack(const uint8_t * restrict cl, + struct V3D41_TMU_CONFIG_PARAMETER_1 * restrict values) +{ + values->sampler_state_address = __gen_unpack_address(cl, 0, 31); + values->per_pixel_mask_enable = __gen_unpack_uint(cl, 2, 2); + values->unnormalized_coordinates = __gen_unpack_uint(cl, 1, 1); + values->output_type_32_bit = __gen_unpack_uint(cl, 0, 0); +} +#endif + + +#define V3D41_TMU_CONFIG_PARAMETER_2_header \ + + +struct V3D41_TMU_CONFIG_PARAMETER_2 { + uint32_t pad; + enum V3D41_TMU_Op op; + int32_t offset_r; + int32_t offset_t; + int32_t offset_s; + bool gather_mode; + uint32_t gather_component; + bool coefficient_mode; + uint32_t sample_number; + bool disable_autolod; + bool offset_format_8; +}; + +static inline void +V3D41_TMU_CONFIG_PARAMETER_2_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TMU_CONFIG_PARAMETER_2 * restrict values) +{ + cl[ 0] = __gen_uint(values->gather_mode, 7, 7) | + __gen_uint(values->gather_component, 5, 6) | + __gen_uint(values->coefficient_mode, 4, 4) | + __gen_uint(values->sample_number, 2, 3) | + __gen_uint(values->disable_autolod, 1, 1) | + __gen_uint(values->offset_format_8, 0, 0); + + cl[ 1] = __gen_uint(values->pad, 0, 23) | + __gen_sint(values->offset_t, 4, 7) | + __gen_sint(values->offset_s, 0, 3); + + cl[ 2] = __gen_uint(values->pad, 0, 23) >> 8 | + __gen_uint(values->op, 4, 7) | + __gen_sint(values->offset_r, 0, 3); + + cl[ 3] = __gen_uint(values->pad, 0, 23) >> 16; + +} + +#define V3D41_TMU_CONFIG_PARAMETER_2_length 4 +#ifdef __gen_unpack_address +static inline void +V3D41_TMU_CONFIG_PARAMETER_2_unpack(const uint8_t * restrict cl, + struct V3D41_TMU_CONFIG_PARAMETER_2 * restrict values) +{ + values->pad = __gen_unpack_uint(cl, 8, 31); + values->op = __gen_unpack_uint(cl, 20, 23); + values->offset_r = __gen_unpack_sint(cl, 16, 19); + values->offset_t = __gen_unpack_sint(cl, 12, 15); + values->offset_s = __gen_unpack_sint(cl, 8, 11); + values->gather_mode = __gen_unpack_uint(cl, 7, 7); + values->gather_component = __gen_unpack_uint(cl, 5, 6); + values->coefficient_mode = __gen_unpack_uint(cl, 4, 4); + values->sample_number = __gen_unpack_uint(cl, 2, 3); + values->disable_autolod = __gen_unpack_uint(cl, 1, 1); + values->offset_format_8 = __gen_unpack_uint(cl, 0, 0); +} +#endif + + +#define V3D41_TEXTURE_SHADER_STATE_header \ + + +struct V3D41_TEXTURE_SHADER_STATE { + uint64_t pad; + bool uif_xor_disable; + bool level_0_is_strictly_uif; + bool level_0_xor_enable; + uint32_t level_0_ub_pad; + uint32_t base_level; + uint32_t max_level; + uint32_t swizzle_a; +#define SWIZZLE_ZERO 0 +#define SWIZZLE_ONE 1 +#define SWIZZLE_RED 2 +#define SWIZZLE_GREEN 3 +#define SWIZZLE_BLUE 4 +#define SWIZZLE_ALPHA 5 + uint32_t swizzle_b; + uint32_t swizzle_g; + uint32_t swizzle_r; + bool extended; + uint32_t texture_type; + uint32_t image_depth; + uint32_t image_height; + uint32_t image_width; + uint32_t array_stride_64_byte_aligned; + __gen_address_type texture_base_pointer; + bool reverse_standard_border_color; + bool ahdr; + bool srgb; + bool flip_s_and_t_on_incoming_request; + bool flip_texture_y_axis; + bool flip_texture_x_axis; +}; + +static inline void +V3D41_TEXTURE_SHADER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_TEXTURE_SHADER_STATE * restrict values) +{ + __gen_emit_reloc(data, &values->texture_base_pointer); + cl[ 0] = __gen_address_offset(&values->texture_base_pointer) | + __gen_uint(values->reverse_standard_border_color, 5, 5) | + __gen_uint(values->ahdr, 4, 4) | + __gen_uint(values->srgb, 3, 3) | + __gen_uint(values->flip_s_and_t_on_incoming_request, 2, 2) | + __gen_uint(values->flip_texture_y_axis, 1, 1) | + __gen_uint(values->flip_texture_x_axis, 0, 0); + + cl[ 1] = __gen_address_offset(&values->texture_base_pointer) >> 8; + + cl[ 2] = __gen_address_offset(&values->texture_base_pointer) >> 16; + + cl[ 3] = __gen_address_offset(&values->texture_base_pointer) >> 24; + + cl[ 4] = __gen_uint(values->array_stride_64_byte_aligned, 0, 25); + + cl[ 5] = __gen_uint(values->array_stride_64_byte_aligned, 0, 25) >> 8; + + cl[ 6] = __gen_uint(values->array_stride_64_byte_aligned, 0, 25) >> 16; + + cl[ 7] = __gen_uint(values->image_width, 2, 15) | + __gen_uint(values->array_stride_64_byte_aligned, 0, 25) >> 24; + + cl[ 8] = __gen_uint(values->image_width, 2, 15) >> 8; + + cl[ 9] = __gen_uint(values->image_height, 0, 13); + + cl[10] = __gen_uint(values->image_depth, 6, 19) | + __gen_uint(values->image_height, 0, 13) >> 8; + + cl[11] = __gen_uint(values->image_depth, 6, 19) >> 8; + + cl[12] = __gen_uint(values->texture_type, 4, 10) | + __gen_uint(values->image_depth, 6, 19) >> 16; + + cl[13] = __gen_uint(values->swizzle_g, 7, 9) | + __gen_uint(values->swizzle_r, 4, 6) | + __gen_uint(values->extended, 3, 3) | + __gen_uint(values->texture_type, 4, 10) >> 8; + + cl[14] = __gen_uint(values->swizzle_a, 5, 7) | + __gen_uint(values->swizzle_b, 2, 4) | + __gen_uint(values->swizzle_g, 7, 9) >> 8; + + cl[15] = __gen_uint(values->base_level, 4, 7) | + __gen_uint(values->max_level, 0, 3); + + cl[16] = __gen_uint(values->uif_xor_disable, 7, 7) | + __gen_uint(values->level_0_is_strictly_uif, 6, 6) | + __gen_uint(values->level_0_xor_enable, 4, 4) | + __gen_uint(values->level_0_ub_pad, 0, 3); + + cl[17] = __gen_uint(values->pad, 0, 55); + + cl[18] = __gen_uint(values->pad, 0, 55) >> 8; + + cl[19] = __gen_uint(values->pad, 0, 55) >> 16; + + cl[20] = __gen_uint(values->pad, 0, 55) >> 24; + + cl[21] = __gen_uint(values->pad, 0, 55) >> 32; + + cl[22] = __gen_uint(values->pad, 0, 55) >> 40; + + cl[23] = __gen_uint(values->pad, 0, 55) >> 48; + +} + +#define V3D41_TEXTURE_SHADER_STATE_length 24 +#ifdef __gen_unpack_address +static inline void +V3D41_TEXTURE_SHADER_STATE_unpack(const uint8_t * restrict cl, + struct V3D41_TEXTURE_SHADER_STATE * restrict values) +{ + values->pad = __gen_unpack_uint(cl, 136, 191); + values->uif_xor_disable = __gen_unpack_uint(cl, 135, 135); + values->level_0_is_strictly_uif = __gen_unpack_uint(cl, 134, 134); + values->level_0_xor_enable = __gen_unpack_uint(cl, 132, 132); + values->level_0_ub_pad = __gen_unpack_uint(cl, 128, 131); + values->base_level = __gen_unpack_uint(cl, 124, 127); + values->max_level = __gen_unpack_uint(cl, 120, 123); + values->swizzle_a = __gen_unpack_uint(cl, 117, 119); + values->swizzle_b = __gen_unpack_uint(cl, 114, 116); + values->swizzle_g = __gen_unpack_uint(cl, 111, 113); + values->swizzle_r = __gen_unpack_uint(cl, 108, 110); + values->extended = __gen_unpack_uint(cl, 107, 107); + values->texture_type = __gen_unpack_uint(cl, 100, 106); + values->image_depth = __gen_unpack_uint(cl, 86, 99); + values->image_height = __gen_unpack_uint(cl, 72, 85); + values->image_width = __gen_unpack_uint(cl, 58, 71); + values->array_stride_64_byte_aligned = __gen_unpack_uint(cl, 32, 57); + values->texture_base_pointer = __gen_unpack_address(cl, 0, 31); + values->reverse_standard_border_color = __gen_unpack_uint(cl, 5, 5); + values->ahdr = __gen_unpack_uint(cl, 4, 4); + values->srgb = __gen_unpack_uint(cl, 3, 3); + values->flip_s_and_t_on_incoming_request = __gen_unpack_uint(cl, 2, 2); + values->flip_texture_y_axis = __gen_unpack_uint(cl, 1, 1); + values->flip_texture_x_axis = __gen_unpack_uint(cl, 0, 0); +} +#endif + + +#define V3D41_SAMPLER_STATE_header \ + + +struct V3D41_SAMPLER_STATE { + uint32_t border_color_alpha; + uint32_t border_color_blue; + uint32_t border_color_green; + uint32_t border_color_red; + uint32_t maximum_anisotropy; + enum V3D41_Border_Color_Mode border_color_mode; + bool wrap_i_border; + enum V3D41_Wrap_Mode wrap_r; + enum V3D41_Wrap_Mode wrap_t; + enum V3D41_Wrap_Mode wrap_s; + float fixed_bias; + float max_level_of_detail; + float min_level_of_detail; + bool srgb_disable; + enum V3D41_Compare_Function depth_compare_function; + bool anisotropy_enable; + bool mip_filter_nearest; + bool min_filter_nearest; + bool mag_filter_nearest; +}; + +static inline void +V3D41_SAMPLER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D41_SAMPLER_STATE * restrict values) +{ + cl[ 0] = __gen_uint(values->srgb_disable, 7, 7) | + __gen_uint(values->depth_compare_function, 4, 6) | + __gen_uint(values->anisotropy_enable, 3, 3) | + __gen_uint(values->mip_filter_nearest, 2, 2) | + __gen_uint(values->min_filter_nearest, 1, 1) | + __gen_uint(values->mag_filter_nearest, 0, 0); + + cl[ 1] = __gen_ufixed(values->min_level_of_detail, 0, 11, 8); + + cl[ 2] = __gen_ufixed(values->max_level_of_detail, 4, 15, 8) | + __gen_ufixed(values->min_level_of_detail, 0, 11, 8) >> 8; + + cl[ 3] = __gen_ufixed(values->max_level_of_detail, 4, 15, 8) >> 8; + + cl[ 4] = __gen_sfixed(values->fixed_bias, 0, 15, 8); + + cl[ 5] = __gen_sfixed(values->fixed_bias, 0, 15, 8) >> 8; + + cl[ 6] = __gen_uint(values->wrap_r, 6, 8) | + __gen_uint(values->wrap_t, 3, 5) | + __gen_uint(values->wrap_s, 0, 2); + + cl[ 7] = __gen_uint(values->maximum_anisotropy, 5, 6) | + __gen_uint(values->border_color_mode, 2, 4) | + __gen_uint(values->wrap_i_border, 1, 1) | + __gen_uint(values->wrap_r, 6, 8) >> 8; + + + memcpy(&cl[8], &values->border_color_red, sizeof(values->border_color_red)); + + memcpy(&cl[12], &values->border_color_green, sizeof(values->border_color_green)); + + memcpy(&cl[16], &values->border_color_blue, sizeof(values->border_color_blue)); + + memcpy(&cl[20], &values->border_color_alpha, sizeof(values->border_color_alpha)); +} + +#define V3D41_SAMPLER_STATE_length 24 +#ifdef __gen_unpack_address +static inline void +V3D41_SAMPLER_STATE_unpack(const uint8_t * restrict cl, + struct V3D41_SAMPLER_STATE * restrict values) +{ + values->border_color_alpha = __gen_unpack_uint(cl, 160, 191); + values->border_color_blue = __gen_unpack_uint(cl, 128, 159); + values->border_color_green = __gen_unpack_uint(cl, 96, 127); + values->border_color_red = __gen_unpack_uint(cl, 64, 95); + values->maximum_anisotropy = __gen_unpack_uint(cl, 61, 62); + values->border_color_mode = __gen_unpack_uint(cl, 58, 60); + values->wrap_i_border = __gen_unpack_uint(cl, 57, 57); + values->wrap_r = __gen_unpack_uint(cl, 54, 56); + values->wrap_t = __gen_unpack_uint(cl, 51, 53); + values->wrap_s = __gen_unpack_uint(cl, 48, 50); + values->fixed_bias = __gen_unpack_sfixed(cl, 32, 47, 8); + values->max_level_of_detail = __gen_unpack_ufixed(cl, 20, 31, 8); + values->min_level_of_detail = __gen_unpack_ufixed(cl, 8, 19, 8); + values->srgb_disable = __gen_unpack_uint(cl, 7, 7); + values->depth_compare_function = __gen_unpack_uint(cl, 4, 6); + values->anisotropy_enable = __gen_unpack_uint(cl, 3, 3); + values->mip_filter_nearest = __gen_unpack_uint(cl, 2, 2); + values->min_filter_nearest = __gen_unpack_uint(cl, 1, 1); + values->mag_filter_nearest = __gen_unpack_uint(cl, 0, 0); +} +#endif + + +enum V3D41_Texture_Data_Formats { + TEXTURE_DATA_FORMAT_R8 = 0, + TEXTURE_DATA_FORMAT_R8_SNORM = 1, + TEXTURE_DATA_FORMAT_RG8 = 2, + TEXTURE_DATA_FORMAT_RG8_SNORM = 3, + TEXTURE_DATA_FORMAT_RGBA8 = 4, + TEXTURE_DATA_FORMAT_RGBA8_SNORM = 5, + TEXTURE_DATA_FORMAT_RGB565 = 6, + TEXTURE_DATA_FORMAT_RGBA4 = 7, + TEXTURE_DATA_FORMAT_RGB5_A1 = 8, + TEXTURE_DATA_FORMAT_RGB10_A2 = 9, + TEXTURE_DATA_FORMAT_R16 = 10, + TEXTURE_DATA_FORMAT_R16_SNORM = 11, + TEXTURE_DATA_FORMAT_RG16 = 12, + TEXTURE_DATA_FORMAT_RG16_SNORM = 13, + TEXTURE_DATA_FORMAT_RGBA16 = 14, + TEXTURE_DATA_FORMAT_RGBA16_SNORM = 15, + TEXTURE_DATA_FORMAT_R16F = 16, + TEXTURE_DATA_FORMAT_RG16F = 17, + TEXTURE_DATA_FORMAT_RGBA16F = 18, + TEXTURE_DATA_FORMAT_R11F_G11F_B10F = 19, + TEXTURE_DATA_FORMAT_RGB9_E5 = 20, + TEXTURE_DATA_FORMAT_DEPTH_COMP16 = 21, + TEXTURE_DATA_FORMAT_DEPTH_COMP24 = 22, + TEXTURE_DATA_FORMAT_DEPTH_COMP32F = 23, + TEXTURE_DATA_FORMAT_DEPTH24_X8 = 24, + TEXTURE_DATA_FORMAT_R4 = 25, + TEXTURE_DATA_FORMAT_R1 = 26, + TEXTURE_DATA_FORMAT_S8 = 27, + TEXTURE_DATA_FORMAT_S16 = 28, + TEXTURE_DATA_FORMAT_R32F = 29, + TEXTURE_DATA_FORMAT_RG32F = 30, + TEXTURE_DATA_FORMAT_RGBA32F = 31, + TEXTURE_DATA_FORMAT_RGB8_ETC2 = 32, + TEXTURE_DATA_FORMAT_RGB8_PUNCHTHROUGH_ALPHA1 = 33, + TEXTURE_DATA_FORMAT_R11_EAC = 34, + TEXTURE_DATA_FORMAT_SIGNED_R11_EAC = 35, + TEXTURE_DATA_FORMAT_RG11_EAC = 36, + TEXTURE_DATA_FORMAT_SIGNED_RG11_EAC = 37, + TEXTURE_DATA_FORMAT_RGBA8_ETC2_EAC = 38, + TEXTURE_DATA_FORMAT_YCBCR_LUMA = 39, + TEXTURE_DATA_FORMAT_YCBCR_420_CHROMA = 40, + TEXTURE_DATA_FORMAT_BC1 = 48, + TEXTURE_DATA_FORMAT_BC2 = 49, + TEXTURE_DATA_FORMAT_BC3 = 50, + TEXTURE_DATA_FORMAT_ASTC_4X4 = 64, + TEXTURE_DATA_FORMAT_ASTC_5X4 = 65, + TEXTURE_DATA_FORMAT_ASTC_5X5 = 66, + TEXTURE_DATA_FORMAT_ASTC_6X5 = 67, + TEXTURE_DATA_FORMAT_ASTC_6X6 = 68, + TEXTURE_DATA_FORMAT_ASTC_8X5 = 69, + TEXTURE_DATA_FORMAT_ASTC_8X6 = 70, + TEXTURE_DATA_FORMAT_ASTC_8X8 = 71, + TEXTURE_DATA_FORMAT_ASTC_10X5 = 72, + TEXTURE_DATA_FORMAT_ASTC_10X6 = 73, + TEXTURE_DATA_FORMAT_ASTC_10X8 = 74, + TEXTURE_DATA_FORMAT_ASTC_10X10 = 75, + TEXTURE_DATA_FORMAT_ASTC_12X10 = 76, + TEXTURE_DATA_FORMAT_ASTC_12X12 = 77, + TEXTURE_DATA_FORMAT_R8I = 96, + TEXTURE_DATA_FORMAT_R8UI = 97, + TEXTURE_DATA_FORMAT_RG8I = 98, + TEXTURE_DATA_FORMAT_RG8UI = 99, + TEXTURE_DATA_FORMAT_RGBA8I = 100, + TEXTURE_DATA_FORMAT_RGBA8UI = 101, + TEXTURE_DATA_FORMAT_R16I = 102, + TEXTURE_DATA_FORMAT_R16UI = 103, + TEXTURE_DATA_FORMAT_RG16I = 104, + TEXTURE_DATA_FORMAT_RG16UI = 105, + TEXTURE_DATA_FORMAT_RGBA16I = 106, + TEXTURE_DATA_FORMAT_RGBA16UI = 107, + TEXTURE_DATA_FORMAT_R32I = 108, + TEXTURE_DATA_FORMAT_R32UI = 109, + TEXTURE_DATA_FORMAT_RG32I = 110, + TEXTURE_DATA_FORMAT_RG32UI = 111, + TEXTURE_DATA_FORMAT_RGBA32I = 112, + TEXTURE_DATA_FORMAT_RGBA32UI = 113, + TEXTURE_DATA_FORMAT_RGB10_A2UI = 114, +}; + +#endif /* V3D41_PACK_H */ diff --git a/lib/mesa/src/broadcom/cle/v3d_packet_v42_pack.h b/lib/mesa/src/broadcom/cle/v3d_packet_v42_pack.h new file mode 100644 index 000000000..48870087f --- /dev/null +++ b/lib/mesa/src/broadcom/cle/v3d_packet_v42_pack.h @@ -0,0 +1,4403 @@ +/* Generated code, see packets.xml and gen_packet_header.py */ + + +/* Packets, enums and structures for V3D 4.2. + * + * This file has been generated, do not hand edit. + */ + +#ifndef V3D42_PACK_H +#define V3D42_PACK_H + +#include "cle/v3d_packet_helpers.h" + + +enum V3D42_Compare_Function { + V3D_COMPARE_FUNC_NEVER = 0, + V3D_COMPARE_FUNC_LESS = 1, + V3D_COMPARE_FUNC_EQUAL = 2, + V3D_COMPARE_FUNC_LEQUAL = 3, + V3D_COMPARE_FUNC_GREATER = 4, + V3D_COMPARE_FUNC_NOTEQUAL = 5, + V3D_COMPARE_FUNC_GEQUAL = 6, + V3D_COMPARE_FUNC_ALWAYS = 7, +}; + +enum V3D42_Blend_Factor { + V3D_BLEND_FACTOR_ZERO = 0, + V3D_BLEND_FACTOR_ONE = 1, + V3D_BLEND_FACTOR_SRC_COLOR = 2, + V3D_BLEND_FACTOR_INV_SRC_COLOR = 3, + V3D_BLEND_FACTOR_DST_COLOR = 4, + V3D_BLEND_FACTOR_INV_DST_COLOR = 5, + V3D_BLEND_FACTOR_SRC_ALPHA = 6, + V3D_BLEND_FACTOR_INV_SRC_ALPHA = 7, + V3D_BLEND_FACTOR_DST_ALPHA = 8, + V3D_BLEND_FACTOR_INV_DST_ALPHA = 9, + V3D_BLEND_FACTOR_CONST_COLOR = 10, + V3D_BLEND_FACTOR_INV_CONST_COLOR = 11, + V3D_BLEND_FACTOR_CONST_ALPHA = 12, + V3D_BLEND_FACTOR_INV_CONST_ALPHA = 13, + V3D_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, +}; + +enum V3D42_Blend_Mode { + V3D_BLEND_MODE_ADD = 0, + V3D_BLEND_MODE_SUB = 1, + V3D_BLEND_MODE_RSUB = 2, + V3D_BLEND_MODE_MIN = 3, + V3D_BLEND_MODE_MAX = 4, + V3D_BLEND_MODE_MUL = 5, + V3D_BLEND_MODE_SCREEN = 6, + V3D_BLEND_MODE_DARKEN = 7, + V3D_BLEND_MODE_LIGHTEN = 8, +}; + +enum V3D42_Stencil_Op { + V3D_STENCIL_OP_ZERO = 0, + V3D_STENCIL_OP_KEEP = 1, + V3D_STENCIL_OP_REPLACE = 2, + V3D_STENCIL_OP_INCR = 3, + V3D_STENCIL_OP_DECR = 4, + V3D_STENCIL_OP_INVERT = 5, + V3D_STENCIL_OP_INCWRAP = 6, + V3D_STENCIL_OP_DECWRAP = 7, +}; + +enum V3D42_Primitive { + V3D_PRIM_POINTS = 0, + V3D_PRIM_LINES = 1, + V3D_PRIM_LINE_LOOP = 2, + V3D_PRIM_LINE_STRIP = 3, + V3D_PRIM_TRIANGLES = 4, + V3D_PRIM_TRIANGLE_STRIP = 5, + V3D_PRIM_TRIANGLE_FAN = 6, + V3D_PRIM_POINTS_TF = 16, + V3D_PRIM_LINES_TF = 17, + V3D_PRIM_LINE_LOOP_TF = 18, + V3D_PRIM_LINE_STRIP_TF = 19, + V3D_PRIM_TRIANGLES_TF = 20, + V3D_PRIM_TRIANGLE_STRIP_TF = 21, + V3D_PRIM_TRIANGLE_FAN_TF = 22, +}; + +enum V3D42_Border_Color_Mode { + V3D_BORDER_COLOR_0000 = 0, + V3D_BORDER_COLOR_0001 = 1, + V3D_BORDER_COLOR_1111 = 2, + V3D_BORDER_COLOR_FOLLOWS = 7, +}; + +enum V3D42_Wrap_Mode { + V3D_WRAP_MODE_WRAP_MODE_REPEAT = 0, + V3D_WRAP_MODE_WRAP_MODE_CLAMP = 1, + V3D_WRAP_MODE_WRAP_MODE_MIRROR = 2, + V3D_WRAP_MODE_WRAP_MODE_BORDER = 3, + V3D_WRAP_MODE_WRAP_MODE_MIRROR_ONCE = 4, +}; + +enum V3D42_TMU_Op { + V3D_TMU_OP_WRITE_ADD_READ_PREFETCH = 0, + V3D_TMU_OP_WRITE_SUB_READ_CLEAR = 1, + V3D_TMU_OP_WRITE_XCHG_READ_FLUSH = 2, + V3D_TMU_OP_WRITE_CMPXCHG_READ_FLUSH = 3, + V3D_TMU_OP_WRITE_UMIN_FULL_L1_CLEAR = 4, + V3D_TMU_OP_WRITE_UMAX = 5, + V3D_TMU_OP_WRITE_SMIN = 6, + V3D_TMU_OP_WRITE_SMAX = 7, + V3D_TMU_OP_WRITE_AND_READ_INC = 8, + V3D_TMU_OP_WRITE_OR_READ_DEC = 9, + V3D_TMU_OP_WRITE_XOR_READ_NOT = 10, + V3D_TMU_OP_REGULAR = 15, +}; + +enum V3D42_Varying_Flags_Action { + V3D_VARYING_FLAGS_ACTION_UNCHANGED = 0, + V3D_VARYING_FLAGS_ACTION_ZEROED = 1, + V3D_VARYING_FLAGS_ACTION_SET = 2, +}; + +enum V3D42_Memory_Format { + V3D_MEMORY_FORMAT_RASTER = 0, + V3D_MEMORY_FORMAT_LINEARTILE = 1, + V3D_MEMORY_FORMAT_UB_LINEAR_1_UIF_BLOCK_WIDE = 2, + V3D_MEMORY_FORMAT_UB_LINEAR_2_UIF_BLOCKS_WIDE = 3, + V3D_MEMORY_FORMAT_UIF_NO_XOR = 4, + V3D_MEMORY_FORMAT_UIF_XOR = 5, +}; + +enum V3D42_Decimate_Mode { + V3D_DECIMATE_MODE_SAMPLE_0 = 0, + V3D_DECIMATE_MODE_4X = 1, + V3D_DECIMATE_MODE_ALL_SAMPLES = 3, +}; + +enum V3D42_Internal_Type { + V3D_INTERNAL_TYPE_8I = 0, + V3D_INTERNAL_TYPE_8UI = 1, + V3D_INTERNAL_TYPE_8 = 2, + V3D_INTERNAL_TYPE_16I = 4, + V3D_INTERNAL_TYPE_16UI = 5, + V3D_INTERNAL_TYPE_16F = 6, + V3D_INTERNAL_TYPE_32I = 8, + V3D_INTERNAL_TYPE_32UI = 9, + V3D_INTERNAL_TYPE_32F = 10, +}; + +enum V3D42_Internal_BPP { + V3D_INTERNAL_BPP_32 = 0, + V3D_INTERNAL_BPP_64 = 1, + V3D_INTERNAL_BPP_128 = 2, +}; + +enum V3D42_Internal_Depth_Type { + V3D_INTERNAL_TYPE_DEPTH_32F = 0, + V3D_INTERNAL_TYPE_DEPTH_24 = 1, + V3D_INTERNAL_TYPE_DEPTH_16 = 2, +}; + +enum V3D42_Render_Target_Clamp { + V3D_RENDER_TARGET_CLAMP_NONE = 0, + V3D_RENDER_TARGET_CLAMP_NORM = 1, + V3D_RENDER_TARGET_CLAMP_POS = 2, + V3D_RENDER_TARGET_CLAMP_INT = 3, +}; + +enum V3D42_Output_Image_Format { + V3D_OUTPUT_IMAGE_FORMAT_SRGB8_ALPHA8 = 0, + V3D_OUTPUT_IMAGE_FORMAT_SRGB = 1, + V3D_OUTPUT_IMAGE_FORMAT_RGB10_A2UI = 2, + V3D_OUTPUT_IMAGE_FORMAT_RGB10_A2 = 3, + V3D_OUTPUT_IMAGE_FORMAT_ABGR1555 = 4, + V3D_OUTPUT_IMAGE_FORMAT_ALPHA_MASKED_ABGR1555 = 5, + V3D_OUTPUT_IMAGE_FORMAT_ABGR4444 = 6, + V3D_OUTPUT_IMAGE_FORMAT_BGR565 = 7, + V3D_OUTPUT_IMAGE_FORMAT_R11F_G11F_B10F = 8, + V3D_OUTPUT_IMAGE_FORMAT_RGBA32F = 9, + V3D_OUTPUT_IMAGE_FORMAT_RG32F = 10, + V3D_OUTPUT_IMAGE_FORMAT_R32F = 11, + V3D_OUTPUT_IMAGE_FORMAT_RGBA32I = 12, + V3D_OUTPUT_IMAGE_FORMAT_RG32I = 13, + V3D_OUTPUT_IMAGE_FORMAT_R32I = 14, + V3D_OUTPUT_IMAGE_FORMAT_RGBA32UI = 15, + V3D_OUTPUT_IMAGE_FORMAT_RG32UI = 16, + V3D_OUTPUT_IMAGE_FORMAT_R32UI = 17, + V3D_OUTPUT_IMAGE_FORMAT_RGBA16F = 18, + V3D_OUTPUT_IMAGE_FORMAT_RG16F = 19, + V3D_OUTPUT_IMAGE_FORMAT_R16F = 20, + V3D_OUTPUT_IMAGE_FORMAT_RGBA16I = 21, + V3D_OUTPUT_IMAGE_FORMAT_RG16I = 22, + V3D_OUTPUT_IMAGE_FORMAT_R16I = 23, + V3D_OUTPUT_IMAGE_FORMAT_RGBA16UI = 24, + V3D_OUTPUT_IMAGE_FORMAT_RG16UI = 25, + V3D_OUTPUT_IMAGE_FORMAT_R16UI = 26, + V3D_OUTPUT_IMAGE_FORMAT_RGBA8 = 27, + V3D_OUTPUT_IMAGE_FORMAT_RGB8 = 28, + V3D_OUTPUT_IMAGE_FORMAT_RG8 = 29, + V3D_OUTPUT_IMAGE_FORMAT_R8 = 30, + V3D_OUTPUT_IMAGE_FORMAT_RGBA8I = 31, + V3D_OUTPUT_IMAGE_FORMAT_RG8I = 32, + V3D_OUTPUT_IMAGE_FORMAT_R8I = 33, + V3D_OUTPUT_IMAGE_FORMAT_RGBA8UI = 34, + V3D_OUTPUT_IMAGE_FORMAT_RG8UI = 35, + V3D_OUTPUT_IMAGE_FORMAT_R8UI = 36, + V3D_OUTPUT_IMAGE_FORMAT_BSTC = 39, + V3D_OUTPUT_IMAGE_FORMAT_D32F = 40, + V3D_OUTPUT_IMAGE_FORMAT_D24 = 41, + V3D_OUTPUT_IMAGE_FORMAT_D16 = 42, + V3D_OUTPUT_IMAGE_FORMAT_D24S8 = 43, + V3D_OUTPUT_IMAGE_FORMAT_S8 = 44, +}; + +enum V3D42_Dither_Mode { + V3D_DITHER_MODE_NONE = 0, + V3D_DITHER_MODE_RGB = 1, + V3D_DITHER_MODE_A = 2, + V3D_DITHER_MODE_RGBA = 3, +}; + +#define V3D42_HALT_opcode 0 +#define V3D42_HALT_header \ + .opcode = 0 + +struct V3D42_HALT { + uint32_t opcode; +}; + +static inline void +V3D42_HALT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_HALT * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_HALT_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_HALT_unpack(const uint8_t * restrict cl, + struct V3D42_HALT * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_NOP_opcode 1 +#define V3D42_NOP_header \ + .opcode = 1 + +struct V3D42_NOP { + uint32_t opcode; +}; + +static inline void +V3D42_NOP_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_NOP * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_NOP_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_NOP_unpack(const uint8_t * restrict cl, + struct V3D42_NOP * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_FLUSH_opcode 4 +#define V3D42_FLUSH_header \ + .opcode = 4 + +struct V3D42_FLUSH { + uint32_t opcode; +}; + +static inline void +V3D42_FLUSH_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_FLUSH * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_FLUSH_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_FLUSH_unpack(const uint8_t * restrict cl, + struct V3D42_FLUSH * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_FLUSH_ALL_STATE_opcode 5 +#define V3D42_FLUSH_ALL_STATE_header \ + .opcode = 5 + +struct V3D42_FLUSH_ALL_STATE { + uint32_t opcode; +}; + +static inline void +V3D42_FLUSH_ALL_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_FLUSH_ALL_STATE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_FLUSH_ALL_STATE_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_FLUSH_ALL_STATE_unpack(const uint8_t * restrict cl, + struct V3D42_FLUSH_ALL_STATE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_START_TILE_BINNING_opcode 6 +#define V3D42_START_TILE_BINNING_header \ + .opcode = 6 + +struct V3D42_START_TILE_BINNING { + uint32_t opcode; +}; + +static inline void +V3D42_START_TILE_BINNING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_START_TILE_BINNING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_START_TILE_BINNING_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_START_TILE_BINNING_unpack(const uint8_t * restrict cl, + struct V3D42_START_TILE_BINNING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_INCREMENT_SEMAPHORE_opcode 7 +#define V3D42_INCREMENT_SEMAPHORE_header \ + .opcode = 7 + +struct V3D42_INCREMENT_SEMAPHORE { + uint32_t opcode; +}; + +static inline void +V3D42_INCREMENT_SEMAPHORE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_INCREMENT_SEMAPHORE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_INCREMENT_SEMAPHORE_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_INCREMENT_SEMAPHORE_unpack(const uint8_t * restrict cl, + struct V3D42_INCREMENT_SEMAPHORE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_WAIT_ON_SEMAPHORE_opcode 8 +#define V3D42_WAIT_ON_SEMAPHORE_header \ + .opcode = 8 + +struct V3D42_WAIT_ON_SEMAPHORE { + uint32_t opcode; +}; + +static inline void +V3D42_WAIT_ON_SEMAPHORE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_WAIT_ON_SEMAPHORE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_WAIT_ON_SEMAPHORE_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_WAIT_ON_SEMAPHORE_unpack(const uint8_t * restrict cl, + struct V3D42_WAIT_ON_SEMAPHORE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_WAIT_FOR_PREVIOUS_FRAME_opcode 9 +#define V3D42_WAIT_FOR_PREVIOUS_FRAME_header \ + .opcode = 9 + +struct V3D42_WAIT_FOR_PREVIOUS_FRAME { + uint32_t opcode; +}; + +static inline void +V3D42_WAIT_FOR_PREVIOUS_FRAME_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_WAIT_FOR_PREVIOUS_FRAME * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_WAIT_FOR_PREVIOUS_FRAME_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_WAIT_FOR_PREVIOUS_FRAME_unpack(const uint8_t * restrict cl, + struct V3D42_WAIT_FOR_PREVIOUS_FRAME * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_ENABLE_Z_ONLY_RENDERING_opcode 10 +#define V3D42_ENABLE_Z_ONLY_RENDERING_header \ + .opcode = 10 + +struct V3D42_ENABLE_Z_ONLY_RENDERING { + uint32_t opcode; +}; + +static inline void +V3D42_ENABLE_Z_ONLY_RENDERING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_ENABLE_Z_ONLY_RENDERING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_ENABLE_Z_ONLY_RENDERING_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_ENABLE_Z_ONLY_RENDERING_unpack(const uint8_t * restrict cl, + struct V3D42_ENABLE_Z_ONLY_RENDERING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_DISABLE_Z_ONLY_RENDERING_opcode 11 +#define V3D42_DISABLE_Z_ONLY_RENDERING_header \ + .opcode = 11 + +struct V3D42_DISABLE_Z_ONLY_RENDERING { + uint32_t opcode; +}; + +static inline void +V3D42_DISABLE_Z_ONLY_RENDERING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_DISABLE_Z_ONLY_RENDERING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_DISABLE_Z_ONLY_RENDERING_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_DISABLE_Z_ONLY_RENDERING_unpack(const uint8_t * restrict cl, + struct V3D42_DISABLE_Z_ONLY_RENDERING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_END_OF_Z_ONLY_RENDERING_IN_FRAME_opcode 12 +#define V3D42_END_OF_Z_ONLY_RENDERING_IN_FRAME_header\ + .opcode = 12 + +struct V3D42_END_OF_Z_ONLY_RENDERING_IN_FRAME { + uint32_t opcode; +}; + +static inline void +V3D42_END_OF_Z_ONLY_RENDERING_IN_FRAME_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_END_OF_Z_ONLY_RENDERING_IN_FRAME * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_END_OF_Z_ONLY_RENDERING_IN_FRAME_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_END_OF_Z_ONLY_RENDERING_IN_FRAME_unpack(const uint8_t * restrict cl, + struct V3D42_END_OF_Z_ONLY_RENDERING_IN_FRAME * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_END_OF_RENDERING_opcode 13 +#define V3D42_END_OF_RENDERING_header \ + .opcode = 13 + +struct V3D42_END_OF_RENDERING { + uint32_t opcode; +}; + +static inline void +V3D42_END_OF_RENDERING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_END_OF_RENDERING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_END_OF_RENDERING_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_END_OF_RENDERING_unpack(const uint8_t * restrict cl, + struct V3D42_END_OF_RENDERING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_WAIT_FOR_TRANSFORM_FEEDBACK_opcode 14 +#define V3D42_WAIT_FOR_TRANSFORM_FEEDBACK_header\ + .opcode = 14 + +struct V3D42_WAIT_FOR_TRANSFORM_FEEDBACK { + uint32_t opcode; + uint32_t block_count; +}; + +static inline void +V3D42_WAIT_FOR_TRANSFORM_FEEDBACK_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_WAIT_FOR_TRANSFORM_FEEDBACK * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->block_count, 0, 7); + +} + +#define V3D42_WAIT_FOR_TRANSFORM_FEEDBACK_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_WAIT_FOR_TRANSFORM_FEEDBACK_unpack(const uint8_t * restrict cl, + struct V3D42_WAIT_FOR_TRANSFORM_FEEDBACK * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->block_count = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D42_BRANCH_TO_AUTO_CHAINED_SUB_LIST_opcode 15 +#define V3D42_BRANCH_TO_AUTO_CHAINED_SUB_LIST_header\ + .opcode = 15 + +struct V3D42_BRANCH_TO_AUTO_CHAINED_SUB_LIST { + uint32_t opcode; + __gen_address_type address; +}; + +static inline void +V3D42_BRANCH_TO_AUTO_CHAINED_SUB_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_BRANCH_TO_AUTO_CHAINED_SUB_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D42_BRANCH_TO_AUTO_CHAINED_SUB_LIST_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_BRANCH_TO_AUTO_CHAINED_SUB_LIST_unpack(const uint8_t * restrict cl, + struct V3D42_BRANCH_TO_AUTO_CHAINED_SUB_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); +} +#endif + + +#define V3D42_BRANCH_opcode 16 +#define V3D42_BRANCH_header \ + .opcode = 16 + +struct V3D42_BRANCH { + uint32_t opcode; + __gen_address_type address; +}; + +static inline void +V3D42_BRANCH_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_BRANCH * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D42_BRANCH_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_BRANCH_unpack(const uint8_t * restrict cl, + struct V3D42_BRANCH * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); +} +#endif + + +#define V3D42_BRANCH_TO_SUB_LIST_opcode 17 +#define V3D42_BRANCH_TO_SUB_LIST_header \ + .opcode = 17 + +struct V3D42_BRANCH_TO_SUB_LIST { + uint32_t opcode; + __gen_address_type address; +}; + +static inline void +V3D42_BRANCH_TO_SUB_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_BRANCH_TO_SUB_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D42_BRANCH_TO_SUB_LIST_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_BRANCH_TO_SUB_LIST_unpack(const uint8_t * restrict cl, + struct V3D42_BRANCH_TO_SUB_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); +} +#endif + + +#define V3D42_RETURN_FROM_SUB_LIST_opcode 18 +#define V3D42_RETURN_FROM_SUB_LIST_header \ + .opcode = 18 + +struct V3D42_RETURN_FROM_SUB_LIST { + uint32_t opcode; +}; + +static inline void +V3D42_RETURN_FROM_SUB_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_RETURN_FROM_SUB_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_RETURN_FROM_SUB_LIST_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_RETURN_FROM_SUB_LIST_unpack(const uint8_t * restrict cl, + struct V3D42_RETURN_FROM_SUB_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_FLUSH_VCD_CACHE_opcode 19 +#define V3D42_FLUSH_VCD_CACHE_header \ + .opcode = 19 + +struct V3D42_FLUSH_VCD_CACHE { + uint32_t opcode; +}; + +static inline void +V3D42_FLUSH_VCD_CACHE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_FLUSH_VCD_CACHE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_FLUSH_VCD_CACHE_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_FLUSH_VCD_CACHE_unpack(const uint8_t * restrict cl, + struct V3D42_FLUSH_VCD_CACHE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_START_ADDRESS_OF_GENERIC_TILE_LIST_opcode 20 +#define V3D42_START_ADDRESS_OF_GENERIC_TILE_LIST_header\ + .opcode = 20 + +struct V3D42_START_ADDRESS_OF_GENERIC_TILE_LIST { + uint32_t opcode; + __gen_address_type start; + __gen_address_type end; +}; + +static inline void +V3D42_START_ADDRESS_OF_GENERIC_TILE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_START_ADDRESS_OF_GENERIC_TILE_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->start); + cl[ 1] = __gen_address_offset(&values->start); + + cl[ 2] = __gen_address_offset(&values->start) >> 8; + + cl[ 3] = __gen_address_offset(&values->start) >> 16; + + cl[ 4] = __gen_address_offset(&values->start) >> 24; + + __gen_emit_reloc(data, &values->end); + cl[ 5] = __gen_address_offset(&values->end); + + cl[ 6] = __gen_address_offset(&values->end) >> 8; + + cl[ 7] = __gen_address_offset(&values->end) >> 16; + + cl[ 8] = __gen_address_offset(&values->end) >> 24; + +} + +#define V3D42_START_ADDRESS_OF_GENERIC_TILE_LIST_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_START_ADDRESS_OF_GENERIC_TILE_LIST_unpack(const uint8_t * restrict cl, + struct V3D42_START_ADDRESS_OF_GENERIC_TILE_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->start = __gen_unpack_address(cl, 8, 39); + values->end = __gen_unpack_address(cl, 40, 71); +} +#endif + + +#define V3D42_BRANCH_TO_IMPLICIT_TILE_LIST_opcode 21 +#define V3D42_BRANCH_TO_IMPLICIT_TILE_LIST_header\ + .opcode = 21 + +struct V3D42_BRANCH_TO_IMPLICIT_TILE_LIST { + uint32_t opcode; + uint32_t tile_list_set_number; +}; + +static inline void +V3D42_BRANCH_TO_IMPLICIT_TILE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_BRANCH_TO_IMPLICIT_TILE_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->tile_list_set_number, 0, 7); + +} + +#define V3D42_BRANCH_TO_IMPLICIT_TILE_LIST_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_BRANCH_TO_IMPLICIT_TILE_LIST_unpack(const uint8_t * restrict cl, + struct V3D42_BRANCH_TO_IMPLICIT_TILE_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->tile_list_set_number = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D42_BRANCH_TO_EXPLICIT_SUPERTILE_opcode 22 +#define V3D42_BRANCH_TO_EXPLICIT_SUPERTILE_header\ + .opcode = 22 + +struct V3D42_BRANCH_TO_EXPLICIT_SUPERTILE { + uint32_t opcode; + __gen_address_type absolute_address_of_explicit_supertile_render_list; + uint32_t explicit_supertile_number; + uint32_t row_number; + uint32_t column_number; +}; + +static inline void +V3D42_BRANCH_TO_EXPLICIT_SUPERTILE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_BRANCH_TO_EXPLICIT_SUPERTILE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->column_number, 0, 7); + + cl[ 2] = __gen_uint(values->row_number, 0, 7); + + cl[ 3] = __gen_uint(values->explicit_supertile_number, 0, 7); + + __gen_emit_reloc(data, &values->absolute_address_of_explicit_supertile_render_list); + cl[ 4] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list); + + cl[ 5] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list) >> 8; + + cl[ 6] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list) >> 16; + + cl[ 7] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list) >> 24; + +} + +#define V3D42_BRANCH_TO_EXPLICIT_SUPERTILE_length 8 +#ifdef __gen_unpack_address +static inline void +V3D42_BRANCH_TO_EXPLICIT_SUPERTILE_unpack(const uint8_t * restrict cl, + struct V3D42_BRANCH_TO_EXPLICIT_SUPERTILE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->absolute_address_of_explicit_supertile_render_list = __gen_unpack_address(cl, 32, 63); + values->explicit_supertile_number = __gen_unpack_uint(cl, 24, 31); + values->row_number = __gen_unpack_uint(cl, 16, 23); + values->column_number = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D42_SUPERTILE_COORDINATES_opcode 23 +#define V3D42_SUPERTILE_COORDINATES_header \ + .opcode = 23 + +struct V3D42_SUPERTILE_COORDINATES { + uint32_t opcode; + uint32_t row_number_in_supertiles; + uint32_t column_number_in_supertiles; +}; + +static inline void +V3D42_SUPERTILE_COORDINATES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_SUPERTILE_COORDINATES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->column_number_in_supertiles, 0, 7); + + cl[ 2] = __gen_uint(values->row_number_in_supertiles, 0, 7); + +} + +#define V3D42_SUPERTILE_COORDINATES_length 3 +#ifdef __gen_unpack_address +static inline void +V3D42_SUPERTILE_COORDINATES_unpack(const uint8_t * restrict cl, + struct V3D42_SUPERTILE_COORDINATES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->row_number_in_supertiles = __gen_unpack_uint(cl, 16, 23); + values->column_number_in_supertiles = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D42_CLEAR_TILE_BUFFERS_opcode 25 +#define V3D42_CLEAR_TILE_BUFFERS_header \ + .opcode = 25 + +struct V3D42_CLEAR_TILE_BUFFERS { + uint32_t opcode; + bool clear_z_stencil_buffer; + bool clear_all_render_targets; +}; + +static inline void +V3D42_CLEAR_TILE_BUFFERS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_CLEAR_TILE_BUFFERS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->clear_z_stencil_buffer, 1, 1) | + __gen_uint(values->clear_all_render_targets, 0, 0); + +} + +#define V3D42_CLEAR_TILE_BUFFERS_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_CLEAR_TILE_BUFFERS_unpack(const uint8_t * restrict cl, + struct V3D42_CLEAR_TILE_BUFFERS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->clear_z_stencil_buffer = __gen_unpack_uint(cl, 9, 9); + values->clear_all_render_targets = __gen_unpack_uint(cl, 8, 8); +} +#endif + + +#define V3D42_END_OF_LOADS_opcode 26 +#define V3D42_END_OF_LOADS_header \ + .opcode = 26 + +struct V3D42_END_OF_LOADS { + uint32_t opcode; +}; + +static inline void +V3D42_END_OF_LOADS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_END_OF_LOADS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_END_OF_LOADS_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_END_OF_LOADS_unpack(const uint8_t * restrict cl, + struct V3D42_END_OF_LOADS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_END_OF_TILE_MARKER_opcode 27 +#define V3D42_END_OF_TILE_MARKER_header \ + .opcode = 27 + +struct V3D42_END_OF_TILE_MARKER { + uint32_t opcode; +}; + +static inline void +V3D42_END_OF_TILE_MARKER_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_END_OF_TILE_MARKER * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_END_OF_TILE_MARKER_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_END_OF_TILE_MARKER_unpack(const uint8_t * restrict cl, + struct V3D42_END_OF_TILE_MARKER * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_STORE_TILE_BUFFER_GENERAL_opcode 29 +#define V3D42_STORE_TILE_BUFFER_GENERAL_header \ + .opcode = 29 + +struct V3D42_STORE_TILE_BUFFER_GENERAL { + uint32_t opcode; + __gen_address_type address; + uint32_t height; + uint32_t height_in_ub_or_stride; + bool r_b_swap; + bool channel_reverse; + bool clear_buffer_being_stored; + enum V3D42_Output_Image_Format output_image_format; + enum V3D42_Decimate_Mode decimate_mode; + enum V3D42_Dither_Mode dither_mode; + bool flip_y; + enum V3D42_Memory_Format memory_format; + uint32_t buffer_to_store; +#define RENDER_TARGET_0 0 +#define RENDER_TARGET_1 1 +#define RENDER_TARGET_2 2 +#define RENDER_TARGET_3 3 +#define NONE 8 +#define Z 9 +#define STENCIL 10 +#define ZSTENCIL 11 +}; + +static inline void +V3D42_STORE_TILE_BUFFER_GENERAL_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_STORE_TILE_BUFFER_GENERAL * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->flip_y, 7, 7) | + __gen_uint(values->memory_format, 4, 6) | + __gen_uint(values->buffer_to_store, 0, 3); + + cl[ 2] = __gen_uint(values->output_image_format, 4, 9) | + __gen_uint(values->decimate_mode, 2, 3) | + __gen_uint(values->dither_mode, 0, 1); + + cl[ 3] = __gen_uint(values->r_b_swap, 4, 4) | + __gen_uint(values->channel_reverse, 3, 3) | + __gen_uint(values->clear_buffer_being_stored, 2, 2) | + __gen_uint(values->output_image_format, 4, 9) >> 8; + + cl[ 4] = __gen_uint(values->height_in_ub_or_stride, 4, 23); + + cl[ 5] = __gen_uint(values->height_in_ub_or_stride, 4, 23) >> 8; + + cl[ 6] = __gen_uint(values->height_in_ub_or_stride, 4, 23) >> 16; + + cl[ 7] = __gen_uint(values->height, 0, 15); + + cl[ 8] = __gen_uint(values->height, 0, 15) >> 8; + + __gen_emit_reloc(data, &values->address); + cl[ 9] = __gen_address_offset(&values->address); + + cl[10] = __gen_address_offset(&values->address) >> 8; + + cl[11] = __gen_address_offset(&values->address) >> 16; + + cl[12] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D42_STORE_TILE_BUFFER_GENERAL_length 13 +#ifdef __gen_unpack_address +static inline void +V3D42_STORE_TILE_BUFFER_GENERAL_unpack(const uint8_t * restrict cl, + struct V3D42_STORE_TILE_BUFFER_GENERAL * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 72, 103); + values->height = __gen_unpack_uint(cl, 56, 71); + values->height_in_ub_or_stride = __gen_unpack_uint(cl, 36, 55); + values->r_b_swap = __gen_unpack_uint(cl, 28, 28); + values->channel_reverse = __gen_unpack_uint(cl, 27, 27); + values->clear_buffer_being_stored = __gen_unpack_uint(cl, 26, 26); + values->output_image_format = __gen_unpack_uint(cl, 20, 25); + values->decimate_mode = __gen_unpack_uint(cl, 18, 19); + values->dither_mode = __gen_unpack_uint(cl, 16, 17); + values->flip_y = __gen_unpack_uint(cl, 15, 15); + values->memory_format = __gen_unpack_uint(cl, 12, 14); + values->buffer_to_store = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_LOAD_TILE_BUFFER_GENERAL_opcode 30 +#define V3D42_LOAD_TILE_BUFFER_GENERAL_header \ + .opcode = 30 + +struct V3D42_LOAD_TILE_BUFFER_GENERAL { + uint32_t opcode; + __gen_address_type address; + uint32_t height; + uint32_t height_in_ub_or_stride; + bool r_b_swap; + bool channel_reverse; + enum V3D42_Output_Image_Format input_image_format; + enum V3D42_Decimate_Mode decimate_mode; + bool flip_y; + enum V3D42_Memory_Format memory_format; + uint32_t buffer_to_load; +#define RENDER_TARGET_0 0 +#define RENDER_TARGET_1 1 +#define RENDER_TARGET_2 2 +#define RENDER_TARGET_3 3 +#define NONE 8 +#define Z 9 +#define STENCIL 10 +#define ZSTENCIL 11 +}; + +static inline void +V3D42_LOAD_TILE_BUFFER_GENERAL_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_LOAD_TILE_BUFFER_GENERAL * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->flip_y, 7, 7) | + __gen_uint(values->memory_format, 4, 6) | + __gen_uint(values->buffer_to_load, 0, 3); + + cl[ 2] = __gen_uint(values->input_image_format, 4, 9) | + __gen_uint(values->decimate_mode, 2, 3); + + cl[ 3] = __gen_uint(values->r_b_swap, 4, 4) | + __gen_uint(values->channel_reverse, 3, 3) | + __gen_uint(values->input_image_format, 4, 9) >> 8; + + cl[ 4] = __gen_uint(values->height_in_ub_or_stride, 4, 23); + + cl[ 5] = __gen_uint(values->height_in_ub_or_stride, 4, 23) >> 8; + + cl[ 6] = __gen_uint(values->height_in_ub_or_stride, 4, 23) >> 16; + + cl[ 7] = __gen_uint(values->height, 0, 15); + + cl[ 8] = __gen_uint(values->height, 0, 15) >> 8; + + __gen_emit_reloc(data, &values->address); + cl[ 9] = __gen_address_offset(&values->address); + + cl[10] = __gen_address_offset(&values->address) >> 8; + + cl[11] = __gen_address_offset(&values->address) >> 16; + + cl[12] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D42_LOAD_TILE_BUFFER_GENERAL_length 13 +#ifdef __gen_unpack_address +static inline void +V3D42_LOAD_TILE_BUFFER_GENERAL_unpack(const uint8_t * restrict cl, + struct V3D42_LOAD_TILE_BUFFER_GENERAL * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 72, 103); + values->height = __gen_unpack_uint(cl, 56, 71); + values->height_in_ub_or_stride = __gen_unpack_uint(cl, 36, 55); + values->r_b_swap = __gen_unpack_uint(cl, 28, 28); + values->channel_reverse = __gen_unpack_uint(cl, 27, 27); + values->input_image_format = __gen_unpack_uint(cl, 20, 25); + values->decimate_mode = __gen_unpack_uint(cl, 18, 19); + values->flip_y = __gen_unpack_uint(cl, 15, 15); + values->memory_format = __gen_unpack_uint(cl, 12, 14); + values->buffer_to_load = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_opcode 31 +#define V3D42_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_header\ + .opcode = 31 + +struct V3D42_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT { + uint32_t opcode; +}; + +static inline void +V3D42_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT_unpack(const uint8_t * restrict cl, + struct V3D42_TRANSFORM_FEEDBACK_FLUSH_AND_COUNT * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_INDEXED_PRIM_LIST_opcode 32 +#define V3D42_INDEXED_PRIM_LIST_header \ + .opcode = 32 + +struct V3D42_INDEXED_PRIM_LIST { + uint32_t opcode; + uint32_t index_offset; + bool enable_primitive_restarts; + uint32_t length; + uint32_t index_type; +#define INDEX_TYPE_8_BIT 0 +#define INDEX_TYPE_16_BIT 1 +#define INDEX_TYPE_32_BIT 2 + enum V3D42_Primitive mode; +}; + +static inline void +V3D42_INDEXED_PRIM_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_INDEXED_PRIM_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->index_type, 6, 7) | + __gen_uint(values->mode, 0, 5); + + cl[ 2] = __gen_uint(values->length, 0, 30); + + cl[ 3] = __gen_uint(values->length, 0, 30) >> 8; + + cl[ 4] = __gen_uint(values->length, 0, 30) >> 16; + + cl[ 5] = __gen_uint(values->enable_primitive_restarts, 7, 7) | + __gen_uint(values->length, 0, 30) >> 24; + + + memcpy(&cl[6], &values->index_offset, sizeof(values->index_offset)); +} + +#define V3D42_INDEXED_PRIM_LIST_length 10 +#ifdef __gen_unpack_address +static inline void +V3D42_INDEXED_PRIM_LIST_unpack(const uint8_t * restrict cl, + struct V3D42_INDEXED_PRIM_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->index_offset = __gen_unpack_uint(cl, 48, 79); + values->enable_primitive_restarts = __gen_unpack_uint(cl, 47, 47); + values->length = __gen_unpack_uint(cl, 16, 46); + values->index_type = __gen_unpack_uint(cl, 14, 15); + values->mode = __gen_unpack_uint(cl, 8, 13); +} +#endif + + +#define V3D42_INDEXED_INSTANCED_PRIM_LIST_opcode 34 +#define V3D42_INDEXED_INSTANCED_PRIM_LIST_header\ + .opcode = 34 + +struct V3D42_INDEXED_INSTANCED_PRIM_LIST { + uint32_t opcode; + uint32_t index_offset; + uint32_t number_of_instances; + bool enable_primitive_restarts; + uint32_t instance_length; + uint32_t index_type; +#define INDEX_TYPE_8_BIT 0 +#define INDEX_TYPE_16_BIT 1 +#define INDEX_TYPE_32_BIT 2 + enum V3D42_Primitive mode; +}; + +static inline void +V3D42_INDEXED_INSTANCED_PRIM_LIST_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_INDEXED_INSTANCED_PRIM_LIST * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->index_type, 6, 7) | + __gen_uint(values->mode, 0, 5); + + cl[ 2] = __gen_uint(values->instance_length, 0, 30); + + cl[ 3] = __gen_uint(values->instance_length, 0, 30) >> 8; + + cl[ 4] = __gen_uint(values->instance_length, 0, 30) >> 16; + + cl[ 5] = __gen_uint(values->enable_primitive_restarts, 7, 7) | + __gen_uint(values->instance_length, 0, 30) >> 24; + + + memcpy(&cl[6], &values->number_of_instances, sizeof(values->number_of_instances)); + + memcpy(&cl[10], &values->index_offset, sizeof(values->index_offset)); +} + +#define V3D42_INDEXED_INSTANCED_PRIM_LIST_length 14 +#ifdef __gen_unpack_address +static inline void +V3D42_INDEXED_INSTANCED_PRIM_LIST_unpack(const uint8_t * restrict cl, + struct V3D42_INDEXED_INSTANCED_PRIM_LIST * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->index_offset = __gen_unpack_uint(cl, 80, 111); + values->number_of_instances = __gen_unpack_uint(cl, 48, 79); + values->enable_primitive_restarts = __gen_unpack_uint(cl, 47, 47); + values->instance_length = __gen_unpack_uint(cl, 16, 46); + values->index_type = __gen_unpack_uint(cl, 14, 15); + values->mode = __gen_unpack_uint(cl, 8, 13); +} +#endif + + +#define V3D42_VERTEX_ARRAY_PRIMS_opcode 36 +#define V3D42_VERTEX_ARRAY_PRIMS_header \ + .opcode = 36 + +struct V3D42_VERTEX_ARRAY_PRIMS { + uint32_t opcode; + uint32_t index_of_first_vertex; + uint32_t length; + enum V3D42_Primitive mode; +}; + +static inline void +V3D42_VERTEX_ARRAY_PRIMS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_VERTEX_ARRAY_PRIMS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->mode, 0, 7); + + + memcpy(&cl[2], &values->length, sizeof(values->length)); + + memcpy(&cl[6], &values->index_of_first_vertex, sizeof(values->index_of_first_vertex)); +} + +#define V3D42_VERTEX_ARRAY_PRIMS_length 10 +#ifdef __gen_unpack_address +static inline void +V3D42_VERTEX_ARRAY_PRIMS_unpack(const uint8_t * restrict cl, + struct V3D42_VERTEX_ARRAY_PRIMS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->index_of_first_vertex = __gen_unpack_uint(cl, 48, 79); + values->length = __gen_unpack_uint(cl, 16, 47); + values->mode = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D42_VERTEX_ARRAY_INSTANCED_PRIMS_opcode 38 +#define V3D42_VERTEX_ARRAY_INSTANCED_PRIMS_header\ + .opcode = 38 + +struct V3D42_VERTEX_ARRAY_INSTANCED_PRIMS { + uint32_t opcode; + uint32_t index_of_first_vertex; + uint32_t number_of_instances; + uint32_t instance_length; + enum V3D42_Primitive mode; +}; + +static inline void +V3D42_VERTEX_ARRAY_INSTANCED_PRIMS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_VERTEX_ARRAY_INSTANCED_PRIMS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->mode, 0, 7); + + + memcpy(&cl[2], &values->instance_length, sizeof(values->instance_length)); + + memcpy(&cl[6], &values->number_of_instances, sizeof(values->number_of_instances)); + + memcpy(&cl[10], &values->index_of_first_vertex, sizeof(values->index_of_first_vertex)); +} + +#define V3D42_VERTEX_ARRAY_INSTANCED_PRIMS_length 14 +#ifdef __gen_unpack_address +static inline void +V3D42_VERTEX_ARRAY_INSTANCED_PRIMS_unpack(const uint8_t * restrict cl, + struct V3D42_VERTEX_ARRAY_INSTANCED_PRIMS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->index_of_first_vertex = __gen_unpack_uint(cl, 80, 111); + values->number_of_instances = __gen_unpack_uint(cl, 48, 79); + values->instance_length = __gen_unpack_uint(cl, 16, 47); + values->mode = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D42_BASE_VERTEX_BASE_INSTANCE_opcode 43 +#define V3D42_BASE_VERTEX_BASE_INSTANCE_header \ + .opcode = 43 + +struct V3D42_BASE_VERTEX_BASE_INSTANCE { + uint32_t opcode; + uint32_t base_instance; + uint32_t base_vertex; +}; + +static inline void +V3D42_BASE_VERTEX_BASE_INSTANCE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_BASE_VERTEX_BASE_INSTANCE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->base_vertex, sizeof(values->base_vertex)); + + memcpy(&cl[5], &values->base_instance, sizeof(values->base_instance)); +} + +#define V3D42_BASE_VERTEX_BASE_INSTANCE_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_BASE_VERTEX_BASE_INSTANCE_unpack(const uint8_t * restrict cl, + struct V3D42_BASE_VERTEX_BASE_INSTANCE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->base_instance = __gen_unpack_uint(cl, 40, 71); + values->base_vertex = __gen_unpack_uint(cl, 8, 39); +} +#endif + + +#define V3D42_INDEX_BUFFER_SETUP_opcode 44 +#define V3D42_INDEX_BUFFER_SETUP_header \ + .opcode = 44 + +struct V3D42_INDEX_BUFFER_SETUP { + uint32_t opcode; + __gen_address_type address; + uint32_t size; +}; + +static inline void +V3D42_INDEX_BUFFER_SETUP_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_INDEX_BUFFER_SETUP * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + + + memcpy(&cl[5], &values->size, sizeof(values->size)); +} + +#define V3D42_INDEX_BUFFER_SETUP_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_INDEX_BUFFER_SETUP_unpack(const uint8_t * restrict cl, + struct V3D42_INDEX_BUFFER_SETUP * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); + values->size = __gen_unpack_uint(cl, 40, 71); +} +#endif + + +#define V3D42_PRIM_LIST_FORMAT_opcode 56 +#define V3D42_PRIM_LIST_FORMAT_header \ + .opcode = 56 + +struct V3D42_PRIM_LIST_FORMAT { + uint32_t opcode; + bool tri_strip_or_fan; + uint32_t primitive_type; +#define LIST_POINTS 0 +#define LIST_LINES 1 +#define LIST_TRIANGLES 2 +}; + +static inline void +V3D42_PRIM_LIST_FORMAT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_PRIM_LIST_FORMAT * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->tri_strip_or_fan, 7, 7) | + __gen_uint(values->primitive_type, 0, 5); + +} + +#define V3D42_PRIM_LIST_FORMAT_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_PRIM_LIST_FORMAT_unpack(const uint8_t * restrict cl, + struct V3D42_PRIM_LIST_FORMAT * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->tri_strip_or_fan = __gen_unpack_uint(cl, 15, 15); + values->primitive_type = __gen_unpack_uint(cl, 8, 13); +} +#endif + + +#define V3D42_GL_SHADER_STATE_opcode 64 +#define V3D42_GL_SHADER_STATE_header \ + .opcode = 64 + +struct V3D42_GL_SHADER_STATE { + uint32_t opcode; + __gen_address_type address; + uint32_t number_of_attribute_arrays; +}; + +static inline void +V3D42_GL_SHADER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_GL_SHADER_STATE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address) | + __gen_uint(values->number_of_attribute_arrays, 0, 4); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D42_GL_SHADER_STATE_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_GL_SHADER_STATE_unpack(const uint8_t * restrict cl, + struct V3D42_GL_SHADER_STATE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 13, 39); + values->number_of_attribute_arrays = __gen_unpack_uint(cl, 8, 12); +} +#endif + + +#define V3D42_VCM_CACHE_SIZE_opcode 71 +#define V3D42_VCM_CACHE_SIZE_header \ + .opcode = 71 + +struct V3D42_VCM_CACHE_SIZE { + uint32_t opcode; + uint32_t number_of_16_vertex_batches_for_rendering; + uint32_t number_of_16_vertex_batches_for_binning; +}; + +static inline void +V3D42_VCM_CACHE_SIZE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_VCM_CACHE_SIZE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->number_of_16_vertex_batches_for_rendering, 4, 7) | + __gen_uint(values->number_of_16_vertex_batches_for_binning, 0, 3); + +} + +#define V3D42_VCM_CACHE_SIZE_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_VCM_CACHE_SIZE_unpack(const uint8_t * restrict cl, + struct V3D42_VCM_CACHE_SIZE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->number_of_16_vertex_batches_for_rendering = __gen_unpack_uint(cl, 12, 15); + values->number_of_16_vertex_batches_for_binning = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_TRANSFORM_FEEDBACK_BUFFER_opcode 73 +#define V3D42_TRANSFORM_FEEDBACK_BUFFER_header \ + .opcode = 73 + +struct V3D42_TRANSFORM_FEEDBACK_BUFFER { + uint32_t opcode; + __gen_address_type buffer_address; + uint32_t buffer_size_in_32_bit_words; + uint32_t buffer_number; +}; + +static inline void +V3D42_TRANSFORM_FEEDBACK_BUFFER_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TRANSFORM_FEEDBACK_BUFFER * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->buffer_size_in_32_bit_words, 2, 31) | + __gen_uint(values->buffer_number, 0, 1); + + cl[ 2] = __gen_uint(values->buffer_size_in_32_bit_words, 2, 31) >> 8; + + cl[ 3] = __gen_uint(values->buffer_size_in_32_bit_words, 2, 31) >> 16; + + cl[ 4] = __gen_uint(values->buffer_size_in_32_bit_words, 2, 31) >> 24; + + __gen_emit_reloc(data, &values->buffer_address); + cl[ 5] = __gen_address_offset(&values->buffer_address); + + cl[ 6] = __gen_address_offset(&values->buffer_address) >> 8; + + cl[ 7] = __gen_address_offset(&values->buffer_address) >> 16; + + cl[ 8] = __gen_address_offset(&values->buffer_address) >> 24; + +} + +#define V3D42_TRANSFORM_FEEDBACK_BUFFER_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_TRANSFORM_FEEDBACK_BUFFER_unpack(const uint8_t * restrict cl, + struct V3D42_TRANSFORM_FEEDBACK_BUFFER * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->buffer_address = __gen_unpack_address(cl, 40, 71); + values->buffer_size_in_32_bit_words = __gen_unpack_uint(cl, 10, 39); + values->buffer_number = __gen_unpack_uint(cl, 8, 9); +} +#endif + + +#define V3D42_TRANSFORM_FEEDBACK_SPECS_opcode 74 +#define V3D42_TRANSFORM_FEEDBACK_SPECS_header \ + .opcode = 74 + +struct V3D42_TRANSFORM_FEEDBACK_SPECS { + uint32_t opcode; + bool enable; + uint32_t number_of_16_bit_output_data_specs_following; +}; + +static inline void +V3D42_TRANSFORM_FEEDBACK_SPECS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TRANSFORM_FEEDBACK_SPECS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->enable, 7, 7) | + __gen_uint(values->number_of_16_bit_output_data_specs_following, 0, 4); + +} + +#define V3D42_TRANSFORM_FEEDBACK_SPECS_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_TRANSFORM_FEEDBACK_SPECS_unpack(const uint8_t * restrict cl, + struct V3D42_TRANSFORM_FEEDBACK_SPECS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->enable = __gen_unpack_uint(cl, 15, 15); + values->number_of_16_bit_output_data_specs_following = __gen_unpack_uint(cl, 8, 12); +} +#endif + + +#define V3D42_FLUSH_TRANSFORM_FEEDBACK_DATA_opcode 75 +#define V3D42_FLUSH_TRANSFORM_FEEDBACK_DATA_header\ + .opcode = 75 + +struct V3D42_FLUSH_TRANSFORM_FEEDBACK_DATA { + uint32_t opcode; +}; + +static inline void +V3D42_FLUSH_TRANSFORM_FEEDBACK_DATA_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_FLUSH_TRANSFORM_FEEDBACK_DATA * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_FLUSH_TRANSFORM_FEEDBACK_DATA_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_FLUSH_TRANSFORM_FEEDBACK_DATA_unpack(const uint8_t * restrict cl, + struct V3D42_FLUSH_TRANSFORM_FEEDBACK_DATA * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_header\ + + +struct V3D42_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC { + uint32_t first_shaded_vertex_value_to_output; + uint32_t number_of_consecutive_vertex_values_to_output_as_32_bit_values; + uint32_t output_buffer_to_write_to; + uint32_t stream_number; +}; + +static inline void +V3D42_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC * restrict values) +{ + assert(values->number_of_consecutive_vertex_values_to_output_as_32_bit_values >= 1); + cl[ 0] = __gen_uint(values->first_shaded_vertex_value_to_output, 0, 7); + + cl[ 1] = __gen_uint(values->number_of_consecutive_vertex_values_to_output_as_32_bit_values - 1, 0, 3) | + __gen_uint(values->output_buffer_to_write_to, 4, 5) | + __gen_uint(values->stream_number, 6, 7); + +} + +#define V3D42_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_unpack(const uint8_t * restrict cl, + struct V3D42_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC * restrict values) +{ + values->first_shaded_vertex_value_to_output = __gen_unpack_uint(cl, 0, 7); + values->number_of_consecutive_vertex_values_to_output_as_32_bit_values = __gen_unpack_uint(cl, 8, 11) + 1; + values->output_buffer_to_write_to = __gen_unpack_uint(cl, 12, 13); + values->stream_number = __gen_unpack_uint(cl, 14, 15); +} +#endif + + +#define V3D42_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_header\ + + +struct V3D42_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS { + __gen_address_type address; +}; + +static inline void +V3D42_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS * restrict values) +{ + __gen_emit_reloc(data, &values->address); + cl[ 0] = __gen_address_offset(&values->address); + + cl[ 1] = __gen_address_offset(&values->address) >> 8; + + cl[ 2] = __gen_address_offset(&values->address) >> 16; + + cl[ 3] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D42_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_length 4 +#ifdef __gen_unpack_address +static inline void +V3D42_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_unpack(const uint8_t * restrict cl, + struct V3D42_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS * restrict values) +{ + values->address = __gen_unpack_address(cl, 0, 31); +} +#endif + + +#define V3D42_STENCIL_CFG_opcode 80 +#define V3D42_STENCIL_CFG_header \ + .opcode = 80 + +struct V3D42_STENCIL_CFG { + uint32_t opcode; + uint32_t stencil_write_mask; + bool back_config; + bool front_config; + enum V3D42_Stencil_Op stencil_pass_op; + enum V3D42_Stencil_Op depth_test_fail_op; + enum V3D42_Stencil_Op stencil_test_fail_op; + enum V3D42_Compare_Function stencil_test_function; + uint32_t stencil_test_mask; + uint32_t stencil_ref_value; +}; + +static inline void +V3D42_STENCIL_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_STENCIL_CFG * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->stencil_ref_value, 0, 7); + + cl[ 2] = __gen_uint(values->stencil_test_mask, 0, 7); + + cl[ 3] = __gen_uint(values->depth_test_fail_op, 6, 8) | + __gen_uint(values->stencil_test_fail_op, 3, 5) | + __gen_uint(values->stencil_test_function, 0, 2); + + cl[ 4] = __gen_uint(values->back_config, 5, 5) | + __gen_uint(values->front_config, 4, 4) | + __gen_uint(values->stencil_pass_op, 1, 3) | + __gen_uint(values->depth_test_fail_op, 6, 8) >> 8; + + cl[ 5] = __gen_uint(values->stencil_write_mask, 0, 7); + +} + +#define V3D42_STENCIL_CFG_length 6 +#ifdef __gen_unpack_address +static inline void +V3D42_STENCIL_CFG_unpack(const uint8_t * restrict cl, + struct V3D42_STENCIL_CFG * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->stencil_write_mask = __gen_unpack_uint(cl, 40, 47); + values->back_config = __gen_unpack_uint(cl, 37, 37); + values->front_config = __gen_unpack_uint(cl, 36, 36); + values->stencil_pass_op = __gen_unpack_uint(cl, 33, 35); + values->depth_test_fail_op = __gen_unpack_uint(cl, 30, 32); + values->stencil_test_fail_op = __gen_unpack_uint(cl, 27, 29); + values->stencil_test_function = __gen_unpack_uint(cl, 24, 26); + values->stencil_test_mask = __gen_unpack_uint(cl, 16, 23); + values->stencil_ref_value = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D42_BLEND_ENABLES_opcode 83 +#define V3D42_BLEND_ENABLES_header \ + .opcode = 83 + +struct V3D42_BLEND_ENABLES { + uint32_t opcode; + uint32_t mask; +}; + +static inline void +V3D42_BLEND_ENABLES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_BLEND_ENABLES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->mask, 0, 7); + +} + +#define V3D42_BLEND_ENABLES_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_BLEND_ENABLES_unpack(const uint8_t * restrict cl, + struct V3D42_BLEND_ENABLES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->mask = __gen_unpack_uint(cl, 8, 15); +} +#endif + + +#define V3D42_BLEND_CFG_opcode 84 +#define V3D42_BLEND_CFG_header \ + .opcode = 84 + +struct V3D42_BLEND_CFG { + uint32_t opcode; + uint32_t render_target_mask; + enum V3D42_Blend_Factor color_blend_dst_factor; + enum V3D42_Blend_Factor color_blend_src_factor; + enum V3D42_Blend_Mode color_blend_mode; + enum V3D42_Blend_Factor alpha_blend_dst_factor; + enum V3D42_Blend_Factor alpha_blend_src_factor; + enum V3D42_Blend_Mode alpha_blend_mode; +}; + +static inline void +V3D42_BLEND_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_BLEND_CFG * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->alpha_blend_src_factor, 4, 7) | + __gen_uint(values->alpha_blend_mode, 0, 3); + + cl[ 2] = __gen_uint(values->color_blend_mode, 4, 7) | + __gen_uint(values->alpha_blend_dst_factor, 0, 3); + + cl[ 3] = __gen_uint(values->color_blend_dst_factor, 4, 7) | + __gen_uint(values->color_blend_src_factor, 0, 3); + + cl[ 4] = __gen_uint(values->render_target_mask, 0, 3); + +} + +#define V3D42_BLEND_CFG_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_BLEND_CFG_unpack(const uint8_t * restrict cl, + struct V3D42_BLEND_CFG * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->render_target_mask = __gen_unpack_uint(cl, 32, 35); + values->color_blend_dst_factor = __gen_unpack_uint(cl, 28, 31); + values->color_blend_src_factor = __gen_unpack_uint(cl, 24, 27); + values->color_blend_mode = __gen_unpack_uint(cl, 20, 23); + values->alpha_blend_dst_factor = __gen_unpack_uint(cl, 16, 19); + values->alpha_blend_src_factor = __gen_unpack_uint(cl, 12, 15); + values->alpha_blend_mode = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_BLEND_CONSTANT_COLOR_opcode 86 +#define V3D42_BLEND_CONSTANT_COLOR_header \ + .opcode = 86 + +struct V3D42_BLEND_CONSTANT_COLOR { + uint32_t opcode; + uint32_t alpha_f16; + uint32_t blue_f16; + uint32_t green_f16; + uint32_t red_f16; +}; + +static inline void +V3D42_BLEND_CONSTANT_COLOR_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_BLEND_CONSTANT_COLOR * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->red_f16, 0, 15); + + cl[ 2] = __gen_uint(values->red_f16, 0, 15) >> 8; + + cl[ 3] = __gen_uint(values->green_f16, 0, 15); + + cl[ 4] = __gen_uint(values->green_f16, 0, 15) >> 8; + + cl[ 5] = __gen_uint(values->blue_f16, 0, 15); + + cl[ 6] = __gen_uint(values->blue_f16, 0, 15) >> 8; + + cl[ 7] = __gen_uint(values->alpha_f16, 0, 15); + + cl[ 8] = __gen_uint(values->alpha_f16, 0, 15) >> 8; + +} + +#define V3D42_BLEND_CONSTANT_COLOR_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_BLEND_CONSTANT_COLOR_unpack(const uint8_t * restrict cl, + struct V3D42_BLEND_CONSTANT_COLOR * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->alpha_f16 = __gen_unpack_uint(cl, 56, 71); + values->blue_f16 = __gen_unpack_uint(cl, 40, 55); + values->green_f16 = __gen_unpack_uint(cl, 24, 39); + values->red_f16 = __gen_unpack_uint(cl, 8, 23); +} +#endif + + +#define V3D42_COLOR_WRITE_MASKS_opcode 87 +#define V3D42_COLOR_WRITE_MASKS_header \ + .opcode = 87 + +struct V3D42_COLOR_WRITE_MASKS { + uint32_t opcode; + uint32_t mask; +}; + +static inline void +V3D42_COLOR_WRITE_MASKS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_COLOR_WRITE_MASKS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->mask, sizeof(values->mask)); +} + +#define V3D42_COLOR_WRITE_MASKS_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_COLOR_WRITE_MASKS_unpack(const uint8_t * restrict cl, + struct V3D42_COLOR_WRITE_MASKS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->mask = __gen_unpack_uint(cl, 8, 39); +} +#endif + + +#define V3D42_ZERO_ALL_CENTROID_FLAGS_opcode 88 +#define V3D42_ZERO_ALL_CENTROID_FLAGS_header \ + .opcode = 88 + +struct V3D42_ZERO_ALL_CENTROID_FLAGS { + uint32_t opcode; +}; + +static inline void +V3D42_ZERO_ALL_CENTROID_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_ZERO_ALL_CENTROID_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_ZERO_ALL_CENTROID_FLAGS_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_ZERO_ALL_CENTROID_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D42_ZERO_ALL_CENTROID_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_CENTROID_FLAGS_opcode 89 +#define V3D42_CENTROID_FLAGS_header \ + .opcode = 89 + +struct V3D42_CENTROID_FLAGS { + uint32_t opcode; + uint32_t centroid_flags_for_varyings_v024; + enum V3D42_Varying_Flags_Action action_for_centroid_flags_of_higher_numbered_varyings; + enum V3D42_Varying_Flags_Action action_for_centroid_flags_of_lower_numbered_varyings; + uint32_t varying_offset_v0; +}; + +static inline void +V3D42_CENTROID_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_CENTROID_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->action_for_centroid_flags_of_higher_numbered_varyings, 6, 7) | + __gen_uint(values->action_for_centroid_flags_of_lower_numbered_varyings, 4, 5) | + __gen_uint(values->varying_offset_v0, 0, 3); + + cl[ 2] = __gen_uint(values->centroid_flags_for_varyings_v024, 0, 23); + + cl[ 3] = __gen_uint(values->centroid_flags_for_varyings_v024, 0, 23) >> 8; + + cl[ 4] = __gen_uint(values->centroid_flags_for_varyings_v024, 0, 23) >> 16; + +} + +#define V3D42_CENTROID_FLAGS_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_CENTROID_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D42_CENTROID_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->centroid_flags_for_varyings_v024 = __gen_unpack_uint(cl, 16, 39); + values->action_for_centroid_flags_of_higher_numbered_varyings = __gen_unpack_uint(cl, 14, 15); + values->action_for_centroid_flags_of_lower_numbered_varyings = __gen_unpack_uint(cl, 12, 13); + values->varying_offset_v0 = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_SAMPLE_STATE_opcode 91 +#define V3D42_SAMPLE_STATE_header \ + .opcode = 91 + +struct V3D42_SAMPLE_STATE { + uint32_t opcode; + float coverage; + uint32_t mask; +}; + +static inline void +V3D42_SAMPLE_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_SAMPLE_STATE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->mask, 0, 3); + + cl[ 2] = 0; + cl[ 3] = __gen_uint(fui(values->coverage) >> 16, 0, 15); + + cl[ 4] = __gen_uint(fui(values->coverage) >> 16, 0, 15) >> 8; + +} + +#define V3D42_SAMPLE_STATE_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_SAMPLE_STATE_unpack(const uint8_t * restrict cl, + struct V3D42_SAMPLE_STATE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->coverage = __gen_unpack_f187(cl, 24, 39); + values->mask = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_OCCLUSION_QUERY_COUNTER_opcode 92 +#define V3D42_OCCLUSION_QUERY_COUNTER_header \ + .opcode = 92 + +struct V3D42_OCCLUSION_QUERY_COUNTER { + uint32_t opcode; + __gen_address_type address; +}; + +static inline void +V3D42_OCCLUSION_QUERY_COUNTER_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_OCCLUSION_QUERY_COUNTER * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D42_OCCLUSION_QUERY_COUNTER_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_OCCLUSION_QUERY_COUNTER_unpack(const uint8_t * restrict cl, + struct V3D42_OCCLUSION_QUERY_COUNTER * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 8, 39); +} +#endif + + +#define V3D42_CFG_BITS_opcode 96 +#define V3D42_CFG_BITS_header \ + .opcode = 96 + +struct V3D42_CFG_BITS { + uint32_t opcode; + bool direct3d_provoking_vertex; + bool direct3d_point_fill_mode; + bool blend_enable; + bool stencil_enable; + bool early_z_updates_enable; + bool early_z_enable; + bool z_updates_enable; + enum V3D42_Compare_Function depth_test_function; + bool direct3d_wireframe_triangles_mode; + uint32_t rasterizer_oversample_mode; + uint32_t line_rasterization; + bool enable_depth_offset; + bool clockwise_primitives; + bool enable_reverse_facing_primitive; + bool enable_forward_facing_primitive; +}; + +static inline void +V3D42_CFG_BITS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_CFG_BITS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->rasterizer_oversample_mode, 6, 7) | + __gen_uint(values->line_rasterization, 4, 5) | + __gen_uint(values->enable_depth_offset, 3, 3) | + __gen_uint(values->clockwise_primitives, 2, 2) | + __gen_uint(values->enable_reverse_facing_primitive, 1, 1) | + __gen_uint(values->enable_forward_facing_primitive, 0, 0); + + cl[ 2] = __gen_uint(values->z_updates_enable, 7, 7) | + __gen_uint(values->depth_test_function, 4, 6) | + __gen_uint(values->direct3d_wireframe_triangles_mode, 3, 3); + + cl[ 3] = __gen_uint(values->direct3d_provoking_vertex, 5, 5) | + __gen_uint(values->direct3d_point_fill_mode, 4, 4) | + __gen_uint(values->blend_enable, 3, 3) | + __gen_uint(values->stencil_enable, 2, 2) | + __gen_uint(values->early_z_updates_enable, 1, 1) | + __gen_uint(values->early_z_enable, 0, 0); + +} + +#define V3D42_CFG_BITS_length 4 +#ifdef __gen_unpack_address +static inline void +V3D42_CFG_BITS_unpack(const uint8_t * restrict cl, + struct V3D42_CFG_BITS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->direct3d_provoking_vertex = __gen_unpack_uint(cl, 29, 29); + values->direct3d_point_fill_mode = __gen_unpack_uint(cl, 28, 28); + values->blend_enable = __gen_unpack_uint(cl, 27, 27); + values->stencil_enable = __gen_unpack_uint(cl, 26, 26); + values->early_z_updates_enable = __gen_unpack_uint(cl, 25, 25); + values->early_z_enable = __gen_unpack_uint(cl, 24, 24); + values->z_updates_enable = __gen_unpack_uint(cl, 23, 23); + values->depth_test_function = __gen_unpack_uint(cl, 20, 22); + values->direct3d_wireframe_triangles_mode = __gen_unpack_uint(cl, 19, 19); + values->rasterizer_oversample_mode = __gen_unpack_uint(cl, 14, 15); + values->line_rasterization = __gen_unpack_uint(cl, 12, 13); + values->enable_depth_offset = __gen_unpack_uint(cl, 11, 11); + values->clockwise_primitives = __gen_unpack_uint(cl, 10, 10); + values->enable_reverse_facing_primitive = __gen_unpack_uint(cl, 9, 9); + values->enable_forward_facing_primitive = __gen_unpack_uint(cl, 8, 8); +} +#endif + + +#define V3D42_ZERO_ALL_FLAT_SHADE_FLAGS_opcode 97 +#define V3D42_ZERO_ALL_FLAT_SHADE_FLAGS_header \ + .opcode = 97 + +struct V3D42_ZERO_ALL_FLAT_SHADE_FLAGS { + uint32_t opcode; +}; + +static inline void +V3D42_ZERO_ALL_FLAT_SHADE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_ZERO_ALL_FLAT_SHADE_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_ZERO_ALL_FLAT_SHADE_FLAGS_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_ZERO_ALL_FLAT_SHADE_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D42_ZERO_ALL_FLAT_SHADE_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_FLAT_SHADE_FLAGS_opcode 98 +#define V3D42_FLAT_SHADE_FLAGS_header \ + .opcode = 98 + +struct V3D42_FLAT_SHADE_FLAGS { + uint32_t opcode; + uint32_t flat_shade_flags_for_varyings_v024; + enum V3D42_Varying_Flags_Action action_for_flat_shade_flags_of_higher_numbered_varyings; + enum V3D42_Varying_Flags_Action action_for_flat_shade_flags_of_lower_numbered_varyings; + uint32_t varying_offset_v0; +}; + +static inline void +V3D42_FLAT_SHADE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_FLAT_SHADE_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->action_for_flat_shade_flags_of_higher_numbered_varyings, 6, 7) | + __gen_uint(values->action_for_flat_shade_flags_of_lower_numbered_varyings, 4, 5) | + __gen_uint(values->varying_offset_v0, 0, 3); + + cl[ 2] = __gen_uint(values->flat_shade_flags_for_varyings_v024, 0, 23); + + cl[ 3] = __gen_uint(values->flat_shade_flags_for_varyings_v024, 0, 23) >> 8; + + cl[ 4] = __gen_uint(values->flat_shade_flags_for_varyings_v024, 0, 23) >> 16; + +} + +#define V3D42_FLAT_SHADE_FLAGS_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_FLAT_SHADE_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D42_FLAT_SHADE_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->flat_shade_flags_for_varyings_v024 = __gen_unpack_uint(cl, 16, 39); + values->action_for_flat_shade_flags_of_higher_numbered_varyings = __gen_unpack_uint(cl, 14, 15); + values->action_for_flat_shade_flags_of_lower_numbered_varyings = __gen_unpack_uint(cl, 12, 13); + values->varying_offset_v0 = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_ZERO_ALL_NON_PERSPECTIVE_FLAGS_opcode 99 +#define V3D42_ZERO_ALL_NON_PERSPECTIVE_FLAGS_header\ + .opcode = 99 + +struct V3D42_ZERO_ALL_NON_PERSPECTIVE_FLAGS { + uint32_t opcode; +}; + +static inline void +V3D42_ZERO_ALL_NON_PERSPECTIVE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_ZERO_ALL_NON_PERSPECTIVE_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_ZERO_ALL_NON_PERSPECTIVE_FLAGS_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_ZERO_ALL_NON_PERSPECTIVE_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D42_ZERO_ALL_NON_PERSPECTIVE_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_NON_PERSPECTIVE_FLAGS_opcode 100 +#define V3D42_NON_PERSPECTIVE_FLAGS_header \ + .opcode = 100 + +struct V3D42_NON_PERSPECTIVE_FLAGS { + uint32_t opcode; + uint32_t non_perspective_flags_for_varyings_v024; + enum V3D42_Varying_Flags_Action action_for_non_perspective_flags_of_higher_numbered_varyings; + enum V3D42_Varying_Flags_Action action_for_non_perspective_flags_of_lower_numbered_varyings; + uint32_t varying_offset_v0; +}; + +static inline void +V3D42_NON_PERSPECTIVE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_NON_PERSPECTIVE_FLAGS * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->action_for_non_perspective_flags_of_higher_numbered_varyings, 6, 7) | + __gen_uint(values->action_for_non_perspective_flags_of_lower_numbered_varyings, 4, 5) | + __gen_uint(values->varying_offset_v0, 0, 3); + + cl[ 2] = __gen_uint(values->non_perspective_flags_for_varyings_v024, 0, 23); + + cl[ 3] = __gen_uint(values->non_perspective_flags_for_varyings_v024, 0, 23) >> 8; + + cl[ 4] = __gen_uint(values->non_perspective_flags_for_varyings_v024, 0, 23) >> 16; + +} + +#define V3D42_NON_PERSPECTIVE_FLAGS_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_NON_PERSPECTIVE_FLAGS_unpack(const uint8_t * restrict cl, + struct V3D42_NON_PERSPECTIVE_FLAGS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->non_perspective_flags_for_varyings_v024 = __gen_unpack_uint(cl, 16, 39); + values->action_for_non_perspective_flags_of_higher_numbered_varyings = __gen_unpack_uint(cl, 14, 15); + values->action_for_non_perspective_flags_of_lower_numbered_varyings = __gen_unpack_uint(cl, 12, 13); + values->varying_offset_v0 = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_POINT_SIZE_opcode 104 +#define V3D42_POINT_SIZE_header \ + .opcode = 104 + +struct V3D42_POINT_SIZE { + uint32_t opcode; + float point_size; +}; + +static inline void +V3D42_POINT_SIZE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_POINT_SIZE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->point_size, sizeof(values->point_size)); +} + +#define V3D42_POINT_SIZE_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_POINT_SIZE_unpack(const uint8_t * restrict cl, + struct V3D42_POINT_SIZE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->point_size = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D42_LINE_WIDTH_opcode 105 +#define V3D42_LINE_WIDTH_header \ + .opcode = 105 + +struct V3D42_LINE_WIDTH { + uint32_t opcode; + float line_width; +}; + +static inline void +V3D42_LINE_WIDTH_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_LINE_WIDTH * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->line_width, sizeof(values->line_width)); +} + +#define V3D42_LINE_WIDTH_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_LINE_WIDTH_unpack(const uint8_t * restrict cl, + struct V3D42_LINE_WIDTH * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->line_width = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D42_DEPTH_OFFSET_opcode 106 +#define V3D42_DEPTH_OFFSET_header \ + .opcode = 106 + +struct V3D42_DEPTH_OFFSET { + uint32_t opcode; + float limit; + float depth_offset_units; + float depth_offset_factor; +}; + +static inline void +V3D42_DEPTH_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_DEPTH_OFFSET * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(fui(values->depth_offset_factor) >> 16, 0, 15); + + cl[ 2] = __gen_uint(fui(values->depth_offset_factor) >> 16, 0, 15) >> 8; + + cl[ 3] = __gen_uint(fui(values->depth_offset_units) >> 16, 0, 15); + + cl[ 4] = __gen_uint(fui(values->depth_offset_units) >> 16, 0, 15) >> 8; + + + memcpy(&cl[5], &values->limit, sizeof(values->limit)); +} + +#define V3D42_DEPTH_OFFSET_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_DEPTH_OFFSET_unpack(const uint8_t * restrict cl, + struct V3D42_DEPTH_OFFSET * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->limit = __gen_unpack_float(cl, 40, 71); + values->depth_offset_units = __gen_unpack_f187(cl, 24, 39); + values->depth_offset_factor = __gen_unpack_f187(cl, 8, 23); +} +#endif + + +#define V3D42_CLIP_WINDOW_opcode 107 +#define V3D42_CLIP_WINDOW_header \ + .opcode = 107 + +struct V3D42_CLIP_WINDOW { + uint32_t opcode; + uint32_t clip_window_height_in_pixels; + uint32_t clip_window_width_in_pixels; + uint32_t clip_window_bottom_pixel_coordinate; + uint32_t clip_window_left_pixel_coordinate; +}; + +static inline void +V3D42_CLIP_WINDOW_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_CLIP_WINDOW * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->clip_window_left_pixel_coordinate, 0, 15); + + cl[ 2] = __gen_uint(values->clip_window_left_pixel_coordinate, 0, 15) >> 8; + + cl[ 3] = __gen_uint(values->clip_window_bottom_pixel_coordinate, 0, 15); + + cl[ 4] = __gen_uint(values->clip_window_bottom_pixel_coordinate, 0, 15) >> 8; + + cl[ 5] = __gen_uint(values->clip_window_width_in_pixels, 0, 15); + + cl[ 6] = __gen_uint(values->clip_window_width_in_pixels, 0, 15) >> 8; + + cl[ 7] = __gen_uint(values->clip_window_height_in_pixels, 0, 15); + + cl[ 8] = __gen_uint(values->clip_window_height_in_pixels, 0, 15) >> 8; + +} + +#define V3D42_CLIP_WINDOW_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_CLIP_WINDOW_unpack(const uint8_t * restrict cl, + struct V3D42_CLIP_WINDOW * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->clip_window_height_in_pixels = __gen_unpack_uint(cl, 56, 71); + values->clip_window_width_in_pixels = __gen_unpack_uint(cl, 40, 55); + values->clip_window_bottom_pixel_coordinate = __gen_unpack_uint(cl, 24, 39); + values->clip_window_left_pixel_coordinate = __gen_unpack_uint(cl, 8, 23); +} +#endif + + +#define V3D42_VIEWPORT_OFFSET_opcode 108 +#define V3D42_VIEWPORT_OFFSET_header \ + .opcode = 108 + +struct V3D42_VIEWPORT_OFFSET { + uint32_t opcode; + uint32_t coarse_y; + float viewport_centre_y_coordinate; + uint32_t coarse_x; + float viewport_centre_x_coordinate; +}; + +static inline void +V3D42_VIEWPORT_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_VIEWPORT_OFFSET * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_sfixed(values->viewport_centre_x_coordinate, 0, 21, 8); + + cl[ 2] = __gen_sfixed(values->viewport_centre_x_coordinate, 0, 21, 8) >> 8; + + cl[ 3] = __gen_uint(values->coarse_x, 6, 15) | + __gen_sfixed(values->viewport_centre_x_coordinate, 0, 21, 8) >> 16; + + cl[ 4] = __gen_uint(values->coarse_x, 6, 15) >> 8; + + cl[ 5] = __gen_sfixed(values->viewport_centre_y_coordinate, 0, 21, 8); + + cl[ 6] = __gen_sfixed(values->viewport_centre_y_coordinate, 0, 21, 8) >> 8; + + cl[ 7] = __gen_uint(values->coarse_y, 6, 15) | + __gen_sfixed(values->viewport_centre_y_coordinate, 0, 21, 8) >> 16; + + cl[ 8] = __gen_uint(values->coarse_y, 6, 15) >> 8; + +} + +#define V3D42_VIEWPORT_OFFSET_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_VIEWPORT_OFFSET_unpack(const uint8_t * restrict cl, + struct V3D42_VIEWPORT_OFFSET * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->coarse_y = __gen_unpack_uint(cl, 62, 71); + values->viewport_centre_y_coordinate = __gen_unpack_sfixed(cl, 40, 61, 8); + values->coarse_x = __gen_unpack_uint(cl, 30, 39); + values->viewport_centre_x_coordinate = __gen_unpack_sfixed(cl, 8, 29, 8); +} +#endif + + +#define V3D42_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_opcode 109 +#define V3D42_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_header\ + .opcode = 109 + +struct V3D42_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES { + uint32_t opcode; + float maximum_zw; + float minimum_zw; +}; + +static inline void +V3D42_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->minimum_zw, sizeof(values->minimum_zw)); + + memcpy(&cl[5], &values->maximum_zw, sizeof(values->maximum_zw)); +} + +#define V3D42_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_unpack(const uint8_t * restrict cl, + struct V3D42_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->maximum_zw = __gen_unpack_float(cl, 40, 71); + values->minimum_zw = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D42_CLIPPER_XY_SCALING_opcode 110 +#define V3D42_CLIPPER_XY_SCALING_header \ + .opcode = 110 + +struct V3D42_CLIPPER_XY_SCALING { + uint32_t opcode; + float viewport_half_height_in_1_256th_of_pixel; + float viewport_half_width_in_1_256th_of_pixel; +}; + +static inline void +V3D42_CLIPPER_XY_SCALING_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_CLIPPER_XY_SCALING * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->viewport_half_width_in_1_256th_of_pixel, sizeof(values->viewport_half_width_in_1_256th_of_pixel)); + + memcpy(&cl[5], &values->viewport_half_height_in_1_256th_of_pixel, sizeof(values->viewport_half_height_in_1_256th_of_pixel)); +} + +#define V3D42_CLIPPER_XY_SCALING_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_CLIPPER_XY_SCALING_unpack(const uint8_t * restrict cl, + struct V3D42_CLIPPER_XY_SCALING * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->viewport_half_height_in_1_256th_of_pixel = __gen_unpack_float(cl, 40, 71); + values->viewport_half_width_in_1_256th_of_pixel = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D42_CLIPPER_Z_SCALE_AND_OFFSET_opcode 111 +#define V3D42_CLIPPER_Z_SCALE_AND_OFFSET_header \ + .opcode = 111 + +struct V3D42_CLIPPER_Z_SCALE_AND_OFFSET { + uint32_t opcode; + float viewport_z_offset_zc_to_zs; + float viewport_z_scale_zc_to_zs; +}; + +static inline void +V3D42_CLIPPER_Z_SCALE_AND_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_CLIPPER_Z_SCALE_AND_OFFSET * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + + memcpy(&cl[1], &values->viewport_z_scale_zc_to_zs, sizeof(values->viewport_z_scale_zc_to_zs)); + + memcpy(&cl[5], &values->viewport_z_offset_zc_to_zs, sizeof(values->viewport_z_offset_zc_to_zs)); +} + +#define V3D42_CLIPPER_Z_SCALE_AND_OFFSET_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_CLIPPER_Z_SCALE_AND_OFFSET_unpack(const uint8_t * restrict cl, + struct V3D42_CLIPPER_Z_SCALE_AND_OFFSET * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->viewport_z_offset_zc_to_zs = __gen_unpack_float(cl, 40, 71); + values->viewport_z_scale_zc_to_zs = __gen_unpack_float(cl, 8, 39); +} +#endif + + +#define V3D42_NUMBER_OF_LAYERS_opcode 119 +#define V3D42_NUMBER_OF_LAYERS_header \ + .opcode = 119 + +struct V3D42_NUMBER_OF_LAYERS { + uint32_t opcode; + uint32_t number_of_layers; +}; + +static inline void +V3D42_NUMBER_OF_LAYERS_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_NUMBER_OF_LAYERS * restrict values) +{ + assert(values->number_of_layers >= 1); + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->number_of_layers - 1, 0, 7); + +} + +#define V3D42_NUMBER_OF_LAYERS_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_NUMBER_OF_LAYERS_unpack(const uint8_t * restrict cl, + struct V3D42_NUMBER_OF_LAYERS * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->number_of_layers = __gen_unpack_uint(cl, 8, 15) + 1; +} +#endif + + +#define V3D42_TILE_BINNING_MODE_CFG_opcode 120 +#define V3D42_TILE_BINNING_MODE_CFG_header \ + .opcode = 120 + +struct V3D42_TILE_BINNING_MODE_CFG { + uint32_t opcode; + uint32_t height_in_pixels; + uint32_t width_in_pixels; + bool double_buffer_in_non_ms_mode; + bool multisample_mode_4x; + uint32_t maximum_bpp_of_all_render_targets; +#define RENDER_TARGET_MAXIMUM_32BPP 0 +#define RENDER_TARGET_MAXIMUM_64BPP 1 +#define RENDER_TARGET_MAXIMUM_128BPP 2 + uint32_t number_of_render_targets; + uint32_t tile_allocation_block_size; +#define TILE_ALLOCATION_BLOCK_SIZE_64B 0 +#define TILE_ALLOCATION_BLOCK_SIZE_128B 1 +#define TILE_ALLOCATION_BLOCK_SIZE_256B 2 + uint32_t tile_allocation_initial_block_size; +#define TILE_ALLOCATION_INITIAL_BLOCK_SIZE_64B 0 +#define TILE_ALLOCATION_INITIAL_BLOCK_SIZE_128B 1 +#define TILE_ALLOCATION_INITIAL_BLOCK_SIZE_256B 2 +}; + +static inline void +V3D42_TILE_BINNING_MODE_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_BINNING_MODE_CFG * restrict values) +{ + assert(values->height_in_pixels >= 1); + assert(values->width_in_pixels >= 1); + assert(values->number_of_render_targets >= 1); + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->tile_allocation_block_size, 4, 5) | + __gen_uint(values->tile_allocation_initial_block_size, 2, 3); + + cl[ 2] = __gen_uint(values->double_buffer_in_non_ms_mode, 7, 7) | + __gen_uint(values->multisample_mode_4x, 6, 6) | + __gen_uint(values->maximum_bpp_of_all_render_targets, 4, 5) | + __gen_uint(values->number_of_render_targets - 1, 0, 3); + + cl[ 3] = 0; + cl[ 4] = 0; + cl[ 5] = __gen_uint(values->width_in_pixels - 1, 0, 11); + + cl[ 6] = __gen_uint(values->width_in_pixels - 1, 0, 11) >> 8; + + cl[ 7] = __gen_uint(values->height_in_pixels - 1, 0, 11); + + cl[ 8] = __gen_uint(values->height_in_pixels - 1, 0, 11) >> 8; + +} + +#define V3D42_TILE_BINNING_MODE_CFG_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_BINNING_MODE_CFG_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_BINNING_MODE_CFG * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->height_in_pixels = __gen_unpack_uint(cl, 56, 67) + 1; + values->width_in_pixels = __gen_unpack_uint(cl, 40, 51) + 1; + values->double_buffer_in_non_ms_mode = __gen_unpack_uint(cl, 23, 23); + values->multisample_mode_4x = __gen_unpack_uint(cl, 22, 22); + values->maximum_bpp_of_all_render_targets = __gen_unpack_uint(cl, 20, 21); + values->number_of_render_targets = __gen_unpack_uint(cl, 16, 19) + 1; + values->tile_allocation_block_size = __gen_unpack_uint(cl, 12, 13); + values->tile_allocation_initial_block_size = __gen_unpack_uint(cl, 10, 11); +} +#endif + + +#define V3D42_TILE_RENDERING_MODE_CFG_COMMON_opcode 121 +#define V3D42_TILE_RENDERING_MODE_CFG_COMMON_header\ + .opcode = 121, \ + .sub_id = 0 + +struct V3D42_TILE_RENDERING_MODE_CFG_COMMON { + uint32_t opcode; + uint32_t pad; + bool early_depth_stencil_clear; + enum V3D42_Internal_Depth_Type internal_depth_type; + bool early_z_disable; + uint32_t early_z_test_and_update_direction; +#define EARLY_Z_DIRECTION_LT_LE 0 +#define EARLY_Z_DIRECTION_GT_GE 1 + bool double_buffer_in_non_ms_mode; + bool multisample_mode_4x; + enum V3D42_Internal_BPP maximum_bpp_of_all_render_targets; + uint32_t image_height_pixels; + uint32_t image_width_pixels; + uint32_t number_of_render_targets; + uint32_t sub_id; +}; + +static inline void +V3D42_TILE_RENDERING_MODE_CFG_COMMON_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_RENDERING_MODE_CFG_COMMON * restrict values) +{ + assert(values->number_of_render_targets >= 1); + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->number_of_render_targets - 1, 4, 7) | + __gen_uint(values->sub_id, 0, 3); + + cl[ 2] = __gen_uint(values->image_width_pixels, 0, 15); + + cl[ 3] = __gen_uint(values->image_width_pixels, 0, 15) >> 8; + + cl[ 4] = __gen_uint(values->image_height_pixels, 0, 15); + + cl[ 5] = __gen_uint(values->image_height_pixels, 0, 15) >> 8; + + cl[ 6] = __gen_uint(values->internal_depth_type, 7, 10) | + __gen_uint(values->early_z_disable, 6, 6) | + __gen_uint(values->early_z_test_and_update_direction, 5, 5) | + __gen_uint(values->double_buffer_in_non_ms_mode, 3, 3) | + __gen_uint(values->multisample_mode_4x, 2, 2) | + __gen_uint(values->maximum_bpp_of_all_render_targets, 0, 1); + + cl[ 7] = __gen_uint(values->pad, 4, 15) | + __gen_uint(values->early_depth_stencil_clear, 3, 3) | + __gen_uint(values->internal_depth_type, 7, 10) >> 8; + + cl[ 8] = __gen_uint(values->pad, 4, 15) >> 8; + +} + +#define V3D42_TILE_RENDERING_MODE_CFG_COMMON_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_RENDERING_MODE_CFG_COMMON_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_RENDERING_MODE_CFG_COMMON * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->pad = __gen_unpack_uint(cl, 60, 71); + values->early_depth_stencil_clear = __gen_unpack_uint(cl, 59, 59); + values->internal_depth_type = __gen_unpack_uint(cl, 55, 58); + values->early_z_disable = __gen_unpack_uint(cl, 54, 54); + values->early_z_test_and_update_direction = __gen_unpack_uint(cl, 53, 53); + values->double_buffer_in_non_ms_mode = __gen_unpack_uint(cl, 51, 51); + values->multisample_mode_4x = __gen_unpack_uint(cl, 50, 50); + values->maximum_bpp_of_all_render_targets = __gen_unpack_uint(cl, 48, 49); + values->image_height_pixels = __gen_unpack_uint(cl, 32, 47); + values->image_width_pixels = __gen_unpack_uint(cl, 16, 31); + values->number_of_render_targets = __gen_unpack_uint(cl, 12, 15) + 1; + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_TILE_RENDERING_MODE_CFG_COLOR_opcode 121 +#define V3D42_TILE_RENDERING_MODE_CFG_COLOR_header\ + .opcode = 121, \ + .sub_id = 1 + +struct V3D42_TILE_RENDERING_MODE_CFG_COLOR { + uint32_t opcode; + uint32_t pad; + enum V3D42_Render_Target_Clamp render_target_3_clamp; + enum V3D42_Internal_Type render_target_3_internal_type; + enum V3D42_Internal_BPP render_target_3_internal_bpp; + enum V3D42_Render_Target_Clamp render_target_2_clamp; + enum V3D42_Internal_Type render_target_2_internal_type; + enum V3D42_Internal_BPP render_target_2_internal_bpp; + enum V3D42_Render_Target_Clamp render_target_1_clamp; + enum V3D42_Internal_Type render_target_1_internal_type; + enum V3D42_Internal_BPP render_target_1_internal_bpp; + enum V3D42_Render_Target_Clamp render_target_0_clamp; + enum V3D42_Internal_Type render_target_0_internal_type; + enum V3D42_Internal_BPP render_target_0_internal_bpp; + uint32_t sub_id; +}; + +static inline void +V3D42_TILE_RENDERING_MODE_CFG_COLOR_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_RENDERING_MODE_CFG_COLOR * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->render_target_0_internal_type, 6, 9) | + __gen_uint(values->render_target_0_internal_bpp, 4, 5) | + __gen_uint(values->sub_id, 0, 3); + + cl[ 2] = __gen_uint(values->render_target_1_internal_type, 6, 9) | + __gen_uint(values->render_target_1_internal_bpp, 4, 5) | + __gen_uint(values->render_target_0_clamp, 2, 3) | + __gen_uint(values->render_target_0_internal_type, 6, 9) >> 8; + + cl[ 3] = __gen_uint(values->render_target_2_internal_type, 6, 9) | + __gen_uint(values->render_target_2_internal_bpp, 4, 5) | + __gen_uint(values->render_target_1_clamp, 2, 3) | + __gen_uint(values->render_target_1_internal_type, 6, 9) >> 8; + + cl[ 4] = __gen_uint(values->render_target_3_internal_type, 6, 9) | + __gen_uint(values->render_target_3_internal_bpp, 4, 5) | + __gen_uint(values->render_target_2_clamp, 2, 3) | + __gen_uint(values->render_target_2_internal_type, 6, 9) >> 8; + + cl[ 5] = __gen_uint(values->pad, 2, 29) | + __gen_uint(values->render_target_3_clamp, 0, 1) | + __gen_uint(values->render_target_3_internal_type, 6, 9) >> 8; + + cl[ 6] = __gen_uint(values->pad, 2, 29) >> 8; + + cl[ 7] = __gen_uint(values->pad, 2, 29) >> 16; + + cl[ 8] = __gen_uint(values->pad, 2, 29) >> 24; + +} + +#define V3D42_TILE_RENDERING_MODE_CFG_COLOR_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_RENDERING_MODE_CFG_COLOR_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_RENDERING_MODE_CFG_COLOR * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->pad = __gen_unpack_uint(cl, 42, 69); + values->render_target_3_clamp = __gen_unpack_uint(cl, 40, 41); + values->render_target_3_internal_type = __gen_unpack_uint(cl, 38, 41); + values->render_target_3_internal_bpp = __gen_unpack_uint(cl, 36, 37); + values->render_target_2_clamp = __gen_unpack_uint(cl, 34, 35); + values->render_target_2_internal_type = __gen_unpack_uint(cl, 30, 33); + values->render_target_2_internal_bpp = __gen_unpack_uint(cl, 28, 29); + values->render_target_1_clamp = __gen_unpack_uint(cl, 26, 27); + values->render_target_1_internal_type = __gen_unpack_uint(cl, 22, 25); + values->render_target_1_internal_bpp = __gen_unpack_uint(cl, 20, 21); + values->render_target_0_clamp = __gen_unpack_uint(cl, 18, 19); + values->render_target_0_internal_type = __gen_unpack_uint(cl, 14, 17); + values->render_target_0_internal_bpp = __gen_unpack_uint(cl, 12, 13); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_opcode 121 +#define V3D42_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_header\ + .opcode = 121, \ + .sub_id = 2 + +struct V3D42_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES { + uint32_t opcode; + uint32_t unused; + float z_clear_value; + uint32_t stencil_clear_value; + uint32_t sub_id; +}; + +static inline void +V3D42_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->sub_id, 0, 3); + + cl[ 2] = __gen_uint(values->stencil_clear_value, 0, 7); + + + memcpy(&cl[3], &values->z_clear_value, sizeof(values->z_clear_value)); + cl[ 7] = __gen_uint(values->unused, 0, 15); + + cl[ 8] = __gen_uint(values->unused, 0, 15) >> 8; + +} + +#define V3D42_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->unused = __gen_unpack_uint(cl, 56, 71); + values->z_clear_value = __gen_unpack_float(cl, 24, 55); + values->stencil_clear_value = __gen_unpack_uint(cl, 16, 23); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_opcode 121 +#define V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_header\ + .opcode = 121, \ + .sub_id = 3 + +struct V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1 { + uint32_t opcode; + uint32_t clear_color_next_24_bits; + uint32_t clear_color_low_32_bits; + uint32_t render_target_number; + uint32_t sub_id; +}; + +static inline void +V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1 * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->render_target_number, 4, 7) | + __gen_uint(values->sub_id, 0, 3); + + + memcpy(&cl[2], &values->clear_color_low_32_bits, sizeof(values->clear_color_low_32_bits)); + cl[ 6] = __gen_uint(values->clear_color_next_24_bits, 0, 23); + + cl[ 7] = __gen_uint(values->clear_color_next_24_bits, 0, 23) >> 8; + + cl[ 8] = __gen_uint(values->clear_color_next_24_bits, 0, 23) >> 16; + +} + +#define V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART1 * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->clear_color_next_24_bits = __gen_unpack_uint(cl, 48, 71); + values->clear_color_low_32_bits = __gen_unpack_uint(cl, 16, 47); + values->render_target_number = __gen_unpack_uint(cl, 12, 15); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_opcode 121 +#define V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_header\ + .opcode = 121, \ + .sub_id = 4 + +struct V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2 { + uint32_t opcode; + uint32_t clear_color_mid_high_24_bits; + uint32_t clear_color_mid_low_32_bits; + uint32_t render_target_number; + uint32_t sub_id; +}; + +static inline void +V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2 * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->render_target_number, 4, 7) | + __gen_uint(values->sub_id, 0, 3); + + + memcpy(&cl[2], &values->clear_color_mid_low_32_bits, sizeof(values->clear_color_mid_low_32_bits)); + cl[ 6] = __gen_uint(values->clear_color_mid_high_24_bits, 0, 23); + + cl[ 7] = __gen_uint(values->clear_color_mid_high_24_bits, 0, 23) >> 8; + + cl[ 8] = __gen_uint(values->clear_color_mid_high_24_bits, 0, 23) >> 16; + +} + +#define V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2 * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->clear_color_mid_high_24_bits = __gen_unpack_uint(cl, 48, 71); + values->clear_color_mid_low_32_bits = __gen_unpack_uint(cl, 16, 47); + values->render_target_number = __gen_unpack_uint(cl, 12, 15); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_opcode 121 +#define V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_header\ + .opcode = 121, \ + .sub_id = 5 + +struct V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3 { + uint32_t opcode; + uint32_t pad; + uint32_t uif_padded_height_in_uif_blocks; + uint32_t raster_row_stride_or_image_height_in_pixels; + uint32_t clear_color_high_16_bits; + uint32_t render_target_number; + uint32_t sub_id; +}; + +static inline void +V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3 * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->render_target_number, 4, 7) | + __gen_uint(values->sub_id, 0, 3); + + cl[ 2] = __gen_uint(values->clear_color_high_16_bits, 0, 15); + + cl[ 3] = __gen_uint(values->clear_color_high_16_bits, 0, 15) >> 8; + + cl[ 4] = __gen_uint(values->raster_row_stride_or_image_height_in_pixels, 0, 15); + + cl[ 5] = __gen_uint(values->raster_row_stride_or_image_height_in_pixels, 0, 15) >> 8; + + cl[ 6] = __gen_uint(values->uif_padded_height_in_uif_blocks, 0, 12); + + cl[ 7] = __gen_uint(values->pad, 5, 15) | + __gen_uint(values->uif_padded_height_in_uif_blocks, 0, 12) >> 8; + + cl[ 8] = __gen_uint(values->pad, 5, 15) >> 8; + +} + +#define V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3 * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->pad = __gen_unpack_uint(cl, 61, 71); + values->uif_padded_height_in_uif_blocks = __gen_unpack_uint(cl, 48, 60); + values->raster_row_stride_or_image_height_in_pixels = __gen_unpack_uint(cl, 32, 47); + values->clear_color_high_16_bits = __gen_unpack_uint(cl, 16, 31); + values->render_target_number = __gen_unpack_uint(cl, 12, 15); + values->sub_id = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_TILE_COORDINATES_opcode 124 +#define V3D42_TILE_COORDINATES_header \ + .opcode = 124 + +struct V3D42_TILE_COORDINATES { + uint32_t opcode; + uint32_t tile_row_number; + uint32_t tile_column_number; +}; + +static inline void +V3D42_TILE_COORDINATES_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_COORDINATES * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->tile_column_number, 0, 11); + + cl[ 2] = __gen_uint(values->tile_row_number, 4, 15) | + __gen_uint(values->tile_column_number, 0, 11) >> 8; + + cl[ 3] = __gen_uint(values->tile_row_number, 4, 15) >> 8; + +} + +#define V3D42_TILE_COORDINATES_length 4 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_COORDINATES_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_COORDINATES * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->tile_row_number = __gen_unpack_uint(cl, 20, 31); + values->tile_column_number = __gen_unpack_uint(cl, 8, 19); +} +#endif + + +#define V3D42_MULTICORE_RENDERING_SUPERTILE_CFG_opcode 122 +#define V3D42_MULTICORE_RENDERING_SUPERTILE_CFG_header\ + .opcode = 122 + +struct V3D42_MULTICORE_RENDERING_SUPERTILE_CFG { + uint32_t opcode; + uint32_t number_of_bin_tile_lists; + bool supertile_raster_order; + bool multicore_enable; + uint32_t total_frame_height_in_tiles; + uint32_t total_frame_width_in_tiles; + uint32_t total_frame_height_in_supertiles; + uint32_t total_frame_width_in_supertiles; + uint32_t supertile_height_in_tiles; + uint32_t supertile_width_in_tiles; +}; + +static inline void +V3D42_MULTICORE_RENDERING_SUPERTILE_CFG_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_MULTICORE_RENDERING_SUPERTILE_CFG * restrict values) +{ + assert(values->number_of_bin_tile_lists >= 1); + assert(values->supertile_height_in_tiles >= 1); + assert(values->supertile_width_in_tiles >= 1); + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->supertile_width_in_tiles - 1, 0, 7); + + cl[ 2] = __gen_uint(values->supertile_height_in_tiles - 1, 0, 7); + + cl[ 3] = __gen_uint(values->total_frame_width_in_supertiles, 0, 7); + + cl[ 4] = __gen_uint(values->total_frame_height_in_supertiles, 0, 7); + + cl[ 5] = __gen_uint(values->total_frame_width_in_tiles, 0, 11); + + cl[ 6] = __gen_uint(values->total_frame_height_in_tiles, 4, 15) | + __gen_uint(values->total_frame_width_in_tiles, 0, 11) >> 8; + + cl[ 7] = __gen_uint(values->total_frame_height_in_tiles, 4, 15) >> 8; + + cl[ 8] = __gen_uint(values->number_of_bin_tile_lists - 1, 5, 7) | + __gen_uint(values->supertile_raster_order, 4, 4) | + __gen_uint(values->multicore_enable, 0, 0); + +} + +#define V3D42_MULTICORE_RENDERING_SUPERTILE_CFG_length 9 +#ifdef __gen_unpack_address +static inline void +V3D42_MULTICORE_RENDERING_SUPERTILE_CFG_unpack(const uint8_t * restrict cl, + struct V3D42_MULTICORE_RENDERING_SUPERTILE_CFG * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->number_of_bin_tile_lists = __gen_unpack_uint(cl, 69, 71) + 1; + values->supertile_raster_order = __gen_unpack_uint(cl, 68, 68); + values->multicore_enable = __gen_unpack_uint(cl, 64, 64); + values->total_frame_height_in_tiles = __gen_unpack_uint(cl, 52, 63); + values->total_frame_width_in_tiles = __gen_unpack_uint(cl, 40, 51); + values->total_frame_height_in_supertiles = __gen_unpack_uint(cl, 32, 39); + values->total_frame_width_in_supertiles = __gen_unpack_uint(cl, 24, 31); + values->supertile_height_in_tiles = __gen_unpack_uint(cl, 16, 23) + 1; + values->supertile_width_in_tiles = __gen_unpack_uint(cl, 8, 15) + 1; +} +#endif + + +#define V3D42_MULTICORE_RENDERING_TILE_LIST_SET_BASE_opcode 123 +#define V3D42_MULTICORE_RENDERING_TILE_LIST_SET_BASE_header\ + .opcode = 123 + +struct V3D42_MULTICORE_RENDERING_TILE_LIST_SET_BASE { + uint32_t opcode; + __gen_address_type address; + uint32_t tile_list_set_number; +}; + +static inline void +V3D42_MULTICORE_RENDERING_TILE_LIST_SET_BASE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_MULTICORE_RENDERING_TILE_LIST_SET_BASE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + __gen_emit_reloc(data, &values->address); + cl[ 1] = __gen_address_offset(&values->address) | + __gen_uint(values->tile_list_set_number, 0, 3); + + cl[ 2] = __gen_address_offset(&values->address) >> 8; + + cl[ 3] = __gen_address_offset(&values->address) >> 16; + + cl[ 4] = __gen_address_offset(&values->address) >> 24; + +} + +#define V3D42_MULTICORE_RENDERING_TILE_LIST_SET_BASE_length 5 +#ifdef __gen_unpack_address +static inline void +V3D42_MULTICORE_RENDERING_TILE_LIST_SET_BASE_unpack(const uint8_t * restrict cl, + struct V3D42_MULTICORE_RENDERING_TILE_LIST_SET_BASE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->address = __gen_unpack_address(cl, 14, 39); + values->tile_list_set_number = __gen_unpack_uint(cl, 8, 11); +} +#endif + + +#define V3D42_TILE_COORDINATES_IMPLICIT_opcode 125 +#define V3D42_TILE_COORDINATES_IMPLICIT_header \ + .opcode = 125 + +struct V3D42_TILE_COORDINATES_IMPLICIT { + uint32_t opcode; +}; + +static inline void +V3D42_TILE_COORDINATES_IMPLICIT_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_COORDINATES_IMPLICIT * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + +} + +#define V3D42_TILE_COORDINATES_IMPLICIT_length 1 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_COORDINATES_IMPLICIT_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_COORDINATES_IMPLICIT * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); +} +#endif + + +#define V3D42_TILE_LIST_INITIAL_BLOCK_SIZE_opcode 126 +#define V3D42_TILE_LIST_INITIAL_BLOCK_SIZE_header\ + .opcode = 126 + +struct V3D42_TILE_LIST_INITIAL_BLOCK_SIZE { + uint32_t opcode; + bool use_auto_chained_tile_lists; + uint32_t size_of_first_block_in_chained_tile_lists; +#define TILE_ALLOCATION_BLOCK_SIZE_64B 0 +#define TILE_ALLOCATION_BLOCK_SIZE_128B 1 +#define TILE_ALLOCATION_BLOCK_SIZE_256B 2 +}; + +static inline void +V3D42_TILE_LIST_INITIAL_BLOCK_SIZE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TILE_LIST_INITIAL_BLOCK_SIZE * restrict values) +{ + cl[ 0] = __gen_uint(values->opcode, 0, 7); + + cl[ 1] = __gen_uint(values->use_auto_chained_tile_lists, 2, 2) | + __gen_uint(values->size_of_first_block_in_chained_tile_lists, 0, 1); + +} + +#define V3D42_TILE_LIST_INITIAL_BLOCK_SIZE_length 2 +#ifdef __gen_unpack_address +static inline void +V3D42_TILE_LIST_INITIAL_BLOCK_SIZE_unpack(const uint8_t * restrict cl, + struct V3D42_TILE_LIST_INITIAL_BLOCK_SIZE * restrict values) +{ + values->opcode = __gen_unpack_uint(cl, 0, 7); + values->use_auto_chained_tile_lists = __gen_unpack_uint(cl, 10, 10); + values->size_of_first_block_in_chained_tile_lists = __gen_unpack_uint(cl, 8, 9); +} +#endif + + +#define V3D42_GL_SHADER_STATE_RECORD_header \ + + +struct V3D42_GL_SHADER_STATE_RECORD { + bool point_size_in_shaded_vertex_data; + bool enable_clipping; + bool vertex_id_read_by_coordinate_shader; + bool instance_id_read_by_coordinate_shader; + bool base_instance_id_read_by_coordinate_shader; + bool vertex_id_read_by_vertex_shader; + bool instance_id_read_by_vertex_shader; + bool base_instance_id_read_by_vertex_shader; + bool fragment_shader_does_z_writes; + bool turn_off_early_z_test; + bool coordinate_shader_has_separate_input_and_output_vpm_blocks; + bool vertex_shader_has_separate_input_and_output_vpm_blocks; + bool fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2; + bool enable_sample_rate_shading; + bool any_shader_reads_hardware_written_primitive_id; + bool insert_primitive_id_as_first_varying_to_fragment_shader; + bool turn_off_scoreboard; + bool do_scoreboard_wait_on_first_thread_switch; + bool disable_implicit_point_line_varyings; + bool no_prim_pack; + uint32_t number_of_varyings_in_fragment_shader; + uint32_t coordinate_shader_output_vpm_segment_size; + uint32_t min_coord_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size; + uint32_t coordinate_shader_input_vpm_segment_size; + uint32_t min_coord_shader_input_segments_required_in_play; + uint32_t vertex_shader_output_vpm_segment_size; + uint32_t min_vertex_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size; + uint32_t vertex_shader_input_vpm_segment_size; + uint32_t min_vertex_shader_input_segments_required_in_play; + __gen_address_type address_of_default_attribute_values; + __gen_address_type fragment_shader_code_address; + bool fragment_shader_4_way_threadable; + bool fragment_shader_start_in_final_thread_section; + bool fragment_shader_propagate_nans; + __gen_address_type fragment_shader_uniforms_address; + __gen_address_type vertex_shader_code_address; + bool vertex_shader_4_way_threadable; + bool vertex_shader_start_in_final_thread_section; + bool vertex_shader_propagate_nans; + __gen_address_type vertex_shader_uniforms_address; + __gen_address_type coordinate_shader_code_address; + bool coordinate_shader_4_way_threadable; + bool coordinate_shader_start_in_final_thread_section; + bool coordinate_shader_propagate_nans; + __gen_address_type coordinate_shader_uniforms_address; +}; + +static inline void +V3D42_GL_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_GL_SHADER_STATE_RECORD * restrict values) +{ + assert(values->min_coord_shader_input_segments_required_in_play >= 1); + assert(values->min_vertex_shader_input_segments_required_in_play >= 1); + cl[ 0] = __gen_uint(values->point_size_in_shaded_vertex_data, 0, 0) | + __gen_uint(values->enable_clipping, 1, 1) | + __gen_uint(values->vertex_id_read_by_coordinate_shader, 2, 2) | + __gen_uint(values->instance_id_read_by_coordinate_shader, 3, 3) | + __gen_uint(values->base_instance_id_read_by_coordinate_shader, 4, 4) | + __gen_uint(values->vertex_id_read_by_vertex_shader, 5, 5) | + __gen_uint(values->instance_id_read_by_vertex_shader, 6, 6) | + __gen_uint(values->base_instance_id_read_by_vertex_shader, 7, 7); + + cl[ 1] = __gen_uint(values->fragment_shader_does_z_writes, 0, 0) | + __gen_uint(values->turn_off_early_z_test, 1, 1) | + __gen_uint(values->coordinate_shader_has_separate_input_and_output_vpm_blocks, 2, 2) | + __gen_uint(values->vertex_shader_has_separate_input_and_output_vpm_blocks, 3, 3) | + __gen_uint(values->fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2, 4, 4) | + __gen_uint(values->enable_sample_rate_shading, 5, 5) | + __gen_uint(values->any_shader_reads_hardware_written_primitive_id, 6, 6) | + __gen_uint(values->insert_primitive_id_as_first_varying_to_fragment_shader, 7, 7); + + cl[ 2] = __gen_uint(values->turn_off_scoreboard, 0, 0) | + __gen_uint(values->do_scoreboard_wait_on_first_thread_switch, 1, 1) | + __gen_uint(values->disable_implicit_point_line_varyings, 2, 2) | + __gen_uint(values->no_prim_pack, 3, 3); + + cl[ 3] = __gen_uint(values->number_of_varyings_in_fragment_shader, 0, 7); + + cl[ 4] = __gen_uint(values->coordinate_shader_output_vpm_segment_size, 0, 3) | + __gen_uint(values->min_coord_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size, 4, 7); + + cl[ 5] = __gen_uint(values->coordinate_shader_input_vpm_segment_size, 0, 3) | + __gen_uint(values->min_coord_shader_input_segments_required_in_play - 1, 4, 7); + + cl[ 6] = __gen_uint(values->vertex_shader_output_vpm_segment_size, 0, 3) | + __gen_uint(values->min_vertex_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size, 4, 7); + + cl[ 7] = __gen_uint(values->vertex_shader_input_vpm_segment_size, 0, 3) | + __gen_uint(values->min_vertex_shader_input_segments_required_in_play - 1, 4, 7); + + __gen_emit_reloc(data, &values->address_of_default_attribute_values); + cl[ 8] = __gen_address_offset(&values->address_of_default_attribute_values); + + cl[ 9] = __gen_address_offset(&values->address_of_default_attribute_values) >> 8; + + cl[10] = __gen_address_offset(&values->address_of_default_attribute_values) >> 16; + + cl[11] = __gen_address_offset(&values->address_of_default_attribute_values) >> 24; + + __gen_emit_reloc(data, &values->fragment_shader_code_address); + cl[12] = __gen_address_offset(&values->fragment_shader_code_address) | + __gen_uint(values->fragment_shader_4_way_threadable, 0, 0) | + __gen_uint(values->fragment_shader_start_in_final_thread_section, 1, 1) | + __gen_uint(values->fragment_shader_propagate_nans, 2, 2); + + cl[13] = __gen_address_offset(&values->fragment_shader_code_address) >> 8; + + cl[14] = __gen_address_offset(&values->fragment_shader_code_address) >> 16; + + cl[15] = __gen_address_offset(&values->fragment_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->fragment_shader_uniforms_address); + cl[16] = __gen_address_offset(&values->fragment_shader_uniforms_address); + + cl[17] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 8; + + cl[18] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 16; + + cl[19] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->vertex_shader_code_address); + cl[20] = __gen_address_offset(&values->vertex_shader_code_address) | + __gen_uint(values->vertex_shader_4_way_threadable, 0, 0) | + __gen_uint(values->vertex_shader_start_in_final_thread_section, 1, 1) | + __gen_uint(values->vertex_shader_propagate_nans, 2, 2); + + cl[21] = __gen_address_offset(&values->vertex_shader_code_address) >> 8; + + cl[22] = __gen_address_offset(&values->vertex_shader_code_address) >> 16; + + cl[23] = __gen_address_offset(&values->vertex_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->vertex_shader_uniforms_address); + cl[24] = __gen_address_offset(&values->vertex_shader_uniforms_address); + + cl[25] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 8; + + cl[26] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 16; + + cl[27] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->coordinate_shader_code_address); + cl[28] = __gen_address_offset(&values->coordinate_shader_code_address) | + __gen_uint(values->coordinate_shader_4_way_threadable, 0, 0) | + __gen_uint(values->coordinate_shader_start_in_final_thread_section, 1, 1) | + __gen_uint(values->coordinate_shader_propagate_nans, 2, 2); + + cl[29] = __gen_address_offset(&values->coordinate_shader_code_address) >> 8; + + cl[30] = __gen_address_offset(&values->coordinate_shader_code_address) >> 16; + + cl[31] = __gen_address_offset(&values->coordinate_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->coordinate_shader_uniforms_address); + cl[32] = __gen_address_offset(&values->coordinate_shader_uniforms_address); + + cl[33] = __gen_address_offset(&values->coordinate_shader_uniforms_address) >> 8; + + cl[34] = __gen_address_offset(&values->coordinate_shader_uniforms_address) >> 16; + + cl[35] = __gen_address_offset(&values->coordinate_shader_uniforms_address) >> 24; + +} + +#define V3D42_GL_SHADER_STATE_RECORD_length 36 +#ifdef __gen_unpack_address +static inline void +V3D42_GL_SHADER_STATE_RECORD_unpack(const uint8_t * restrict cl, + struct V3D42_GL_SHADER_STATE_RECORD * restrict values) +{ + values->point_size_in_shaded_vertex_data = __gen_unpack_uint(cl, 0, 0); + values->enable_clipping = __gen_unpack_uint(cl, 1, 1); + values->vertex_id_read_by_coordinate_shader = __gen_unpack_uint(cl, 2, 2); + values->instance_id_read_by_coordinate_shader = __gen_unpack_uint(cl, 3, 3); + values->base_instance_id_read_by_coordinate_shader = __gen_unpack_uint(cl, 4, 4); + values->vertex_id_read_by_vertex_shader = __gen_unpack_uint(cl, 5, 5); + values->instance_id_read_by_vertex_shader = __gen_unpack_uint(cl, 6, 6); + values->base_instance_id_read_by_vertex_shader = __gen_unpack_uint(cl, 7, 7); + values->fragment_shader_does_z_writes = __gen_unpack_uint(cl, 8, 8); + values->turn_off_early_z_test = __gen_unpack_uint(cl, 9, 9); + values->coordinate_shader_has_separate_input_and_output_vpm_blocks = __gen_unpack_uint(cl, 10, 10); + values->vertex_shader_has_separate_input_and_output_vpm_blocks = __gen_unpack_uint(cl, 11, 11); + values->fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2 = __gen_unpack_uint(cl, 12, 12); + values->enable_sample_rate_shading = __gen_unpack_uint(cl, 13, 13); + values->any_shader_reads_hardware_written_primitive_id = __gen_unpack_uint(cl, 14, 14); + values->insert_primitive_id_as_first_varying_to_fragment_shader = __gen_unpack_uint(cl, 15, 15); + values->turn_off_scoreboard = __gen_unpack_uint(cl, 16, 16); + values->do_scoreboard_wait_on_first_thread_switch = __gen_unpack_uint(cl, 17, 17); + values->disable_implicit_point_line_varyings = __gen_unpack_uint(cl, 18, 18); + values->no_prim_pack = __gen_unpack_uint(cl, 19, 19); + values->number_of_varyings_in_fragment_shader = __gen_unpack_uint(cl, 24, 31); + values->coordinate_shader_output_vpm_segment_size = __gen_unpack_uint(cl, 32, 35); + values->min_coord_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size = __gen_unpack_uint(cl, 36, 39); + values->coordinate_shader_input_vpm_segment_size = __gen_unpack_uint(cl, 40, 43); + values->min_coord_shader_input_segments_required_in_play = __gen_unpack_uint(cl, 44, 47) + 1; + values->vertex_shader_output_vpm_segment_size = __gen_unpack_uint(cl, 48, 51); + values->min_vertex_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size = __gen_unpack_uint(cl, 52, 55); + values->vertex_shader_input_vpm_segment_size = __gen_unpack_uint(cl, 56, 59); + values->min_vertex_shader_input_segments_required_in_play = __gen_unpack_uint(cl, 60, 63) + 1; + values->address_of_default_attribute_values = __gen_unpack_address(cl, 64, 95); + values->fragment_shader_code_address = __gen_unpack_address(cl, 99, 127); + values->fragment_shader_4_way_threadable = __gen_unpack_uint(cl, 96, 96); + values->fragment_shader_start_in_final_thread_section = __gen_unpack_uint(cl, 97, 97); + values->fragment_shader_propagate_nans = __gen_unpack_uint(cl, 98, 98); + values->fragment_shader_uniforms_address = __gen_unpack_address(cl, 128, 159); + values->vertex_shader_code_address = __gen_unpack_address(cl, 163, 191); + values->vertex_shader_4_way_threadable = __gen_unpack_uint(cl, 160, 160); + values->vertex_shader_start_in_final_thread_section = __gen_unpack_uint(cl, 161, 161); + values->vertex_shader_propagate_nans = __gen_unpack_uint(cl, 162, 162); + values->vertex_shader_uniforms_address = __gen_unpack_address(cl, 192, 223); + values->coordinate_shader_code_address = __gen_unpack_address(cl, 227, 255); + values->coordinate_shader_4_way_threadable = __gen_unpack_uint(cl, 224, 224); + values->coordinate_shader_start_in_final_thread_section = __gen_unpack_uint(cl, 225, 225); + values->coordinate_shader_propagate_nans = __gen_unpack_uint(cl, 226, 226); + values->coordinate_shader_uniforms_address = __gen_unpack_address(cl, 256, 287); +} +#endif + + +#define V3D42_GEOMETRY_SHADER_STATE_RECORD_header\ + + +struct V3D42_GEOMETRY_SHADER_STATE_RECORD { + __gen_address_type geometry_bin_mode_shader_code_address; + bool _4_way_threadable; + bool start_in_final_thread_section; + bool propagate_nans; + __gen_address_type geometry_bin_mode_shader_uniforms_address; + __gen_address_type geometry_render_mode_shader_code_address; + __gen_address_type geometry_render_mode_shader_uniforms_address; +}; + +static inline void +V3D42_GEOMETRY_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_GEOMETRY_SHADER_STATE_RECORD * restrict values) +{ + __gen_emit_reloc(data, &values->geometry_bin_mode_shader_code_address); + cl[ 0] = __gen_address_offset(&values->geometry_bin_mode_shader_code_address) | + __gen_uint(values->_4_way_threadable, 0, 0) | + __gen_uint(values->start_in_final_thread_section, 1, 1) | + __gen_uint(values->propagate_nans, 2, 2); + + cl[ 1] = __gen_address_offset(&values->geometry_bin_mode_shader_code_address) >> 8; + + cl[ 2] = __gen_address_offset(&values->geometry_bin_mode_shader_code_address) >> 16; + + cl[ 3] = __gen_address_offset(&values->geometry_bin_mode_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->geometry_bin_mode_shader_uniforms_address); + cl[ 4] = __gen_address_offset(&values->geometry_bin_mode_shader_uniforms_address); + + cl[ 5] = __gen_address_offset(&values->geometry_bin_mode_shader_uniforms_address) >> 8; + + cl[ 6] = __gen_address_offset(&values->geometry_bin_mode_shader_uniforms_address) >> 16; + + cl[ 7] = __gen_address_offset(&values->geometry_bin_mode_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->geometry_render_mode_shader_code_address); + cl[ 8] = __gen_address_offset(&values->geometry_render_mode_shader_code_address); + + cl[ 9] = __gen_address_offset(&values->geometry_render_mode_shader_code_address) >> 8; + + cl[10] = __gen_address_offset(&values->geometry_render_mode_shader_code_address) >> 16; + + cl[11] = __gen_address_offset(&values->geometry_render_mode_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->geometry_render_mode_shader_uniforms_address); + cl[12] = __gen_address_offset(&values->geometry_render_mode_shader_uniforms_address); + + cl[13] = __gen_address_offset(&values->geometry_render_mode_shader_uniforms_address) >> 8; + + cl[14] = __gen_address_offset(&values->geometry_render_mode_shader_uniforms_address) >> 16; + + cl[15] = __gen_address_offset(&values->geometry_render_mode_shader_uniforms_address) >> 24; + +} + +#define V3D42_GEOMETRY_SHADER_STATE_RECORD_length 16 +#ifdef __gen_unpack_address +static inline void +V3D42_GEOMETRY_SHADER_STATE_RECORD_unpack(const uint8_t * restrict cl, + struct V3D42_GEOMETRY_SHADER_STATE_RECORD * restrict values) +{ + values->geometry_bin_mode_shader_code_address = __gen_unpack_address(cl, 0, 31); + values->_4_way_threadable = __gen_unpack_uint(cl, 0, 0); + values->start_in_final_thread_section = __gen_unpack_uint(cl, 1, 1); + values->propagate_nans = __gen_unpack_uint(cl, 2, 2); + values->geometry_bin_mode_shader_uniforms_address = __gen_unpack_address(cl, 32, 63); + values->geometry_render_mode_shader_code_address = __gen_unpack_address(cl, 64, 95); + values->geometry_render_mode_shader_uniforms_address = __gen_unpack_address(cl, 96, 127); +} +#endif + + +#define V3D42_TESSELLATION_SHADER_STATE_RECORD_header\ + + +struct V3D42_TESSELLATION_SHADER_STATE_RECORD { + __gen_address_type tessellation_bin_mode_control_shader_code_address; + __gen_address_type tessellation_bin_mode_control_shader_uniforms_address; + __gen_address_type tessellation_render_mode_control_shader_code_address; + __gen_address_type tessellation_render_mode_control_shader_uniforms_address; + __gen_address_type tessellation_bin_mode_evaluation_shader_code_address; + __gen_address_type tessellation_bin_mode_evaluation_shader_uniforms_address; + __gen_address_type tessellation_render_mode_evaluation_shader_code_address; + __gen_address_type tessellation_render_mode_evaluation_shader_uniforms_address; +}; + +static inline void +V3D42_TESSELLATION_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TESSELLATION_SHADER_STATE_RECORD * restrict values) +{ + __gen_emit_reloc(data, &values->tessellation_bin_mode_control_shader_code_address); + cl[ 0] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_code_address); + + cl[ 1] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_code_address) >> 8; + + cl[ 2] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_code_address) >> 16; + + cl[ 3] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_bin_mode_control_shader_uniforms_address); + cl[ 4] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_uniforms_address); + + cl[ 5] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_uniforms_address) >> 8; + + cl[ 6] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_uniforms_address) >> 16; + + cl[ 7] = __gen_address_offset(&values->tessellation_bin_mode_control_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_render_mode_control_shader_code_address); + cl[ 8] = __gen_address_offset(&values->tessellation_render_mode_control_shader_code_address); + + cl[ 9] = __gen_address_offset(&values->tessellation_render_mode_control_shader_code_address) >> 8; + + cl[10] = __gen_address_offset(&values->tessellation_render_mode_control_shader_code_address) >> 16; + + cl[11] = __gen_address_offset(&values->tessellation_render_mode_control_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_render_mode_control_shader_uniforms_address); + cl[12] = __gen_address_offset(&values->tessellation_render_mode_control_shader_uniforms_address); + + cl[13] = __gen_address_offset(&values->tessellation_render_mode_control_shader_uniforms_address) >> 8; + + cl[14] = __gen_address_offset(&values->tessellation_render_mode_control_shader_uniforms_address) >> 16; + + cl[15] = __gen_address_offset(&values->tessellation_render_mode_control_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_bin_mode_evaluation_shader_code_address); + cl[16] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_code_address); + + cl[17] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_code_address) >> 8; + + cl[18] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_code_address) >> 16; + + cl[19] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_bin_mode_evaluation_shader_uniforms_address); + cl[20] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_uniforms_address); + + cl[21] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_uniforms_address) >> 8; + + cl[22] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_uniforms_address) >> 16; + + cl[23] = __gen_address_offset(&values->tessellation_bin_mode_evaluation_shader_uniforms_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_render_mode_evaluation_shader_code_address); + cl[24] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_code_address); + + cl[25] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_code_address) >> 8; + + cl[26] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_code_address) >> 16; + + cl[27] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_code_address) >> 24; + + __gen_emit_reloc(data, &values->tessellation_render_mode_evaluation_shader_uniforms_address); + cl[28] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_uniforms_address); + + cl[29] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_uniforms_address) >> 8; + + cl[30] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_uniforms_address) >> 16; + + cl[31] = __gen_address_offset(&values->tessellation_render_mode_evaluation_shader_uniforms_address) >> 24; + +} + +#define V3D42_TESSELLATION_SHADER_STATE_RECORD_length 32 +#ifdef __gen_unpack_address +static inline void +V3D42_TESSELLATION_SHADER_STATE_RECORD_unpack(const uint8_t * restrict cl, + struct V3D42_TESSELLATION_SHADER_STATE_RECORD * restrict values) +{ + values->tessellation_bin_mode_control_shader_code_address = __gen_unpack_address(cl, 0, 31); + values->tessellation_bin_mode_control_shader_uniforms_address = __gen_unpack_address(cl, 32, 63); + values->tessellation_render_mode_control_shader_code_address = __gen_unpack_address(cl, 64, 95); + values->tessellation_render_mode_control_shader_uniforms_address = __gen_unpack_address(cl, 96, 127); + values->tessellation_bin_mode_evaluation_shader_code_address = __gen_unpack_address(cl, 128, 159); + values->tessellation_bin_mode_evaluation_shader_uniforms_address = __gen_unpack_address(cl, 160, 191); + values->tessellation_render_mode_evaluation_shader_code_address = __gen_unpack_address(cl, 192, 223); + values->tessellation_render_mode_evaluation_shader_uniforms_address = __gen_unpack_address(cl, 224, 255); +} +#endif + + +#define V3D42_GL_SHADER_STATE_ATTRIBUTE_RECORD_header\ + + +struct V3D42_GL_SHADER_STATE_ATTRIBUTE_RECORD { + __gen_address_type address; + uint32_t vec_size; + uint32_t type; +#define ATTRIBUTE_HALF_FLOAT 1 +#define ATTRIBUTE_FLOAT 2 +#define ATTRIBUTE_FIXED 3 +#define ATTRIBUTE_BYTE 4 +#define ATTRIBUTE_SHORT 5 +#define ATTRIBUTE_INT 6 +#define ATTRIBUTE_INT2_10_10_10 7 + bool signed_int_type; + bool normalized_int_type; + bool read_as_int_uint; + uint32_t number_of_values_read_by_coordinate_shader; + uint32_t number_of_values_read_by_vertex_shader; + uint32_t instance_divisor; + uint32_t stride; + uint32_t maximum_index; +}; + +static inline void +V3D42_GL_SHADER_STATE_ATTRIBUTE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_GL_SHADER_STATE_ATTRIBUTE_RECORD * restrict values) +{ + __gen_emit_reloc(data, &values->address); + cl[ 0] = __gen_address_offset(&values->address); + + cl[ 1] = __gen_address_offset(&values->address) >> 8; + + cl[ 2] = __gen_address_offset(&values->address) >> 16; + + cl[ 3] = __gen_address_offset(&values->address) >> 24; + + cl[ 4] = __gen_uint(values->vec_size, 0, 1) | + __gen_uint(values->type, 2, 4) | + __gen_uint(values->signed_int_type, 5, 5) | + __gen_uint(values->normalized_int_type, 6, 6) | + __gen_uint(values->read_as_int_uint, 7, 7); + + cl[ 5] = __gen_uint(values->number_of_values_read_by_coordinate_shader, 0, 3) | + __gen_uint(values->number_of_values_read_by_vertex_shader, 4, 7); + + cl[ 6] = __gen_uint(values->instance_divisor, 0, 15); + + cl[ 7] = __gen_uint(values->instance_divisor, 0, 15) >> 8; + + + memcpy(&cl[8], &values->stride, sizeof(values->stride)); + + memcpy(&cl[12], &values->maximum_index, sizeof(values->maximum_index)); +} + +#define V3D42_GL_SHADER_STATE_ATTRIBUTE_RECORD_length 16 +#ifdef __gen_unpack_address +static inline void +V3D42_GL_SHADER_STATE_ATTRIBUTE_RECORD_unpack(const uint8_t * restrict cl, + struct V3D42_GL_SHADER_STATE_ATTRIBUTE_RECORD * restrict values) +{ + values->address = __gen_unpack_address(cl, 0, 31); + values->vec_size = __gen_unpack_uint(cl, 32, 33); + values->type = __gen_unpack_uint(cl, 34, 36); + values->signed_int_type = __gen_unpack_uint(cl, 37, 37); + values->normalized_int_type = __gen_unpack_uint(cl, 38, 38); + values->read_as_int_uint = __gen_unpack_uint(cl, 39, 39); + values->number_of_values_read_by_coordinate_shader = __gen_unpack_uint(cl, 40, 43); + values->number_of_values_read_by_vertex_shader = __gen_unpack_uint(cl, 44, 47); + values->instance_divisor = __gen_unpack_uint(cl, 48, 63); + values->stride = __gen_unpack_uint(cl, 64, 95); + values->maximum_index = __gen_unpack_uint(cl, 96, 127); +} +#endif + + +#define V3D42_VPM_GENERIC_BLOCK_WRITE_SETUP_header\ + .id = 0, \ + .id0 = 0 + +struct V3D42_VPM_GENERIC_BLOCK_WRITE_SETUP { + uint32_t id; + uint32_t id0; + bool horiz; + bool laned; + bool segs; + int32_t stride; + uint32_t size; +#define VPM_SETUP_SIZE_8_BIT 0 +#define VPM_SETUP_SIZE_16_BIT 1 +#define VPM_SETUP_SIZE_32_BIT 2 + uint32_t addr; +}; + +static inline void +V3D42_VPM_GENERIC_BLOCK_WRITE_SETUP_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_VPM_GENERIC_BLOCK_WRITE_SETUP * restrict values) +{ + cl[ 0] = __gen_uint(values->addr, 0, 12); + + cl[ 1] = __gen_sint(values->stride, 7, 13) | + __gen_uint(values->size, 5, 6) | + __gen_uint(values->addr, 0, 12) >> 8; + + cl[ 2] = __gen_uint(values->laned, 7, 7) | + __gen_uint(values->segs, 6, 6) | + __gen_sint(values->stride, 7, 13) >> 8; + + cl[ 3] = __gen_uint(values->id, 6, 7) | + __gen_uint(values->id0, 3, 5) | + __gen_uint(values->horiz, 0, 0); + +} + +#define V3D42_VPM_GENERIC_BLOCK_WRITE_SETUP_length 4 +#ifdef __gen_unpack_address +static inline void +V3D42_VPM_GENERIC_BLOCK_WRITE_SETUP_unpack(const uint8_t * restrict cl, + struct V3D42_VPM_GENERIC_BLOCK_WRITE_SETUP * restrict values) +{ + values->id = __gen_unpack_uint(cl, 30, 31); + values->id0 = __gen_unpack_uint(cl, 27, 29); + values->horiz = __gen_unpack_uint(cl, 24, 24); + values->laned = __gen_unpack_uint(cl, 23, 23); + values->segs = __gen_unpack_uint(cl, 22, 22); + values->stride = __gen_unpack_sint(cl, 15, 21); + values->size = __gen_unpack_uint(cl, 13, 14); + values->addr = __gen_unpack_uint(cl, 0, 12); +} +#endif + + +#define V3D42_VPM_GENERIC_BLOCK_READ_SETUP_header\ + .id = 1 + +struct V3D42_VPM_GENERIC_BLOCK_READ_SETUP { + uint32_t id; + bool horiz; + bool laned; + bool segs; + uint32_t num; + int32_t stride; + uint32_t size; +#define VPM_SETUP_SIZE_8_BIT 0 +#define VPM_SETUP_SIZE_16_BIT 1 +#define VPM_SETUP_SIZE_32_BIT 2 + uint32_t addr; +}; + +static inline void +V3D42_VPM_GENERIC_BLOCK_READ_SETUP_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_VPM_GENERIC_BLOCK_READ_SETUP * restrict values) +{ + cl[ 0] = __gen_uint(values->addr, 0, 12); + + cl[ 1] = __gen_sint(values->stride, 7, 13) | + __gen_uint(values->size, 5, 6) | + __gen_uint(values->addr, 0, 12) >> 8; + + cl[ 2] = __gen_uint(values->num, 6, 10) | + __gen_sint(values->stride, 7, 13) >> 8; + + cl[ 3] = __gen_uint(values->id, 6, 7) | + __gen_uint(values->horiz, 5, 5) | + __gen_uint(values->laned, 4, 4) | + __gen_uint(values->segs, 3, 3) | + __gen_uint(values->num, 6, 10) >> 8; + +} + +#define V3D42_VPM_GENERIC_BLOCK_READ_SETUP_length 4 +#ifdef __gen_unpack_address +static inline void +V3D42_VPM_GENERIC_BLOCK_READ_SETUP_unpack(const uint8_t * restrict cl, + struct V3D42_VPM_GENERIC_BLOCK_READ_SETUP * restrict values) +{ + values->id = __gen_unpack_uint(cl, 30, 31); + values->horiz = __gen_unpack_uint(cl, 29, 29); + values->laned = __gen_unpack_uint(cl, 28, 28); + values->segs = __gen_unpack_uint(cl, 27, 27); + values->num = __gen_unpack_uint(cl, 22, 26); + values->stride = __gen_unpack_sint(cl, 15, 21); + values->size = __gen_unpack_uint(cl, 13, 14); + values->addr = __gen_unpack_uint(cl, 0, 12); +} +#endif + + +#define V3D42_TMU_CONFIG_PARAMETER_0_header \ + + +struct V3D42_TMU_CONFIG_PARAMETER_0 { + __gen_address_type texture_state_address; + uint32_t return_words_of_texture_data; +}; + +static inline void +V3D42_TMU_CONFIG_PARAMETER_0_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TMU_CONFIG_PARAMETER_0 * restrict values) +{ + __gen_emit_reloc(data, &values->texture_state_address); + cl[ 0] = __gen_address_offset(&values->texture_state_address) | + __gen_uint(values->return_words_of_texture_data, 0, 3); + + cl[ 1] = __gen_address_offset(&values->texture_state_address) >> 8; + + cl[ 2] = __gen_address_offset(&values->texture_state_address) >> 16; + + cl[ 3] = __gen_address_offset(&values->texture_state_address) >> 24; + +} + +#define V3D42_TMU_CONFIG_PARAMETER_0_length 4 +#ifdef __gen_unpack_address +static inline void +V3D42_TMU_CONFIG_PARAMETER_0_unpack(const uint8_t * restrict cl, + struct V3D42_TMU_CONFIG_PARAMETER_0 * restrict values) +{ + values->texture_state_address = __gen_unpack_address(cl, 0, 31); + values->return_words_of_texture_data = __gen_unpack_uint(cl, 0, 3); +} +#endif + + +#define V3D42_TMU_CONFIG_PARAMETER_1_header \ + + +struct V3D42_TMU_CONFIG_PARAMETER_1 { + __gen_address_type sampler_state_address; + bool per_pixel_mask_enable; + bool unnormalized_coordinates; + bool output_type_32_bit; +}; + +static inline void +V3D42_TMU_CONFIG_PARAMETER_1_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TMU_CONFIG_PARAMETER_1 * restrict values) +{ + __gen_emit_reloc(data, &values->sampler_state_address); + cl[ 0] = __gen_address_offset(&values->sampler_state_address) | + __gen_uint(values->per_pixel_mask_enable, 2, 2) | + __gen_uint(values->unnormalized_coordinates, 1, 1) | + __gen_uint(values->output_type_32_bit, 0, 0); + + cl[ 1] = __gen_address_offset(&values->sampler_state_address) >> 8; + + cl[ 2] = __gen_address_offset(&values->sampler_state_address) >> 16; + + cl[ 3] = __gen_address_offset(&values->sampler_state_address) >> 24; + +} + +#define V3D42_TMU_CONFIG_PARAMETER_1_length 4 +#ifdef __gen_unpack_address +static inline void +V3D42_TMU_CONFIG_PARAMETER_1_unpack(const uint8_t * restrict cl, + struct V3D42_TMU_CONFIG_PARAMETER_1 * restrict values) +{ + values->sampler_state_address = __gen_unpack_address(cl, 0, 31); + values->per_pixel_mask_enable = __gen_unpack_uint(cl, 2, 2); + values->unnormalized_coordinates = __gen_unpack_uint(cl, 1, 1); + values->output_type_32_bit = __gen_unpack_uint(cl, 0, 0); +} +#endif + + +#define V3D42_TMU_CONFIG_PARAMETER_2_header \ + + +struct V3D42_TMU_CONFIG_PARAMETER_2 { + uint32_t pad; + bool lod_query; + enum V3D42_TMU_Op op; + int32_t offset_r; + int32_t offset_t; + int32_t offset_s; + bool gather_mode; + uint32_t gather_component; + bool coefficient_mode; + uint32_t sample_number; + bool disable_autolod; + bool offset_format_8; +}; + +static inline void +V3D42_TMU_CONFIG_PARAMETER_2_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TMU_CONFIG_PARAMETER_2 * restrict values) +{ + cl[ 0] = __gen_uint(values->gather_mode, 7, 7) | + __gen_uint(values->gather_component, 5, 6) | + __gen_uint(values->coefficient_mode, 4, 4) | + __gen_uint(values->sample_number, 2, 3) | + __gen_uint(values->disable_autolod, 1, 1) | + __gen_uint(values->offset_format_8, 0, 0); + + cl[ 1] = __gen_uint(values->pad, 1, 23) | + __gen_uint(values->lod_query, 0, 0) | + __gen_sint(values->offset_t, 4, 7) | + __gen_sint(values->offset_s, 0, 3); + + cl[ 2] = __gen_uint(values->pad, 1, 23) >> 8 | + __gen_uint(values->op, 4, 7) | + __gen_sint(values->offset_r, 0, 3); + + cl[ 3] = __gen_uint(values->pad, 1, 23) >> 16; + +} + +#define V3D42_TMU_CONFIG_PARAMETER_2_length 4 +#ifdef __gen_unpack_address +static inline void +V3D42_TMU_CONFIG_PARAMETER_2_unpack(const uint8_t * restrict cl, + struct V3D42_TMU_CONFIG_PARAMETER_2 * restrict values) +{ + values->pad = __gen_unpack_uint(cl, 9, 31); + values->lod_query = __gen_unpack_uint(cl, 8, 8); + values->op = __gen_unpack_uint(cl, 20, 23); + values->offset_r = __gen_unpack_sint(cl, 16, 19); + values->offset_t = __gen_unpack_sint(cl, 12, 15); + values->offset_s = __gen_unpack_sint(cl, 8, 11); + values->gather_mode = __gen_unpack_uint(cl, 7, 7); + values->gather_component = __gen_unpack_uint(cl, 5, 6); + values->coefficient_mode = __gen_unpack_uint(cl, 4, 4); + values->sample_number = __gen_unpack_uint(cl, 2, 3); + values->disable_autolod = __gen_unpack_uint(cl, 1, 1); + values->offset_format_8 = __gen_unpack_uint(cl, 0, 0); +} +#endif + + +#define V3D42_TEXTURE_SHADER_STATE_header \ + + +struct V3D42_TEXTURE_SHADER_STATE { + uint64_t pad; + bool uif_xor_disable; + bool level_0_is_strictly_uif; + bool level_0_xor_enable; + uint32_t level_0_ub_pad; + uint32_t base_level; + uint32_t max_level; + uint32_t swizzle_a; +#define SWIZZLE_ZERO 0 +#define SWIZZLE_ONE 1 +#define SWIZZLE_RED 2 +#define SWIZZLE_GREEN 3 +#define SWIZZLE_BLUE 4 +#define SWIZZLE_ALPHA 5 + uint32_t swizzle_b; + uint32_t swizzle_g; + uint32_t swizzle_r; + bool extended; + uint32_t texture_type; + uint32_t image_depth; + uint32_t image_height; + uint32_t image_width; + uint32_t array_stride_64_byte_aligned; + __gen_address_type texture_base_pointer; + bool reverse_standard_border_color; + bool ahdr; + bool srgb; + bool flip_s_and_t_on_incoming_request; + bool flip_texture_y_axis; + bool flip_texture_x_axis; +}; + +static inline void +V3D42_TEXTURE_SHADER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_TEXTURE_SHADER_STATE * restrict values) +{ + __gen_emit_reloc(data, &values->texture_base_pointer); + cl[ 0] = __gen_address_offset(&values->texture_base_pointer) | + __gen_uint(values->reverse_standard_border_color, 5, 5) | + __gen_uint(values->ahdr, 4, 4) | + __gen_uint(values->srgb, 3, 3) | + __gen_uint(values->flip_s_and_t_on_incoming_request, 2, 2) | + __gen_uint(values->flip_texture_y_axis, 1, 1) | + __gen_uint(values->flip_texture_x_axis, 0, 0); + + cl[ 1] = __gen_address_offset(&values->texture_base_pointer) >> 8; + + cl[ 2] = __gen_address_offset(&values->texture_base_pointer) >> 16; + + cl[ 3] = __gen_address_offset(&values->texture_base_pointer) >> 24; + + cl[ 4] = __gen_uint(values->array_stride_64_byte_aligned, 0, 25); + + cl[ 5] = __gen_uint(values->array_stride_64_byte_aligned, 0, 25) >> 8; + + cl[ 6] = __gen_uint(values->array_stride_64_byte_aligned, 0, 25) >> 16; + + cl[ 7] = __gen_uint(values->image_width, 2, 15) | + __gen_uint(values->array_stride_64_byte_aligned, 0, 25) >> 24; + + cl[ 8] = __gen_uint(values->image_width, 2, 15) >> 8; + + cl[ 9] = __gen_uint(values->image_height, 0, 13); + + cl[10] = __gen_uint(values->image_depth, 6, 19) | + __gen_uint(values->image_height, 0, 13) >> 8; + + cl[11] = __gen_uint(values->image_depth, 6, 19) >> 8; + + cl[12] = __gen_uint(values->texture_type, 4, 10) | + __gen_uint(values->image_depth, 6, 19) >> 16; + + cl[13] = __gen_uint(values->swizzle_g, 7, 9) | + __gen_uint(values->swizzle_r, 4, 6) | + __gen_uint(values->extended, 3, 3) | + __gen_uint(values->texture_type, 4, 10) >> 8; + + cl[14] = __gen_uint(values->swizzle_a, 5, 7) | + __gen_uint(values->swizzle_b, 2, 4) | + __gen_uint(values->swizzle_g, 7, 9) >> 8; + + cl[15] = __gen_uint(values->base_level, 4, 7) | + __gen_uint(values->max_level, 0, 3); + + cl[16] = __gen_uint(values->uif_xor_disable, 7, 7) | + __gen_uint(values->level_0_is_strictly_uif, 6, 6) | + __gen_uint(values->level_0_xor_enable, 4, 4) | + __gen_uint(values->level_0_ub_pad, 0, 3); + + cl[17] = __gen_uint(values->pad, 0, 55); + + cl[18] = __gen_uint(values->pad, 0, 55) >> 8; + + cl[19] = __gen_uint(values->pad, 0, 55) >> 16; + + cl[20] = __gen_uint(values->pad, 0, 55) >> 24; + + cl[21] = __gen_uint(values->pad, 0, 55) >> 32; + + cl[22] = __gen_uint(values->pad, 0, 55) >> 40; + + cl[23] = __gen_uint(values->pad, 0, 55) >> 48; + +} + +#define V3D42_TEXTURE_SHADER_STATE_length 24 +#ifdef __gen_unpack_address +static inline void +V3D42_TEXTURE_SHADER_STATE_unpack(const uint8_t * restrict cl, + struct V3D42_TEXTURE_SHADER_STATE * restrict values) +{ + values->pad = __gen_unpack_uint(cl, 136, 191); + values->uif_xor_disable = __gen_unpack_uint(cl, 135, 135); + values->level_0_is_strictly_uif = __gen_unpack_uint(cl, 134, 134); + values->level_0_xor_enable = __gen_unpack_uint(cl, 132, 132); + values->level_0_ub_pad = __gen_unpack_uint(cl, 128, 131); + values->base_level = __gen_unpack_uint(cl, 124, 127); + values->max_level = __gen_unpack_uint(cl, 120, 123); + values->swizzle_a = __gen_unpack_uint(cl, 117, 119); + values->swizzle_b = __gen_unpack_uint(cl, 114, 116); + values->swizzle_g = __gen_unpack_uint(cl, 111, 113); + values->swizzle_r = __gen_unpack_uint(cl, 108, 110); + values->extended = __gen_unpack_uint(cl, 107, 107); + values->texture_type = __gen_unpack_uint(cl, 100, 106); + values->image_depth = __gen_unpack_uint(cl, 86, 99); + values->image_height = __gen_unpack_uint(cl, 72, 85); + values->image_width = __gen_unpack_uint(cl, 58, 71); + values->array_stride_64_byte_aligned = __gen_unpack_uint(cl, 32, 57); + values->texture_base_pointer = __gen_unpack_address(cl, 0, 31); + values->reverse_standard_border_color = __gen_unpack_uint(cl, 5, 5); + values->ahdr = __gen_unpack_uint(cl, 4, 4); + values->srgb = __gen_unpack_uint(cl, 3, 3); + values->flip_s_and_t_on_incoming_request = __gen_unpack_uint(cl, 2, 2); + values->flip_texture_y_axis = __gen_unpack_uint(cl, 1, 1); + values->flip_texture_x_axis = __gen_unpack_uint(cl, 0, 0); +} +#endif + + +#define V3D42_SAMPLER_STATE_header \ + + +struct V3D42_SAMPLER_STATE { + uint32_t border_color_alpha; + uint32_t border_color_blue; + uint32_t border_color_green; + uint32_t border_color_red; + uint32_t maximum_anisotropy; + enum V3D42_Border_Color_Mode border_color_mode; + bool wrap_i_border; + enum V3D42_Wrap_Mode wrap_r; + enum V3D42_Wrap_Mode wrap_t; + enum V3D42_Wrap_Mode wrap_s; + float fixed_bias; + float max_level_of_detail; + float min_level_of_detail; + bool srgb_disable; + enum V3D42_Compare_Function depth_compare_function; + bool anisotropy_enable; + bool mip_filter_nearest; + bool min_filter_nearest; + bool mag_filter_nearest; +}; + +static inline void +V3D42_SAMPLER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl, + const struct V3D42_SAMPLER_STATE * restrict values) +{ + cl[ 0] = __gen_uint(values->srgb_disable, 7, 7) | + __gen_uint(values->depth_compare_function, 4, 6) | + __gen_uint(values->anisotropy_enable, 3, 3) | + __gen_uint(values->mip_filter_nearest, 2, 2) | + __gen_uint(values->min_filter_nearest, 1, 1) | + __gen_uint(values->mag_filter_nearest, 0, 0); + + cl[ 1] = __gen_ufixed(values->min_level_of_detail, 0, 11, 8); + + cl[ 2] = __gen_ufixed(values->max_level_of_detail, 4, 15, 8) | + __gen_ufixed(values->min_level_of_detail, 0, 11, 8) >> 8; + + cl[ 3] = __gen_ufixed(values->max_level_of_detail, 4, 15, 8) >> 8; + + cl[ 4] = __gen_sfixed(values->fixed_bias, 0, 15, 8); + + cl[ 5] = __gen_sfixed(values->fixed_bias, 0, 15, 8) >> 8; + + cl[ 6] = __gen_uint(values->wrap_r, 6, 8) | + __gen_uint(values->wrap_t, 3, 5) | + __gen_uint(values->wrap_s, 0, 2); + + cl[ 7] = __gen_uint(values->maximum_anisotropy, 5, 6) | + __gen_uint(values->border_color_mode, 2, 4) | + __gen_uint(values->wrap_i_border, 1, 1) | + __gen_uint(values->wrap_r, 6, 8) >> 8; + + + memcpy(&cl[8], &values->border_color_red, sizeof(values->border_color_red)); + + memcpy(&cl[12], &values->border_color_green, sizeof(values->border_color_green)); + + memcpy(&cl[16], &values->border_color_blue, sizeof(values->border_color_blue)); + + memcpy(&cl[20], &values->border_color_alpha, sizeof(values->border_color_alpha)); +} + +#define V3D42_SAMPLER_STATE_length 24 +#ifdef __gen_unpack_address +static inline void +V3D42_SAMPLER_STATE_unpack(const uint8_t * restrict cl, + struct V3D42_SAMPLER_STATE * restrict values) +{ + values->border_color_alpha = __gen_unpack_uint(cl, 160, 191); + values->border_color_blue = __gen_unpack_uint(cl, 128, 159); + values->border_color_green = __gen_unpack_uint(cl, 96, 127); + values->border_color_red = __gen_unpack_uint(cl, 64, 95); + values->maximum_anisotropy = __gen_unpack_uint(cl, 61, 62); + values->border_color_mode = __gen_unpack_uint(cl, 58, 60); + values->wrap_i_border = __gen_unpack_uint(cl, 57, 57); + values->wrap_r = __gen_unpack_uint(cl, 54, 56); + values->wrap_t = __gen_unpack_uint(cl, 51, 53); + values->wrap_s = __gen_unpack_uint(cl, 48, 50); + values->fixed_bias = __gen_unpack_sfixed(cl, 32, 47, 8); + values->max_level_of_detail = __gen_unpack_ufixed(cl, 20, 31, 8); + values->min_level_of_detail = __gen_unpack_ufixed(cl, 8, 19, 8); + values->srgb_disable = __gen_unpack_uint(cl, 7, 7); + values->depth_compare_function = __gen_unpack_uint(cl, 4, 6); + values->anisotropy_enable = __gen_unpack_uint(cl, 3, 3); + values->mip_filter_nearest = __gen_unpack_uint(cl, 2, 2); + values->min_filter_nearest = __gen_unpack_uint(cl, 1, 1); + values->mag_filter_nearest = __gen_unpack_uint(cl, 0, 0); +} +#endif + + +enum V3D42_Texture_Data_Formats { + TEXTURE_DATA_FORMAT_R8 = 0, + TEXTURE_DATA_FORMAT_R8_SNORM = 1, + TEXTURE_DATA_FORMAT_RG8 = 2, + TEXTURE_DATA_FORMAT_RG8_SNORM = 3, + TEXTURE_DATA_FORMAT_RGBA8 = 4, + TEXTURE_DATA_FORMAT_RGBA8_SNORM = 5, + TEXTURE_DATA_FORMAT_RGB565 = 6, + TEXTURE_DATA_FORMAT_RGBA4 = 7, + TEXTURE_DATA_FORMAT_RGB5_A1 = 8, + TEXTURE_DATA_FORMAT_RGB10_A2 = 9, + TEXTURE_DATA_FORMAT_R16 = 10, + TEXTURE_DATA_FORMAT_R16_SNORM = 11, + TEXTURE_DATA_FORMAT_RG16 = 12, + TEXTURE_DATA_FORMAT_RG16_SNORM = 13, + TEXTURE_DATA_FORMAT_RGBA16 = 14, + TEXTURE_DATA_FORMAT_RGBA16_SNORM = 15, + TEXTURE_DATA_FORMAT_R16F = 16, + TEXTURE_DATA_FORMAT_RG16F = 17, + TEXTURE_DATA_FORMAT_RGBA16F = 18, + TEXTURE_DATA_FORMAT_R11F_G11F_B10F = 19, + TEXTURE_DATA_FORMAT_RGB9_E5 = 20, + TEXTURE_DATA_FORMAT_DEPTH_COMP16 = 21, + TEXTURE_DATA_FORMAT_DEPTH_COMP24 = 22, + TEXTURE_DATA_FORMAT_DEPTH_COMP32F = 23, + TEXTURE_DATA_FORMAT_DEPTH24_X8 = 24, + TEXTURE_DATA_FORMAT_R4 = 25, + TEXTURE_DATA_FORMAT_R1 = 26, + TEXTURE_DATA_FORMAT_S8 = 27, + TEXTURE_DATA_FORMAT_S16 = 28, + TEXTURE_DATA_FORMAT_R32F = 29, + TEXTURE_DATA_FORMAT_RG32F = 30, + TEXTURE_DATA_FORMAT_RGBA32F = 31, + TEXTURE_DATA_FORMAT_RGB8_ETC2 = 32, + TEXTURE_DATA_FORMAT_RGB8_PUNCHTHROUGH_ALPHA1 = 33, + TEXTURE_DATA_FORMAT_R11_EAC = 34, + TEXTURE_DATA_FORMAT_SIGNED_R11_EAC = 35, + TEXTURE_DATA_FORMAT_RG11_EAC = 36, + TEXTURE_DATA_FORMAT_SIGNED_RG11_EAC = 37, + TEXTURE_DATA_FORMAT_RGBA8_ETC2_EAC = 38, + TEXTURE_DATA_FORMAT_YCBCR_LUMA = 39, + TEXTURE_DATA_FORMAT_YCBCR_420_CHROMA = 40, + TEXTURE_DATA_FORMAT_BC1 = 48, + TEXTURE_DATA_FORMAT_BC2 = 49, + TEXTURE_DATA_FORMAT_BC3 = 50, + TEXTURE_DATA_FORMAT_ASTC_4X4 = 64, + TEXTURE_DATA_FORMAT_ASTC_5X4 = 65, + TEXTURE_DATA_FORMAT_ASTC_5X5 = 66, + TEXTURE_DATA_FORMAT_ASTC_6X5 = 67, + TEXTURE_DATA_FORMAT_ASTC_6X6 = 68, + TEXTURE_DATA_FORMAT_ASTC_8X5 = 69, + TEXTURE_DATA_FORMAT_ASTC_8X6 = 70, + TEXTURE_DATA_FORMAT_ASTC_8X8 = 71, + TEXTURE_DATA_FORMAT_ASTC_10X5 = 72, + TEXTURE_DATA_FORMAT_ASTC_10X6 = 73, + TEXTURE_DATA_FORMAT_ASTC_10X8 = 74, + TEXTURE_DATA_FORMAT_ASTC_10X10 = 75, + TEXTURE_DATA_FORMAT_ASTC_12X10 = 76, + TEXTURE_DATA_FORMAT_ASTC_12X12 = 77, + TEXTURE_DATA_FORMAT_R8I = 96, + TEXTURE_DATA_FORMAT_R8UI = 97, + TEXTURE_DATA_FORMAT_RG8I = 98, + TEXTURE_DATA_FORMAT_RG8UI = 99, + TEXTURE_DATA_FORMAT_RGBA8I = 100, + TEXTURE_DATA_FORMAT_RGBA8UI = 101, + TEXTURE_DATA_FORMAT_R16I = 102, + TEXTURE_DATA_FORMAT_R16UI = 103, + TEXTURE_DATA_FORMAT_RG16I = 104, + TEXTURE_DATA_FORMAT_RG16UI = 105, + TEXTURE_DATA_FORMAT_RGBA16I = 106, + TEXTURE_DATA_FORMAT_RGBA16UI = 107, + TEXTURE_DATA_FORMAT_R32I = 108, + TEXTURE_DATA_FORMAT_R32UI = 109, + TEXTURE_DATA_FORMAT_RG32I = 110, + TEXTURE_DATA_FORMAT_RG32UI = 111, + TEXTURE_DATA_FORMAT_RGBA32I = 112, + TEXTURE_DATA_FORMAT_RGBA32UI = 113, + TEXTURE_DATA_FORMAT_RGB10_A2UI = 114, +}; + +#endif /* V3D42_PACK_H */ diff --git a/lib/mesa/src/broadcom/cle/v3d_xml.h b/lib/mesa/src/broadcom/cle/v3d_xml.h index a940429c1..1c807324b 100644 --- a/lib/mesa/src/broadcom/cle/v3d_xml.h +++ b/lib/mesa/src/broadcom/cle/v3d_xml.h @@ -3,717 +3,1051 @@ static const struct { uint32_t offset; uint32_t length; } genxml_files_table[] = { - { 21, 0, 15431 }, - { 33, 15431, 42910 }, + { 21, 0, 15538 }, + { 33, 15538, 75716 }, }; static const uint8_t compress_genxmls[] = { - 0x78, 0x9c, 0xed, 0x5d, 0x5b, 0x73, 0xe3, 0xb6, 0x92, 0x7e, 0xcf, 0xaf, - 0xc0, 0xce, 0xcb, 0xf1, 0xec, 0xae, 0x62, 0x91, 0xba, 0x58, 0xae, 0x4a, - 0xb2, 0xa5, 0x9b, 0x3d, 0xae, 0x23, 0x5b, 0x5a, 0x49, 0xf6, 0xcc, 0xf8, - 0x45, 0x45, 0x49, 0x94, 0xcd, 0x8a, 0x44, 0xea, 0x90, 0x94, 0x2f, 0xf9, - 0xf5, 0x8b, 0x0b, 0x49, 0x00, 0x64, 0x83, 0x00, 0x35, 0x9e, 0x49, 0xb2, - 0xc7, 0xa7, 0x4e, 0x25, 0x8e, 0xdd, 0x68, 0x00, 0xdd, 0x8d, 0x46, 0xa3, - 0xd1, 0xf8, 0xf8, 0xcb, 0xd3, 0xea, 0x65, 0xb7, 0x45, 0x0f, 0xae, 0xff, - 0xeb, 0x07, 0xfb, 0x67, 0xeb, 0xc3, 0x6f, 0x3f, 0x21, 0xf4, 0xcb, 0xde, - 0x59, 0xfd, 0xee, 0xc6, 0xc8, 0x77, 0x76, 0xee, 0xaf, 0x1f, 0x3e, 0x39, - 0xdb, 0xf8, 0x03, 0x5a, 0x05, 0x6b, 0xfc, 0x73, 0xfd, 0xc3, 0x69, 0x91, - 0xe0, 0x66, 0x3c, 0x49, 0xff, 0x6e, 0x41, 0x7f, 0xbf, 0xd8, 0x1e, 0xa2, - 0xc7, 0x94, 0xa2, 0x89, 0x7f, 0xd8, 0xfe, 0xfa, 0xa1, 0xa7, 0x24, 0x44, - 0xdd, 0xed, 0x16, 0xcd, 0x62, 0x27, 0x76, 0xd3, 0x26, 0xad, 0x92, 0x26, - 0x98, 0x30, 0x8c, 0xd1, 0xdc, 0xdb, 0xba, 0xa8, 0xe7, 0xf9, 0xbe, 0xe7, - 0x3f, 0xa4, 0xad, 0xda, 0x25, 0xad, 0xae, 0xfc, 0x55, 0xe8, 0xee, 0x5c, - 0x3f, 0x46, 0x33, 0x77, 0xe7, 0xec, 0x1f, 0x83, 0x30, 0xeb, 0xec, 0x0c, - 0xa2, 0xff, 0xec, 0x78, 0x31, 0x0a, 0xfc, 0x22, 0x75, 0x07, 0xa2, 0xee, - 0x85, 0x8e, 0xbf, 0xca, 0x26, 0x6c, 0xb5, 0xa9, 0x4c, 0x31, 0xd1, 0xc6, - 0x73, 0xb7, 0xeb, 0x84, 0xa6, 0xbb, 0x5e, 0x87, 0x6e, 0x14, 0x7d, 0x40, - 0x91, 0xf7, 0x07, 0xfe, 0xcf, 0x86, 0x8d, 0x7f, 0x22, 0x53, 0x21, 0x22, - 0x46, 0xf1, 0xeb, 0x1e, 0xff, 0xce, 0x49, 0x48, 0x58, 0x0f, 0xa7, 0xac, - 0x0b, 0x55, 0x6f, 0x28, 0x0e, 0x50, 0x74, 0x58, 0xd6, 0xb6, 0x5e, 0x94, - 0x29, 0xcb, 0x3a, 0xfb, 0xbe, 0x3d, 0x4f, 0xdd, 0xf8, 0x10, 0xfa, 0x68, - 0x13, 0x06, 0xbb, 0x62, 0xdf, 0x54, 0x32, 0x80, 0xba, 0xb0, 0xf0, 0xd0, - 0xf5, 0x61, 0x1b, 0x7b, 0xb5, 0xc8, 0xd9, 0xed, 0xb1, 0xda, 0xa6, 0x6e, - 0x14, 0x6c, 0x9f, 0xdc, 0x35, 0x53, 0x62, 0x3f, 0xd8, 0x06, 0x21, 0xea, - 0x1d, 0x36, 0x1b, 0x37, 0x4c, 0x79, 0xd9, 0x89, 0xcd, 0x4c, 0x61, 0x03, - 0xa8, 0xc0, 0x11, 0x39, 0xfe, 0x1a, 0x0d, 0xc7, 0x17, 0x19, 0xe7, 0x96, - 0xc0, 0x59, 0xc1, 0xfa, 0xe2, 0x80, 0xed, 0x91, 0xb2, 0x3c, 0xc4, 0x1e, - 0xb6, 0x01, 0x66, 0x6b, 0xe9, 0x00, 0x69, 0xe3, 0x94, 0x9b, 0x89, 0xa6, - 0xed, 0x4e, 0x26, 0xef, 0x26, 0x28, 0xef, 0x5c, 0xf3, 0x91, 0x13, 0x31, - 0xfb, 0x4e, 0x19, 0x58, 0x59, 0xfb, 0x46, 0xda, 0x7e, 0x19, 0x04, 0x5b, - 0xb0, 0xf1, 0xc0, 0x8b, 0x9c, 0x25, 0x91, 0xc1, 0xd6, 0x75, 0x42, 0x62, - 0xc0, 0x9f, 0x43, 0x2f, 0x06, 0x38, 0xd9, 0xc6, 0x9c, 0xee, 0x4f, 0x67, - 0xb1, 0xeb, 0xaf, 0xbc, 0x6d, 0x2a, 0xd1, 0x67, 0x98, 0xa3, 0x65, 0x3e, - 0x36, 0x51, 0x3f, 0x0a, 0x6e, 0xf5, 0x22, 0x37, 0x6e, 0x96, 0x80, 0x5d, - 0xd6, 0xb6, 0x81, 0xb3, 0xae, 0xa2, 0x39, 0x93, 0x95, 0x52, 0x55, 0x73, - 0x4a, 0x91, 0x85, 0xae, 0xb3, 0x7e, 0x33, 0x89, 0xc1, 0xcc, 0xaa, 0x09, - 0x8c, 0x19, 0xba, 0x20, 0x1e, 0x74, 0xe9, 0xfa, 0x6e, 0xe8, 0x6c, 0x33, - 0xf9, 0x74, 0x52, 0x81, 0x01, 0xc3, 0xba, 0x76, 0x77, 0x41, 0xf8, 0x8a, - 0x96, 0x4e, 0xe4, 0xa2, 0x44, 0x1e, 0x28, 0xd8, 0x60, 0xb7, 0x80, 0xff, - 0x7a, 0x1a, 0x13, 0xa6, 0xeb, 0xc3, 0x6e, 0x8f, 0x96, 0x89, 0xe0, 0x0b, - 0xc2, 0xb4, 0x61, 0xbf, 0xa3, 0x5a, 0x07, 0x84, 0xf7, 0x05, 0xe1, 0x0d, - 0x88, 0xf0, 0xdc, 0x58, 0x86, 0x77, 0x97, 0xb5, 0x6b, 0x27, 0xfa, 0x3d, - 0x19, 0x15, 0x1d, 0x21, 0xc0, 0xaf, 0x73, 0xc4, 0xba, 0x28, 0xe7, 0x78, - 0x56, 0x51, 0xcb, 0xe5, 0xdc, 0xda, 0xc7, 0xce, 0x77, 0x95, 0x3a, 0x84, - 0x88, 0xa8, 0xfe, 0x54, 0xc1, 0xbe, 0x75, 0xfc, 0xf4, 0xcd, 0x3a, 0x68, - 0x1e, 0x27, 0x0d, 0x33, 0xe6, 0x05, 0xf7, 0x58, 0xe4, 0x3e, 0xf1, 0x5e, - 0xdc, 0x6d, 0xc2, 0xfb, 0x22, 0x08, 0x77, 0x4e, 0x9c, 0xd9, 0x67, 0xc6, - 0x27, 0xb3, 0x81, 0x83, 0xe7, 0xc7, 0x89, 0xfd, 0x63, 0x36, 0x4f, 0xce, - 0xf6, 0xe0, 0x26, 0x6c, 0xc2, 0x87, 0xa5, 0xd3, 0xc1, 0xff, 0xfb, 0x80, - 0xe8, 0x6f, 0xb3, 0x30, 0xa9, 0x40, 0xb8, 0x7c, 0x08, 0x5b, 0xed, 0x16, - 0x5a, 0x7b, 0xf1, 0xa3, 0x1b, 0xba, 0xeb, 0x8c, 0xde, 0x2a, 0xa7, 0xf7, - 0x83, 0xa4, 0x49, 0xd6, 0xc0, 0xce, 0x84, 0x75, 0x4a, 0xe7, 0x03, 0x4d, - 0xee, 0x1a, 0x2f, 0xdd, 0xe2, 0x74, 0xda, 0xfa, 0xe9, 0xcc, 0xd8, 0x36, - 0x5a, 0xd7, 0x4e, 0x67, 0xe0, 0xae, 0x3c, 0x2c, 0x33, 0x17, 0xbd, 0x34, - 0xb5, 0x53, 0xe1, 0xb4, 0xc4, 0x6a, 0x2b, 0x4c, 0x43, 0xa5, 0x97, 0xa6, - 0x7e, 0x22, 0x53, 0xec, 0x33, 0x04, 0xa1, 0xa9, 0xa6, 0x31, 0xd7, 0x0e, - 0x7e, 0x34, 0xaf, 0x34, 0xe4, 0xc4, 0x89, 0xe2, 0x90, 0x8c, 0x7a, 0xd6, - 0x2c, 0xd4, 0x2a, 0xba, 0x67, 0xf5, 0xd8, 0x6f, 0x02, 0xdf, 0xd5, 0x8e, - 0x9c, 0x5a, 0xae, 0x76, 0xf4, 0xf7, 0xa7, 0x11, 0x5b, 0x9c, 0xc5, 0x49, - 0xe4, 0x29, 0x33, 0x8a, 0x86, 0x82, 0x22, 0xf1, 0x23, 0x19, 0x5d, 0xb3, - 0x20, 0x8e, 0xd2, 0x9d, 0x66, 0x44, 0xf6, 0xe5, 0xb2, 0x8d, 0xe6, 0xfc, - 0x4f, 0xdf, 0x68, 0x14, 0x1e, 0x93, 0x44, 0x14, 0x6f, 0xbb, 0x43, 0x28, - 0x38, 0x1e, 0xb9, 0x43, 0x28, 0xb8, 0x15, 0x76, 0x88, 0x77, 0x27, 0xf8, - 0xee, 0x04, 0xdf, 0x9d, 0xe0, 0x9f, 0xea, 0x04, 0xaf, 0xfc, 0xb5, 0xfb, - 0x82, 0x8f, 0xa7, 0x93, 0xd0, 0xdb, 0x79, 0xb1, 0xf7, 0xe4, 0xa2, 0x91, - 0x70, 0x72, 0xc6, 0x07, 0x72, 0xc8, 0xf7, 0x39, 0x2f, 0xde, 0xee, 0xb0, - 0x43, 0xb4, 0x2d, 0x70, 0x76, 0x3f, 0xb3, 0x25, 0x69, 0x42, 0x6e, 0xa3, - 0xcb, 0x5d, 0x26, 0xe6, 0xe2, 0xad, 0xdc, 0x28, 0xe9, 0xb7, 0xc0, 0xac, - 0x59, 0xd7, 0x32, 0x1b, 0xb9, 0xfe, 0x43, 0xfc, 0x08, 0xb4, 0xed, 0x68, - 0x9b, 0xd2, 0x29, 0x50, 0xa2, 0xb4, 0x79, 0xb3, 0x8a, 0x3d, 0x77, 0x6a, - 0x4b, 0x2f, 0xd6, 0x1a, 0x85, 0xd5, 0x96, 0xc8, 0x2c, 0x40, 0x43, 0x79, - 0x37, 0x98, 0x69, 0x63, 0x27, 0xf8, 0x8c, 0x66, 0x15, 0x73, 0xdd, 0x07, - 0xf8, 0x4f, 0x91, 0x76, 0x6c, 0x5b, 0xcf, 0x77, 0x23, 0xad, 0xc1, 0x12, - 0x2a, 0xec, 0xd5, 0x83, 0xbd, 0xd6, 0x60, 0x29, 0x65, 0x14, 0x87, 0xde, - 0x5e, 0x6b, 0xb9, 0x98, 0xc8, 0xf1, 0x1f, 0xb6, 0x42, 0xf7, 0x4d, 0x1d, - 0x65, 0x8e, 0x73, 0x4b, 0x4b, 0xbf, 0x71, 0xfc, 0x8c, 0xba, 0x5d, 0x6d, - 0x65, 0xdc, 0xb9, 0x61, 0x8c, 0x6d, 0xa3, 0x1b, 0x86, 0xce, 0x2b, 0x5f, - 0x1e, 0x51, 0xb6, 0x34, 0x1a, 0xd0, 0xd2, 0x60, 0xf6, 0x44, 0x4e, 0x85, - 0x5e, 0x88, 0xcf, 0x88, 0x8c, 0xc7, 0x0f, 0xb7, 0xea, 0x77, 0xf3, 0xf9, - 0xf3, 0xcd, 0x47, 0x76, 0xa8, 0x59, 0x30, 0x23, 0xa5, 0x7a, 0x5a, 0x60, - 0x92, 0x6e, 0xe0, 0xc4, 0x0e, 0x9a, 0x1f, 0xeb, 0x92, 0x98, 0xb3, 0x41, - 0x1e, 0xf3, 0xcd, 0x1a, 0xc5, 0x34, 0x6c, 0x4a, 0xfc, 0x72, 0xfa, 0x5a, - 0x14, 0x77, 0xc9, 0x76, 0xca, 0xe7, 0x06, 0x0f, 0xd3, 0xc0, 0xbe, 0x26, - 0xd4, 0xbe, 0x12, 0xa7, 0xaf, 0x31, 0xb2, 0x11, 0x31, 0x32, 0x99, 0x54, - 0x35, 0xa1, 0x79, 0xa6, 0x3a, 0x89, 0x5c, 0x65, 0x6e, 0xd3, 0x4f, 0x5f, - 0x65, 0xc2, 0xe2, 0xec, 0x4b, 0x95, 0x7c, 0x39, 0x42, 0xb3, 0x47, 0x67, - 0x8d, 0x43, 0x0b, 0xe9, 0x92, 0xa0, 0xdd, 0x4c, 0xf5, 0xfa, 0x1f, 0xb5, - 0x1a, 0x9a, 0x3f, 0xf2, 0x23, 0x02, 0x93, 0xe2, 0xb3, 0xb7, 0xc5, 0x91, - 0xb7, 0x8b, 0xff, 0x6b, 0xbb, 0xc5, 0x7b, 0xaf, 0xe7, 0xa3, 0xe5, 0x2b, - 0xfa, 0xdd, 0x0d, 0x7d, 0x1c, 0xfb, 0xe2, 0x81, 0x78, 0x6b, 0x87, 0xe6, - 0x08, 0x09, 0xb3, 0x9f, 0x51, 0xad, 0x56, 0x29, 0x1d, 0xa8, 0x77, 0x2c, - 0xc3, 0x17, 0x1c, 0x7c, 0xac, 0x71, 0xbf, 0x11, 0x1b, 0x7a, 0xe8, 0xae, - 0x82, 0x10, 0x88, 0xd7, 0xf5, 0x29, 0xdd, 0x9b, 0xc3, 0x6e, 0x89, 0x19, - 0x60, 0x77, 0xe7, 0xc4, 0x78, 0xd1, 0x2c, 0x0f, 0x38, 0x9a, 0x74, 0x88, - 0xbf, 0x8c, 0x74, 0x11, 0x96, 0x2e, 0x0b, 0xc8, 0x92, 0xc4, 0x34, 0x9a, - 0x8a, 0x72, 0x8b, 0xc6, 0xb2, 0x9a, 0xd0, 0xaa, 0x61, 0x2d, 0x66, 0x69, - 0x5c, 0xc5, 0xba, 0xe7, 0x62, 0x39, 0x6f, 0x6b, 0xe5, 0xc2, 0x38, 0xdc, - 0x5d, 0x22, 0x16, 0x4f, 0xe5, 0x39, 0x74, 0xf4, 0x7e, 0x97, 0x71, 0xb8, - 0x9f, 0x65, 0x6a, 0xe1, 0x4b, 0xa2, 0xdd, 0x34, 0x6c, 0x9d, 0x44, 0x90, - 0x8c, 0x41, 0x5b, 0xb5, 0xa6, 0xb4, 0xf2, 0x0b, 0xfc, 0x8d, 0xf7, 0x70, - 0x08, 0x99, 0x21, 0xf5, 0xbc, 0x38, 0xdb, 0xb7, 0xce, 0x41, 0x9f, 0x33, - 0x74, 0xc2, 0xed, 0x2b, 0xba, 0x47, 0x87, 0x3d, 0xb6, 0x3d, 0xbc, 0x7a, - 0x5c, 0x9f, 0x9c, 0xea, 0x8e, 0x3a, 0x11, 0xa6, 0xac, 0x94, 0x2c, 0xf4, - 0x89, 0x42, 0x83, 0x71, 0x18, 0xa4, 0x03, 0xdd, 0x7d, 0xfc, 0x58, 0x9b, - 0xbb, 0xc4, 0xf9, 0x1e, 0xfc, 0x15, 0x11, 0x44, 0xd1, 0x2a, 0x2d, 0x38, - 0x54, 0x25, 0xcb, 0x16, 0x2f, 0x59, 0xe6, 0x15, 0x22, 0x78, 0x09, 0xf6, - 0x83, 0x27, 0x37, 0x74, 0x1e, 0xc8, 0x15, 0x8f, 0xb3, 0x46, 0xe2, 0xd9, - 0x4e, 0x18, 0xa6, 0xf5, 0xed, 0xec, 0x27, 0xde, 0xde, 0x45, 0x33, 0x77, - 0xeb, 0xae, 0xe2, 0x62, 0x07, 0xfa, 0x23, 0x3f, 0x3b, 0x72, 0x79, 0x11, - 0x5e, 0xa7, 0x63, 0xcc, 0x31, 0xb9, 0x96, 0xd2, 0x1c, 0x45, 0x25, 0x6e, - 0xd5, 0x85, 0x21, 0xee, 0x0a, 0x7c, 0xac, 0xad, 0xa3, 0x65, 0xd1, 0xf5, - 0x63, 0x0f, 0xbb, 0x45, 0x27, 0x22, 0x07, 0x15, 0xb6, 0x71, 0x90, 0xcb, - 0xb3, 0x11, 0x0b, 0x3e, 0xf2, 0xfd, 0xe8, 0x13, 0xb9, 0x43, 0x6a, 0x55, - 0x88, 0x5a, 0x08, 0x1a, 0x6f, 0x36, 0x91, 0x0b, 0x88, 0x56, 0xef, 0xfe, - 0xfa, 0xdb, 0x60, 0xf5, 0xfb, 0x33, 0x16, 0xad, 0x14, 0x1e, 0x56, 0xbf, - 0xcf, 0x4a, 0x86, 0x33, 0x75, 0x89, 0x7e, 0x5c, 0x74, 0xe1, 0xac, 0x3c, - 0xff, 0x81, 0xf3, 0x3c, 0xe6, 0x7a, 0x26, 0x61, 0x89, 0xa3, 0x8e, 0x67, - 0x27, 0x5c, 0x1b, 0xb0, 0xac, 0x76, 0x49, 0x73, 0xb1, 0x75, 0x62, 0xb6, - 0xf3, 0x21, 0xfc, 0xe3, 0x03, 0x77, 0x2e, 0xe0, 0xdd, 0x15, 0xa1, 0xae, - 0x91, 0xcd, 0x86, 0x8c, 0x21, 0xa1, 0x57, 0x5f, 0xf8, 0x1a, 0xf9, 0x37, - 0x6a, 0x05, 0x94, 0x49, 0xd6, 0x75, 0x07, 0xea, 0x9a, 0xd1, 0xcd, 0x28, - 0x9d, 0xba, 0xcb, 0xcd, 0x36, 0x70, 0xf4, 0x7d, 0x12, 0x73, 0xc3, 0x5b, - 0xf7, 0x3a, 0xce, 0xae, 0xd3, 0xcf, 0xcf, 0xa1, 0x3e, 0x45, 0xba, 0x6f, - 0xed, 0x73, 0xfa, 0x69, 0x8e, 0xbe, 0xa0, 0x65, 0x70, 0xf0, 0xd7, 0x4e, - 0xf8, 0x9a, 0x6d, 0x81, 0xf5, 0x3a, 0xd4, 0x31, 0x21, 0xde, 0x67, 0xa1, - 0x99, 0xd8, 0x2c, 0xd1, 0x76, 0xbb, 0x38, 0x0c, 0x13, 0x61, 0xcb, 0xeb, - 0x24, 0x1d, 0x82, 0x25, 0xc6, 0x38, 0xf1, 0xa3, 0x1b, 0xb9, 0x2c, 0xba, - 0xc1, 0x6b, 0x33, 0x74, 0x71, 0xdf, 0xb8, 0x09, 0x9d, 0x63, 0xcd, 0xaa, - 0x75, 0x6a, 0x67, 0xd8, 0x93, 0x93, 0x86, 0x6b, 0x74, 0x12, 0x07, 0x7b, - 0x64, 0xb5, 0x11, 0x8e, 0x3b, 0xe9, 0xf1, 0xdf, 0x61, 0x54, 0x0d, 0xfb, - 0x23, 0xbc, 0xf6, 0xc5, 0xce, 0xd1, 0xad, 0x4f, 0x77, 0xb2, 0xc2, 0x74, - 0x2c, 0xfd, 0xee, 0x2e, 0xf1, 0xc1, 0xeb, 0x21, 0xe6, 0xbb, 0x2c, 0x24, - 0x17, 0xc3, 0x28, 0xc5, 0xdb, 0xa3, 0xcf, 0x38, 0xd4, 0x0e, 0x9e, 0xb9, - 0x5c, 0xc0, 0x94, 0x89, 0x40, 0x89, 0x3e, 0xb9, 0xde, 0xc3, 0x23, 0x89, - 0xd0, 0xd1, 0x9e, 0x64, 0x3b, 0xa1, 0xf9, 0x34, 0x4d, 0x62, 0x0d, 0xce, - 0xf1, 0x33, 0x31, 0xb6, 0x52, 0x86, 0x0d, 0x7d, 0x4a, 0x46, 0x64, 0xd8, - 0x0b, 0xe2, 0x38, 0xd8, 0xa1, 0x34, 0x1b, 0x8b, 0xc3, 0x43, 0xcf, 0x77, - 0x84, 0xcb, 0xf0, 0x4a, 0x92, 0x17, 0x19, 0x8f, 0xdc, 0x4d, 0x6c, 0xc2, - 0xb6, 0x9a, 0x1e, 0xee, 0x3c, 0xf7, 0x79, 0x1f, 0x84, 0x71, 0xc1, 0x46, - 0xc1, 0x33, 0x7a, 0x46, 0xdd, 0x77, 0xfd, 0x18, 0x9b, 0xea, 0xd7, 0xda, - 0xca, 0x6c, 0x86, 0x91, 0x65, 0xff, 0xdc, 0x04, 0xa7, 0x98, 0x67, 0xf9, - 0xa5, 0x9c, 0x65, 0x1d, 0xe0, 0x58, 0x32, 0xbd, 0x7b, 0xb4, 0xc3, 0xba, - 0x25, 0x3b, 0xde, 0xce, 0x79, 0xc1, 0xc1, 0xb0, 0xb7, 0xdf, 0x13, 0x4f, - 0xba, 0xdf, 0x3a, 0x3e, 0xcf, 0x47, 0x58, 0x75, 0x30, 0x2c, 0x4e, 0x73, - 0x75, 0xf7, 0xcf, 0x80, 0x33, 0xe2, 0x56, 0x21, 0x78, 0xa3, 0x3c, 0x03, - 0xcf, 0x57, 0x33, 0xa8, 0xe8, 0xcd, 0x88, 0x25, 0xec, 0x71, 0x20, 0xf2, - 0xe5, 0x2b, 0x9a, 0xad, 0xf0, 0x86, 0xce, 0x0b, 0xa4, 0xac, 0x7a, 0x56, - 0x58, 0x55, 0x26, 0xde, 0x4f, 0xce, 0x76, 0x53, 0xe3, 0xeb, 0xc7, 0x3a, - 0xb5, 0xda, 0xd8, 0xf0, 0xb1, 0x17, 0xa1, 0x86, 0x7f, 0xe4, 0x0c, 0x65, - 0xee, 0xd9, 0x5a, 0xd2, 0x33, 0x3f, 0x72, 0xf6, 0xf7, 0x74, 0xf2, 0x2e, - 0x55, 0x68, 0xde, 0x60, 0xdb, 0x26, 0x52, 0xb8, 0x4f, 0xdd, 0xd8, 0xc9, - 0xfd, 0x8a, 0xe4, 0xb4, 0xef, 0xa3, 0x8f, 0xdf, 0x3a, 0xf5, 0x74, 0x4c, - 0xa5, 0x1c, 0x2b, 0xce, 0x57, 0x2c, 0x84, 0xa3, 0x01, 0x27, 0x92, 0x4e, - 0x25, 0xfc, 0x3c, 0x67, 0x97, 0x4c, 0x7a, 0x10, 0x1c, 0x70, 0x20, 0x53, - 0x4b, 0x2e, 0x96, 0xb0, 0x5a, 0xfc, 0xc0, 0xaf, 0xed, 0x22, 0x29, 0xb1, - 0x25, 0xc6, 0xdb, 0x85, 0xaa, 0x8b, 0x22, 0x4b, 0x3a, 0xae, 0xee, 0x16, - 0x07, 0x6f, 0xc9, 0xe9, 0x88, 0x84, 0x71, 0x52, 0x8c, 0x60, 0x0b, 0x0c, - 0xcf, 0x24, 0x4f, 0x04, 0x5f, 0x0a, 0x51, 0x06, 0xa4, 0x29, 0x22, 0xd2, - 0xd2, 0x5d, 0x39, 0x71, 0xea, 0xb6, 0xfe, 0x96, 0x46, 0xa0, 0xb6, 0xec, - 0x8e, 0x36, 0xa1, 0x21, 0x90, 0xdb, 0xad, 0x76, 0xa5, 0xa4, 0x4e, 0x5e, - 0x2c, 0x57, 0x78, 0xaf, 0xc5, 0x51, 0xb7, 0x46, 0x3c, 0xad, 0x7f, 0x17, - 0xf1, 0x74, 0x0f, 0x71, 0x50, 0xf3, 0x98, 0x4c, 0x48, 0xc8, 0x4f, 0xc5, - 0x45, 0xb3, 0x3e, 0x88, 0x26, 0xec, 0x68, 0x9e, 0x18, 0xb2, 0x48, 0xfd, - 0x71, 0x44, 0xbc, 0x83, 0x6e, 0x37, 0x69, 0x46, 0x8e, 0xdd, 0x80, 0xd2, - 0x98, 0x05, 0xe2, 0xa9, 0x3f, 0x9b, 0xd0, 0x22, 0x44, 0xe1, 0xb0, 0x87, - 0x4e, 0x9a, 0x2f, 0x1f, 0x21, 0x56, 0x85, 0xe3, 0x49, 0x91, 0x57, 0xe2, - 0x70, 0x4f, 0xf0, 0xea, 0x23, 0x37, 0xdb, 0xdc, 0x37, 0xf0, 0xe4, 0x08, - 0xd9, 0x7d, 0x74, 0x71, 0x00, 0xf3, 0xac, 0x65, 0x5c, 0x8a, 0x49, 0x1a, - 0x85, 0xb0, 0xf2, 0x72, 0x47, 0xea, 0x42, 0x52, 0x83, 0xc4, 0x4b, 0xde, - 0xf2, 0x77, 0xec, 0x6e, 0x3f, 0x82, 0x4f, 0x0d, 0x06, 0xa1, 0x94, 0x82, - 0xa1, 0xa3, 0xaf, 0x76, 0x15, 0xe6, 0xad, 0xf3, 0xac, 0x53, 0x92, 0xc4, - 0x0b, 0x75, 0xbe, 0xb5, 0x51, 0x52, 0xc3, 0x50, 0xcd, 0xb7, 0x9e, 0xe9, - 0xf3, 0x36, 0x34, 0xf5, 0x53, 0xbb, 0x3f, 0x65, 0xff, 0xee, 0x07, 0x4f, - 0x68, 0xcd, 0xca, 0x03, 0x00, 0x6e, 0xfa, 0x04, 0x4e, 0xc2, 0x0d, 0xdd, - 0xd2, 0x5c, 0x10, 0x1a, 0x78, 0xa1, 0x4b, 0xb3, 0x38, 0xe8, 0x72, 0x7e, - 0x7a, 0x39, 0x04, 0x58, 0xea, 0x57, 0x1a, 0x4b, 0xa3, 0xa0, 0x2c, 0x5b, - 0x01, 0x67, 0x6d, 0xce, 0xf4, 0xcb, 0x2b, 0x39, 0x5f, 0x27, 0xc9, 0xc2, - 0xac, 0x90, 0xb3, 0xc0, 0x49, 0x7f, 0xf8, 0x4f, 0x0a, 0x49, 0x54, 0x97, - 0xea, 0x67, 0x06, 0xb9, 0xf4, 0x1f, 0x73, 0xab, 0x0e, 0x9c, 0xa8, 0x92, - 0x02, 0x02, 0x45, 0x32, 0xa9, 0x70, 0x86, 0x01, 0x12, 0xc8, 0xd8, 0xe0, - 0x3e, 0x0d, 0xa6, 0xac, 0x86, 0x32, 0x75, 0x81, 0xe5, 0xd5, 0x1f, 0x6d, - 0x83, 0x7a, 0x89, 0x30, 0x5b, 0x1a, 0x2b, 0xba, 0x2a, 0x90, 0xaa, 0xcc, - 0x43, 0x25, 0xaa, 0x02, 0x83, 0x42, 0x41, 0x89, 0x4a, 0x84, 0xaa, 0xae, - 0x8f, 0xab, 0x18, 0xa9, 0xba, 0x33, 0xb4, 0xf5, 0xab, 0xca, 0x70, 0x63, - 0x68, 0xeb, 0x17, 0x53, 0xba, 0x2d, 0xb0, 0x43, 0x27, 0xe7, 0x51, 0xe9, - 0x18, 0x9b, 0x6c, 0x0a, 0x6a, 0x1e, 0x06, 0xee, 0x36, 0x59, 0x42, 0xc7, - 0x3f, 0x26, 0x80, 0x1d, 0x2c, 0x3f, 0xa0, 0xf2, 0x43, 0x96, 0xd5, 0x2a, - 0xf1, 0xa7, 0xcc, 0x2d, 0xe3, 0x53, 0x2e, 0xbb, 0x17, 0x01, 0xae, 0x10, - 0xcc, 0x76, 0x0e, 0xac, 0xe2, 0xc3, 0xce, 0x57, 0x72, 0xa9, 0x76, 0x36, - 0xbe, 0x74, 0x77, 0x78, 0xab, 0x48, 0xb7, 0xa2, 0x6c, 0x26, 0x76, 0xab, - 0x59, 0x12, 0x75, 0x27, 0x5b, 0x82, 0x75, 0xdc, 0xf6, 0x97, 0xb4, 0xae, - 0x1f, 0x93, 0xe5, 0x8b, 0xe2, 0xf0, 0xb0, 0xca, 0x6a, 0xc1, 0xd9, 0x05, - 0xd5, 0x94, 0x5d, 0x50, 0x41, 0x99, 0x45, 0xec, 0xc5, 0xd9, 0xd3, 0x19, - 0x46, 0xe9, 0x45, 0xb8, 0x4b, 0x72, 0xff, 0x87, 0xe2, 0x47, 0x52, 0x8c, - 0xee, 0x9a, 0x95, 0xa3, 0x2b, 0x93, 0x86, 0x78, 0x53, 0x5c, 0x6d, 0x0f, - 0x6b, 0x76, 0x47, 0x47, 0xaf, 0xcb, 0xd6, 0xe8, 0x89, 0xd5, 0x05, 0xe0, - 0x3d, 0xc9, 0xf9, 0x86, 0xcc, 0x6c, 0x3f, 0x39, 0xc5, 0x1b, 0xe4, 0x8b, - 0xf5, 0xd3, 0xe6, 0xf7, 0x70, 0xb7, 0xbe, 0xb7, 0xc1, 0x8e, 0x33, 0x42, - 0x27, 0x7e, 0x10, 0xa3, 0x03, 0x49, 0x98, 0xaf, 0x0e, 0x21, 0x76, 0x4a, - 0xf1, 0xf6, 0x15, 0x5a, 0x5d, 0xf6, 0x52, 0xab, 0x4d, 0x75, 0x67, 0x77, - 0x4e, 0xf8, 0x8a, 0xa7, 0x10, 0x15, 0x4d, 0xb4, 0x51, 0x9d, 0x6d, 0x9f, - 0xf8, 0x22, 0xf5, 0x12, 0x6e, 0x2e, 0xc1, 0x35, 0x9c, 0xa4, 0x1f, 0xc9, - 0x61, 0xf8, 0xb0, 0x27, 0xb7, 0xa8, 0xd8, 0xc5, 0xa6, 0x37, 0xa9, 0x60, - 0x3a, 0x31, 0xdf, 0x6d, 0x26, 0x30, 0x75, 0xd7, 0x9d, 0xc2, 0x64, 0x80, - 0x83, 0x34, 0x33, 0x8a, 0x6f, 0xd6, 0x87, 0x65, 0xa0, 0x10, 0xb9, 0xaf, - 0x6e, 0x76, 0xf3, 0xca, 0x22, 0xe1, 0x88, 0x85, 0x38, 0x4b, 0x21, 0x51, - 0x2a, 0x84, 0xe9, 0xcd, 0xaa, 0xec, 0xe7, 0x41, 0x8c, 0xcf, 0x80, 0x59, - 0x27, 0x91, 0x74, 0x10, 0x14, 0x18, 0xb7, 0xaa, 0x32, 0xd6, 0xe8, 0xdb, - 0x6a, 0xbf, 0x91, 0xc2, 0xe5, 0x5e, 0x0d, 0xd4, 0x2d, 0xf4, 0xac, 0xd6, - 0x37, 0xdf, 0x1b, 0xde, 0x60, 0x0d, 0x1a, 0x28, 0xa5, 0xd8, 0x5f, 0x25, - 0xbd, 0xdb, 0xc5, 0x39, 0x19, 0x74, 0x61, 0xa8, 0x7b, 0xfb, 0xec, 0x18, - 0xe6, 0x1a, 0xfd, 0xdb, 0x9d, 0x37, 0xd2, 0x7f, 0xb1, 0x67, 0x03, 0x1b, - 0x68, 0x40, 0xcb, 0xf0, 0x97, 0x53, 0xb6, 0x39, 0x01, 0x1b, 0x15, 0x57, - 0x86, 0x7a, 0xaf, 0x2a, 0x09, 0x4f, 0x94, 0x53, 0x85, 0x8b, 0x2d, 0x7a, - 0xaf, 0x44, 0x19, 0x3b, 0xcf, 0x3f, 0x44, 0x7c, 0x8b, 0xee, 0x00, 0xae, - 0x52, 0xa9, 0x8e, 0x19, 0x1e, 0xee, 0x1a, 0x50, 0x65, 0xe5, 0x55, 0x7c, - 0x37, 0xb9, 0xc6, 0x23, 0x12, 0x2f, 0x50, 0x39, 0xb3, 0xa3, 0x6c, 0xae, - 0x8c, 0x21, 0x64, 0x67, 0x82, 0x52, 0x7e, 0x39, 0xa5, 0xcf, 0x87, 0x7f, - 0xfb, 0xe9, 0x17, 0xe1, 0x19, 0x71, 0xe3, 0x67, 0x72, 0x07, 0x40, 0x08, - 0x5d, 0xff, 0xb0, 0xcb, 0xba, 0xdd, 0xed, 0x1d, 0xfa, 0x9c, 0x32, 0xad, - 0x0b, 0xd8, 0x87, 0xee, 0xc6, 0x7b, 0xc1, 0xb3, 0x6b, 0x0c, 0x16, 0xfd, - 0xf1, 0xf5, 0xa4, 0x3b, 0x1d, 0x2e, 0x2e, 0x6e, 0x6f, 0xfa, 0xa9, 0x22, - 0xa5, 0x42, 0xe0, 0xe1, 0xdd, 0x70, 0x5a, 0x3c, 0x42, 0xc8, 0x27, 0xa9, - 0xe1, 0x6c, 0x06, 0x14, 0x7c, 0x8a, 0x24, 0xc3, 0xff, 0xbd, 0xed, 0x8e, - 0x80, 0xd3, 0x80, 0xcc, 0x46, 0x22, 0x6a, 0x80, 0x44, 0x97, 0xd3, 0x61, - 0x77, 0x2e, 0x8c, 0xa8, 0x09, 0x52, 0xdd, 0x8c, 0xe7, 0x32, 0xb3, 0x16, - 0xcc, 0x4c, 0x26, 0x6a, 0x83, 0x44, 0xdd, 0xd1, 0xe7, 0xee, 0x57, 0x3e, - 0xbf, 0xf4, 0x99, 0xf2, 0x29, 0x11, 0x71, 0x41, 0xd8, 0xbd, 0x2d, 0x3e, - 0x12, 0x65, 0x37, 0x6e, 0xa2, 0xa0, 0x7b, 0xa3, 0xe1, 0xcd, 0x60, 0x71, - 0xd1, 0xed, 0xcf, 0xc7, 0x53, 0x48, 0xd0, 0xf7, 0xc3, 0xe9, 0x58, 0x23, - 0xe7, 0xf1, 0xcd, 0x50, 0x23, 0xe6, 0xd9, 0xb4, 0x8f, 0x35, 0x3a, 0x1a, - 0x4f, 0x35, 0xa2, 0xbe, 0xba, 0xb9, 0x5b, 0x14, 0x69, 0x61, 0x89, 0x0f, - 0x66, 0xf3, 0x1c, 0x1d, 0x2c, 0x73, 0xc2, 0xb3, 0x48, 0x0b, 0x0b, 0x9e, - 0xf4, 0xdd, 0x1d, 0x4d, 0x3e, 0x75, 0x35, 0xb2, 0x4f, 0xc7, 0x29, 0xd3, - 0x9e, 0x29, 0xc7, 0x29, 0xd3, 0x75, 0x4a, 0xc7, 0x29, 0xd3, 0x9e, 0x83, - 0xb4, 0xfd, 0xf1, 0x4d, 0x61, 0x46, 0x16, 0xac, 0x1c, 0xc2, 0x16, 0x24, - 0x87, 0x35, 0xc5, 0x48, 0xe5, 0x31, 0x58, 0x6a, 0x65, 0x81, 0xe4, 0xb0, - 0xbe, 0x32, 0x79, 0x2d, 0x66, 0xdd, 0xf9, 0xed, 0x14, 0xaf, 0x16, 0xde, - 0xa2, 0x69, 0x60, 0xbc, 0x2c, 0xc1, 0x51, 0x34, 0xdd, 0xeb, 0xf1, 0x60, - 0x08, 0x19, 0x6e, 0x77, 0x30, 0xd0, 0xd8, 0xed, 0xec, 0xb6, 0xa7, 0xb1, - 0xdb, 0xa9, 0x48, 0x02, 0x4b, 0xe1, 0xfa, 0xea, 0x46, 0x63, 0xa8, 0xd7, - 0xdd, 0x2f, 0x1a, 0x13, 0xbd, 0xbe, 0xd5, 0x79, 0x84, 0x59, 0x7f, 0x3a, - 0x1c, 0xde, 0x68, 0xac, 0x72, 0xd0, 0x9d, 0xfe, 0x53, 0x20, 0x82, 0xcd, - 0x71, 0x74, 0x75, 0xf9, 0x69, 0x2e, 0x50, 0x75, 0x4a, 0x45, 0x9f, 0xbe, - 0x50, 0x1a, 0xef, 0x65, 0xd1, 0xcf, 0x30, 0x8b, 0xfe, 0xd5, 0x68, 0x31, - 0x9e, 0x1c, 0xe9, 0x33, 0xfe, 0x39, 0x1c, 0x4e, 0x74, 0xc2, 0x1f, 0x4e, - 0x46, 0xdd, 0xfe, 0x50, 0xeb, 0x32, 0xfa, 0x5a, 0x4f, 0x31, 0xec, 0x1b, - 0x38, 0x89, 0xe1, 0x74, 0xae, 0x51, 0x02, 0xee, 0xea, 0xf3, 0xb4, 0x3b, - 0xd1, 0x69, 0x61, 0x28, 0x53, 0x95, 0x3b, 0x66, 0xa1, 0x1a, 0x48, 0x94, - 0xef, 0x64, 0x7a, 0x75, 0x0d, 0x49, 0x76, 0x32, 0xbe, 0xba, 0x99, 0xcf, - 0x34, 0xb2, 0x1d, 0x5d, 0xdd, 0x0c, 0x75, 0x1b, 0x1f, 0xa1, 0x59, 0x8c, - 0xc6, 0xe3, 0x89, 0x46, 0xbc, 0x94, 0x6e, 0x36, 0x9f, 0x5e, 0x4d, 0x34, - 0x42, 0xc6, 0x24, 0xdd, 0x9b, 0xcb, 0x91, 0xd0, 0x31, 0x2c, 0xe9, 0x94, - 0x2e, 0xc7, 0x14, 0x96, 0x78, 0x46, 0x7c, 0xd1, 0xd5, 0x19, 0x3f, 0x93, - 0xcc, 0x62, 0x7e, 0xc1, 0x27, 0x0e, 0x13, 0x52, 0xe9, 0x48, 0x74, 0xaa, - 0x85, 0x92, 0x48, 0x48, 0xa2, 0x85, 0x7d, 0x37, 0x97, 0x92, 0x44, 0x0c, - 0x3b, 0xef, 0x4c, 0x52, 0x22, 0xad, 0x0d, 0xab, 0x52, 0x96, 0x96, 0xd4, - 0x00, 0xd6, 0xab, 0x28, 0x31, 0x89, 0xdc, 0x2e, 0x9a, 0x61, 0x92, 0xa2, - 0x4a, 0x81, 0x5c, 0xd2, 0x8c, 0x22, 0x41, 0x77, 0x61, 0xb4, 0x12, 0x81, - 0x95, 0x12, 0x10, 0x74, 0x17, 0xe0, 0xef, 0xcd, 0xf4, 0xef, 0x0c, 0xdd, - 0x05, 0xa0, 0x68, 0x49, 0x14, 0x02, 0xac, 0x0b, 0x40, 0xdb, 0xfe, 0x90, - 0x79, 0x20, 0x27, 0x8f, 0xe7, 0x02, 0x90, 0x9f, 0xa5, 0xe4, 0x10, 0x90, - 0x0b, 0x40, 0xdf, 0x49, 0xe9, 0x8b, 0x40, 0x2e, 0x00, 0xf5, 0xb9, 0x44, - 0x8d, 0xcf, 0x2d, 0x64, 0xad, 0x3e, 0x79, 0x01, 0x0e, 0xfd, 0xe9, 0x5b, - 0x53, 0x50, 0x5c, 0x99, 0x40, 0x93, 0x64, 0xd3, 0x7d, 0x2d, 0xf0, 0xb7, - 0xaf, 0x28, 0xcb, 0x4d, 0x83, 0x10, 0x26, 0x69, 0x86, 0x33, 0x6d, 0x9b, - 0xbd, 0x15, 0xad, 0xd0, 0xd8, 0xe6, 0x1d, 0xaf, 0xc9, 0x49, 0x25, 0xdf, - 0x96, 0xa4, 0xd1, 0xd4, 0xc3, 0x6e, 0xe4, 0x5a, 0xf3, 0x2e, 0x4f, 0x01, - 0xab, 0xb1, 0x9a, 0x05, 0xd1, 0xc4, 0xa1, 0xe3, 0x47, 0xe4, 0x6c, 0x87, - 0x36, 0xae, 0xbb, 0x5e, 0x62, 0xea, 0x92, 0x1c, 0x27, 0xbb, 0xd7, 0x5e, - 0x05, 0x07, 0x1f, 0x38, 0x6a, 0x98, 0xe6, 0x58, 0x93, 0xa1, 0x64, 0xe6, - 0xc5, 0x01, 0x70, 0x1c, 0x72, 0x5f, 0xbc, 0x7a, 0x74, 0x3c, 0x9f, 0x54, - 0xda, 0xa7, 0x88, 0x34, 0xc0, 0x38, 0x0c, 0x6e, 0x05, 0xf5, 0x69, 0xeb, - 0x0c, 0xde, 0x47, 0x1a, 0xc7, 0xf7, 0xee, 0xee, 0xac, 0x38, 0xed, 0xd9, - 0x0f, 0x9a, 0x69, 0xb6, 0x8a, 0x40, 0xe0, 0x1f, 0xc8, 0xba, 0xce, 0x65, - 0x17, 0x70, 0xd7, 0x1f, 0xa0, 0x95, 0xb3, 0x7a, 0x74, 0x41, 0xe3, 0xb2, - 0xeb, 0xb2, 0x13, 0x10, 0xde, 0x2b, 0xd2, 0x57, 0xe2, 0xde, 0x8a, 0xf9, - 0x85, 0x91, 0x62, 0xaa, 0x74, 0x5e, 0xc6, 0x13, 0xcd, 0x35, 0xc6, 0x66, - 0x5f, 0x9a, 0x78, 0x37, 0x15, 0x92, 0x6d, 0x15, 0xf5, 0x73, 0xb5, 0xdb, - 0x6f, 0xbd, 0x95, 0x17, 0x97, 0x0f, 0x9f, 0x3e, 0x60, 0x27, 0x92, 0xa4, - 0x89, 0x16, 0xff, 0x1b, 0x2f, 0x22, 0x92, 0xd1, 0xd8, 0xc5, 0xd1, 0x0c, - 0x5f, 0x92, 0xd1, 0xcc, 0x0e, 0x7b, 0x37, 0x24, 0xbd, 0x82, 0x99, 0x93, - 0x25, 0x85, 0xcd, 0x91, 0x1e, 0xda, 0xbb, 0x69, 0xcb, 0x28, 0x6d, 0x99, - 0xb8, 0x0b, 0xb4, 0x85, 0xdf, 0x91, 0xda, 0x46, 0x38, 0x39, 0x00, 0x5b, - 0xd5, 0xec, 0x0d, 0x2a, 0x1f, 0xc3, 0xe0, 0x59, 0xd9, 0x5c, 0x7f, 0x17, - 0xb4, 0x62, 0xd7, 0x40, 0x6f, 0x24, 0xfd, 0xcc, 0xb9, 0x66, 0xa2, 0x96, - 0x2e, 0xb8, 0x4a, 0x47, 0x4f, 0x6f, 0x3f, 0xd2, 0x66, 0x40, 0x7a, 0xb1, - 0xe2, 0x5c, 0x74, 0xec, 0x2a, 0xce, 0xac, 0xc9, 0x97, 0x2a, 0x87, 0xdf, - 0x9a, 0x19, 0x00, 0x7a, 0x01, 0x60, 0x5b, 0x1c, 0x8a, 0xeb, 0x08, 0x96, - 0xe8, 0xc4, 0x4d, 0x9e, 0x56, 0x7d, 0x2c, 0xab, 0xba, 0xd0, 0x62, 0x4d, - 0x55, 0x11, 0x6c, 0xba, 0xc3, 0xab, 0xd0, 0xaa, 0x0c, 0xde, 0xeb, 0x30, - 0x0e, 0xe9, 0x71, 0x4b, 0xc1, 0x47, 0xfd, 0x34, 0x84, 0x5c, 0x4a, 0xb7, - 0xd0, 0xc1, 0xa7, 0x89, 0x6e, 0xb8, 0x84, 0x5b, 0x98, 0xf1, 0x21, 0x05, - 0x89, 0x38, 0x89, 0x3e, 0x72, 0xec, 0x1c, 0x45, 0xa7, 0xe6, 0x90, 0x3c, - 0x2a, 0xc4, 0x1f, 0x05, 0x63, 0x73, 0xb4, 0xb2, 0x7b, 0x53, 0x96, 0xe6, - 0xb0, 0x65, 0x1b, 0x82, 0x1e, 0x15, 0xec, 0x49, 0xdd, 0xe5, 0xc1, 0xc7, - 0xce, 0x0a, 0xef, 0x25, 0x94, 0x27, 0x0a, 0x0e, 0xb4, 0xaa, 0x75, 0x27, - 0xdc, 0xd0, 0x2b, 0xca, 0x1c, 0xb5, 0x7d, 0x99, 0x20, 0x54, 0x99, 0x3e, - 0xf9, 0xc8, 0x00, 0xe5, 0xb2, 0x1d, 0x77, 0x9b, 0x21, 0xa7, 0x24, 0x2a, - 0x95, 0x97, 0x94, 0xde, 0x04, 0x7a, 0x45, 0x9c, 0x90, 0xa3, 0x8c, 0x1e, - 0x06, 0x1a, 0xa9, 0x6c, 0xf3, 0x30, 0x1b, 0xc0, 0xe4, 0xcb, 0xe4, 0x73, - 0x96, 0x8b, 0x5e, 0xa9, 0x7c, 0xae, 0x9d, 0xf0, 0x77, 0x8d, 0xaf, 0x39, - 0x97, 0x7d, 0x0d, 0x0c, 0x48, 0xa3, 0x92, 0x6b, 0xd9, 0x35, 0x96, 0xc9, - 0x7e, 0x37, 0xc1, 0x7f, 0xc4, 0xcb, 0xf6, 0x91, 0x95, 0x72, 0xe0, 0x51, - 0x63, 0x1b, 0xdc, 0x13, 0x33, 0xdc, 0x91, 0xf2, 0x28, 0x6c, 0x8c, 0xb7, - 0x57, 0x17, 0x88, 0x56, 0x4d, 0xf2, 0x57, 0x05, 0xc2, 0xeb, 0x39, 0xf8, - 0x79, 0x9b, 0xd8, 0xc1, 0x97, 0xf1, 0x94, 0xf0, 0x00, 0x6c, 0x58, 0x7f, - 0x0f, 0x6f, 0x62, 0xc4, 0xe6, 0x98, 0x37, 0x95, 0xbd, 0x8f, 0x39, 0xf8, - 0x4d, 0x45, 0xef, 0x63, 0x8e, 0x94, 0x66, 0xec, 0x7d, 0xf4, 0x75, 0x3f, - 0x53, 0xe7, 0x59, 0x51, 0xee, 0xa6, 0xf7, 0xb2, 0x0a, 0xf8, 0x94, 0x4a, - 0x0f, 0xbe, 0x59, 0xb9, 0x22, 0xc2, 0xf4, 0x0f, 0xd8, 0xf6, 0xf5, 0x50, - 0x36, 0x32, 0xbd, 0xa5, 0x2d, 0xbc, 0x92, 0xe9, 0xed, 0x62, 0x6e, 0xa9, - 0x94, 0xbe, 0xa1, 0x85, 0x1b, 0x90, 0xe0, 0x5f, 0x3a, 0x0a, 0x22, 0x0e, - 0xd7, 0x72, 0xae, 0xa0, 0x98, 0xe5, 0x80, 0x5f, 0x2c, 0xd5, 0xfc, 0xef, - 0xff, 0xab, 0x40, 0x0a, 0x01, 0x87, 0x94, 0x78, 0xa4, 0x46, 0x76, 0x86, - 0x29, 0x41, 0xba, 0x32, 0x74, 0x2c, 0xc2, 0x4b, 0x66, 0xb3, 0x40, 0xfa, - 0x2f, 0xed, 0x58, 0xde, 0x66, 0x2d, 0x8c, 0x84, 0x5d, 0xe3, 0x7d, 0x29, - 0xfc, 0xb5, 0x97, 0x82, 0xcd, 0x93, 0x74, 0x0a, 0xbc, 0x23, 0x55, 0x9a, - 0x28, 0x7d, 0xff, 0xe4, 0x29, 0xc0, 0x8e, 0x4c, 0x2a, 0xdf, 0x93, 0x70, - 0x83, 0xf7, 0x89, 0xcf, 0x10, 0xa4, 0x35, 0xf0, 0x5a, 0x98, 0xbc, 0x59, - 0xd3, 0x96, 0x70, 0x26, 0x6f, 0xba, 0xe4, 0x21, 0x41, 0x55, 0xc7, 0x6f, - 0x8a, 0xbf, 0x54, 0x8a, 0x88, 0x6a, 0x0c, 0x56, 0x53, 0x6c, 0x5b, 0xc4, - 0x60, 0xaa, 0x04, 0x8e, 0xc6, 0x9b, 0x23, 0x33, 0x38, 0x26, 0xa1, 0x81, - 0x0a, 0x99, 0x49, 0xdd, 0x82, 0x21, 0xa6, 0x54, 0x2a, 0xe2, 0x15, 0x63, - 0xf8, 0x56, 0xa9, 0x9f, 0x30, 0x34, 0xe6, 0x66, 0xde, 0x98, 0xaf, 0x7c, - 0xcc, 0xd4, 0x5f, 0x55, 0x31, 0xeb, 0x2a, 0x26, 0xd9, 0x30, 0xa8, 0x2a, - 0xd6, 0x98, 0xa4, 0xc9, 0x2a, 0x31, 0xb7, 0xc9, 0x33, 0x38, 0x15, 0x96, - 0xe3, 0xc7, 0x0b, 0x66, 0x52, 0xf9, 0x80, 0x85, 0x85, 0x7a, 0xc0, 0x94, - 0xb4, 0x39, 0x7a, 0xb7, 0xf2, 0xa3, 0xad, 0x9c, 0x5f, 0x36, 0xea, 0x0e, - 0x52, 0x8d, 0xec, 0xa0, 0xa9, 0x46, 0xe0, 0x52, 0x59, 0xf5, 0x9f, 0x02, - 0xbf, 0x55, 0x2e, 0x0b, 0x20, 0xad, 0x55, 0x41, 0x16, 0x1d, 0x50, 0x16, - 0xc0, 0x7a, 0x7f, 0x0b, 0xa9, 0x18, 0xec, 0x1b, 0x7f, 0xad, 0x35, 0xf5, - 0x66, 0x72, 0x6e, 0x66, 0xd9, 0xd1, 0x1e, 0x01, 0x74, 0x4d, 0x84, 0x4d, - 0x7f, 0x4e, 0x07, 0x5a, 0x76, 0x93, 0x24, 0xd3, 0x19, 0x94, 0xcc, 0x2b, - 0x78, 0x28, 0x35, 0x53, 0x2d, 0x23, 0xda, 0xca, 0x56, 0x10, 0x0c, 0x42, - 0x06, 0x4c, 0x81, 0x54, 0xb3, 0x4b, 0xce, 0x09, 0x38, 0xad, 0xaa, 0x9d, - 0x13, 0x65, 0x9e, 0x6c, 0x46, 0x06, 0x68, 0x5e, 0x98, 0x38, 0x01, 0x1e, - 0xfb, 0x72, 0xfa, 0xb5, 0x0a, 0x2c, 0x22, 0x07, 0xb7, 0x10, 0x87, 0xaa, - 0x42, 0x0d, 0x50, 0xf7, 0x3e, 0x31, 0x03, 0xb7, 0xa3, 0xb4, 0x23, 0x23, - 0x84, 0x3b, 0x4a, 0x3a, 0x2f, 0x20, 0xd2, 0x41, 0xaf, 0xa8, 0x4a, 0x14, - 0xd7, 0xce, 0x76, 0xf6, 0x3c, 0xb0, 0x98, 0xfe, 0x36, 0x8d, 0xe4, 0x9f, - 0xf2, 0xc9, 0x80, 0xb2, 0xdd, 0xd1, 0xd7, 0x62, 0x77, 0xa9, 0x62, 0x15, - 0x9d, 0xf9, 0x9d, 0x65, 0xb3, 0x98, 0x67, 0xf7, 0xb1, 0x17, 0xc9, 0x7d, - 0x2c, 0x62, 0x71, 0x07, 0x34, 0x1f, 0x3e, 0xa0, 0xc4, 0x38, 0xc6, 0xec, - 0xc4, 0x98, 0x1c, 0xb8, 0xd2, 0xe8, 0x60, 0x13, 0x6c, 0xb7, 0xc1, 0xb3, - 0xf0, 0x72, 0xa2, 0xa1, 0xf6, 0x18, 0x25, 0x7d, 0x24, 0x30, 0x79, 0x49, - 0x1f, 0xf4, 0x25, 0xe9, 0x6c, 0xef, 0xae, 0x00, 0xfe, 0x5c, 0x0c, 0xd0, - 0xa9, 0xb4, 0x4c, 0x0e, 0xb9, 0xa2, 0x03, 0x40, 0x1a, 0xa4, 0xdf, 0x34, - 0x2b, 0x28, 0x15, 0x14, 0x03, 0xb4, 0xf9, 0xa1, 0x82, 0xef, 0x61, 0xa8, - 0x83, 0x9f, 0xb1, 0x87, 0x2a, 0x89, 0x17, 0xbb, 0xa3, 0x66, 0x8a, 0xcf, - 0xab, 0xec, 0x04, 0x6e, 0x74, 0xdd, 0xa2, 0xf4, 0xfa, 0xab, 0xc0, 0x8f, - 0xdc, 0xd5, 0x81, 0xae, 0x41, 0x91, 0x7f, 0xc4, 0x3b, 0x40, 0x4e, 0x94, - 0x6a, 0xf0, 0x89, 0xfd, 0x29, 0x57, 0xa9, 0xdc, 0xac, 0xa0, 0x30, 0xd9, - 0x06, 0x70, 0x1f, 0x2c, 0x53, 0x1e, 0x07, 0xc5, 0x20, 0x0a, 0x82, 0xf2, - 0x2a, 0x29, 0xd9, 0x56, 0x4b, 0x38, 0x4d, 0x7d, 0xbc, 0xc9, 0x0d, 0xb6, - 0xd8, 0xbf, 0x5c, 0x06, 0x22, 0xdc, 0x30, 0xb3, 0xec, 0x21, 0x7b, 0xc1, - 0x0b, 0x75, 0x9b, 0x52, 0xd0, 0x2f, 0xa6, 0x28, 0xe0, 0xe9, 0x0c, 0xde, - 0x65, 0xf5, 0xc8, 0x24, 0x93, 0x5e, 0x8a, 0xf7, 0x17, 0xfa, 0xef, 0x55, - 0x5c, 0x84, 0x81, 0x1f, 0xab, 0x19, 0xe8, 0x53, 0xb1, 0xe9, 0x3c, 0x26, - 0x0e, 0x5e, 0xc8, 0xe3, 0x7d, 0x71, 0x05, 0xdb, 0x99, 0xeb, 0x12, 0xaa, - 0xff, 0xc0, 0x04, 0x29, 0x45, 0xf3, 0x61, 0xe0, 0x6e, 0x4e, 0x52, 0x24, - 0x58, 0x60, 0x66, 0x1b, 0x32, 0x4b, 0xff, 0x5c, 0xce, 0x8e, 0x43, 0x4b, - 0x54, 0x62, 0xa7, 0x86, 0x9e, 0xcb, 0x36, 0xd6, 0x42, 0x39, 0xba, 0x96, - 0xab, 0x02, 0xa1, 0xd0, 0xa0, 0xee, 0x9f, 0x31, 0x99, 0xba, 0x1b, 0xb6, - 0x6e, 0x8d, 0xbc, 0x41, 0x89, 0x8f, 0xeb, 0x64, 0xbe, 0x9e, 0x55, 0xca, - 0xaa, 0x6d, 0xf8, 0xee, 0x52, 0x7e, 0x76, 0x1d, 0x15, 0x57, 0xb0, 0xad, - 0x9f, 0x40, 0x9a, 0xc4, 0xa7, 0x9d, 0xad, 0xb1, 0x24, 0x36, 0x12, 0x92, - 0x93, 0x90, 0xa5, 0xcc, 0xe6, 0x21, 0xd5, 0x9f, 0x6b, 0x79, 0x46, 0xe1, - 0x4a, 0xc9, 0x93, 0x6b, 0xac, 0x1a, 0x4f, 0x18, 0x84, 0x97, 0xfb, 0x2b, - 0xa1, 0xc8, 0x18, 0x3c, 0x17, 0x6f, 0xf7, 0x8f, 0x8e, 0xc1, 0x94, 0x3b, - 0xc6, 0xa3, 0x13, 0x39, 0x96, 0x4d, 0xb8, 0x79, 0x14, 0x47, 0x0d, 0xe6, - 0x70, 0x7e, 0xb6, 0x65, 0xd6, 0xd5, 0x2e, 0x58, 0x17, 0x09, 0xb2, 0xe3, - 0xe4, 0x2e, 0x07, 0xcc, 0x5b, 0xd3, 0x81, 0x9c, 0x5c, 0x58, 0xed, 0x23, - 0x1f, 0x24, 0xf7, 0xc8, 0x6e, 0xa9, 0x6a, 0x6f, 0xe0, 0x64, 0x2f, 0x43, - 0xd7, 0xf5, 0x95, 0x0c, 0x0c, 0x8a, 0x46, 0xa6, 0x04, 0x24, 0x4d, 0xd1, - 0xbc, 0xe2, 0xe2, 0xcc, 0xae, 0x24, 0x13, 0x73, 0xe4, 0xfb, 0x07, 0xb8, - 0xbb, 0x4d, 0xdd, 0xc8, 0x0d, 0x9f, 0x84, 0x37, 0xb3, 0x15, 0xc7, 0x4d, - 0xb3, 0xc8, 0xf3, 0x24, 0x8b, 0x8c, 0x08, 0xd4, 0xd1, 0x8a, 0xf5, 0xbb, - 0xc2, 0x0e, 0x2e, 0xf0, 0x49, 0x65, 0x24, 0xdb, 0xbe, 0x77, 0x74, 0x04, - 0x25, 0x2b, 0xc2, 0xb0, 0x13, 0xfb, 0x88, 0x4e, 0xf4, 0x16, 0x20, 0xf7, - 0x61, 0x1d, 0xd1, 0x87, 0x3e, 0xd7, 0x25, 0xf7, 0x51, 0x3f, 0xa2, 0x8f, - 0x6a, 0xa6, 0x70, 0xde, 0xe6, 0xa6, 0x50, 0x40, 0x86, 0x05, 0x2f, 0x20, - 0x09, 0xd8, 0x46, 0x63, 0x80, 0x26, 0x61, 0xf0, 0x14, 0xfc, 0x4e, 0x4a, - 0x37, 0xe5, 0xc3, 0xa9, 0xb0, 0xef, 0x9b, 0x7c, 0x2c, 0x2c, 0xe1, 0xf6, - 0x0f, 0x7a, 0xf2, 0xaa, 0x11, 0xdc, 0xe3, 0x7f, 0x28, 0x6a, 0x1b, 0x6c, - 0xfd, 0xf5, 0x0d, 0x73, 0x06, 0x4a, 0x68, 0x58, 0x7d, 0x20, 0x93, 0x6e, - 0x83, 0x4a, 0x16, 0xfa, 0x50, 0xe6, 0x1d, 0x30, 0xd7, 0x28, 0x6a, 0xc9, - 0x34, 0xff, 0x19, 0xff, 0x40, 0x2b, 0x7f, 0x11, 0x47, 0x57, 0x57, 0x61, - 0x78, 0x69, 0x47, 0x9a, 0x05, 0x12, 0x09, 0x34, 0x0c, 0x0c, 0x40, 0x72, - 0x6e, 0x10, 0x4d, 0xbc, 0x29, 0xc6, 0xee, 0x1f, 0x95, 0x30, 0x76, 0xd5, - 0x99, 0x47, 0x82, 0x1f, 0x9a, 0xb2, 0x74, 0x44, 0x35, 0xa8, 0xbe, 0xb5, - 0x52, 0x72, 0xe7, 0xf4, 0x8e, 0x71, 0x7b, 0x6c, 0xc1, 0xd3, 0x79, 0xb6, - 0x7b, 0xde, 0xbb, 0x61, 0x40, 0x9f, 0x0c, 0x14, 0x60, 0x6f, 0xa1, 0x82, - 0x9e, 0xf3, 0x0e, 0x3f, 0xf6, 0xe7, 0xc8, 0xa1, 0x33, 0x55, 0x8e, 0x86, - 0xd6, 0xb1, 0x3f, 0x25, 0xc0, 0x0a, 0xe8, 0xae, 0xfe, 0x9f, 0xf4, 0xe6, - 0x3d, 0x7f, 0x07, 0xaf, 0xdf, 0xc4, 0xba, 0x0c, 0x2a, 0x89, 0x70, 0x2b, - 0x74, 0x81, 0xcf, 0xf1, 0x8f, 0xde, 0xc3, 0x23, 0xb6, 0x56, 0x96, 0x0f, - 0x21, 0xa0, 0x16, 0x39, 0x28, 0x87, 0x2a, 0xf6, 0xaa, 0xe9, 0x6a, 0x1b, - 0x3c, 0x9b, 0xf5, 0xa4, 0xb7, 0xe9, 0x04, 0x70, 0x22, 0x79, 0x20, 0x8c, - 0xa5, 0xf3, 0xad, 0xdb, 0x22, 0xbd, 0x96, 0x4a, 0x52, 0xa5, 0x1c, 0x51, - 0x18, 0x2a, 0x67, 0x78, 0x13, 0x1c, 0x61, 0x01, 0xeb, 0x52, 0x58, 0xea, - 0x0c, 0x2a, 0x58, 0xe5, 0x08, 0xde, 0x08, 0x48, 0x18, 0xc6, 0xf0, 0xcd, - 0xb0, 0xe0, 0xdf, 0x31, 0x7c, 0x25, 0x0c, 0x5f, 0x10, 0xc6, 0xfa, 0x1d, - 0xc3, 0xf7, 0x4f, 0xc1, 0xf0, 0x05, 0x71, 0xbd, 0x4d, 0x30, 0x7c, 0xc1, - 0x1b, 0x98, 0xc8, 0x6e, 0xfe, 0xdc, 0x81, 0x9d, 0x8b, 0x01, 0x86, 0x2f, - 0xb4, 0xfe, 0x04, 0x8e, 0x46, 0xe0, 0xaf, 0x3b, 0xcf, 0x3f, 0x2d, 0xc5, - 0xf1, 0x05, 0x41, 0xc5, 0xff, 0x2e, 0x38, 0xbe, 0xa4, 0xfa, 0xea, 0x08, - 0x1c, 0x5f, 0xbb, 0xf5, 0x3d, 0x81, 0x7c, 0xb5, 0xdc, 0xdf, 0x1e, 0xc9, - 0x97, 0x44, 0xb1, 0xff, 0x0f, 0x90, 0x7c, 0xd3, 0x77, 0x7d, 0x59, 0xb2, - 0x5a, 0x03, 0xea, 0x8b, 0x4e, 0x26, 0xb8, 0x03, 0xeb, 0xe3, 0xb7, 0xc3, - 0x4d, 0xb6, 0xdf, 0x0c, 0xe3, 0xb4, 0x6d, 0x80, 0xa8, 0x95, 0x2e, 0xaf, - 0xde, 0x64, 0x42, 0x37, 0x34, 0x1c, 0xec, 0x85, 0x62, 0x55, 0x1c, 0x14, - 0x18, 0x55, 0xae, 0xf4, 0xdb, 0x25, 0x9d, 0x34, 0xec, 0xe5, 0x7e, 0x5f, - 0xb1, 0xea, 0x2f, 0x6d, 0xdb, 0x6e, 0x8a, 0x6d, 0xcd, 0x2a, 0x00, 0xd3, - 0xb6, 0x96, 0xdd, 0x11, 0x1b, 0x9b, 0x54, 0x75, 0xf0, 0x9b, 0x1f, 0x29, - 0x63, 0x01, 0xe4, 0x23, 0x5a, 0xfa, 0x4d, 0x44, 0x89, 0x23, 0x6b, 0x09, - 0x41, 0xe0, 0xf1, 0x38, 0xb2, 0x16, 0xb4, 0x62, 0xaa, 0x02, 0xc9, 0xd2, - 0x7b, 0xf8, 0x6a, 0x48, 0x82, 0x45, 0xd6, 0xf4, 0x75, 0x95, 0xc3, 0xf1, - 0x5f, 0x39, 0xec, 0xb0, 0x2e, 0xea, 0x05, 0xb5, 0xa9, 0x66, 0x47, 0xcc, - 0x41, 0x6b, 0x48, 0x25, 0xcd, 0x2d, 0x0a, 0xb3, 0xa4, 0x31, 0xa6, 0x92, - 0xf6, 0xd8, 0xb1, 0x2e, 0x4b, 0x2f, 0xbb, 0x35, 0x82, 0x49, 0xf0, 0x94, - 0x4b, 0x05, 0x64, 0x57, 0x17, 0x50, 0x91, 0xed, 0x51, 0x82, 0x02, 0xd8, - 0x1c, 0x25, 0x30, 0x80, 0x4f, 0x55, 0xc1, 0x39, 0x22, 0xfa, 0x34, 0x6e, - 0x4f, 0xbb, 0x88, 0xa8, 0xf1, 0xd2, 0xd2, 0x0d, 0x47, 0x81, 0x3e, 0x2d, - 0x79, 0x3e, 0xb4, 0x76, 0x37, 0x0e, 0xf6, 0x99, 0x62, 0xad, 0x85, 0xd8, - 0x09, 0x79, 0x3e, 0xeb, 0x95, 0x21, 0x26, 0x52, 0x0d, 0x70, 0x2e, 0xf5, - 0x37, 0xdf, 0x38, 0xec, 0x8f, 0x25, 0xbb, 0x66, 0x1e, 0x55, 0x59, 0x0b, - 0xfb, 0xa9, 0x78, 0x31, 0x6b, 0xc6, 0x56, 0x77, 0xd6, 0x53, 0x3b, 0x96, - 0xaa, 0x62, 0xb4, 0x0c, 0xc4, 0x68, 0x49, 0x62, 0x2c, 0x83, 0x7e, 0x46, - 0x27, 0xfd, 0x60, 0xb7, 0xc3, 0xff, 0x96, 0x7e, 0x6b, 0xf2, 0x20, 0x51, - 0xce, 0x49, 0xd3, 0x97, 0x1e, 0xc0, 0xe3, 0x4c, 0x03, 0x3f, 0x9f, 0x3d, - 0xcf, 0x92, 0x5e, 0x8b, 0x08, 0x8f, 0x55, 0x0c, 0xb0, 0x9f, 0xe5, 0x07, - 0x5a, 0x2a, 0x46, 0x85, 0x72, 0x7d, 0x45, 0x76, 0xb5, 0x76, 0xaf, 0x46, - 0xa2, 0x6e, 0x1a, 0x7c, 0x96, 0x3a, 0x65, 0x42, 0x93, 0xa3, 0x24, 0xda, - 0xcb, 0x63, 0x52, 0x03, 0x6c, 0x0d, 0x90, 0xf1, 0xf9, 0xd8, 0x52, 0x68, - 0xeb, 0xd1, 0xfc, 0x74, 0x34, 0xd4, 0x3a, 0xaa, 0x62, 0xbb, 0x04, 0x12, - 0x5b, 0x59, 0x4a, 0x05, 0xe4, 0xc0, 0x8d, 0xa0, 0xb0, 0x9b, 0x05, 0x09, - 0x7f, 0x63, 0x58, 0xd7, 0x7c, 0xb3, 0xb0, 0xae, 0xf9, 0x7d, 0xc2, 0xba, - 0xe6, 0xbf, 0x43, 0x58, 0x77, 0x45, 0x5f, 0xe1, 0xe8, 0x01, 0x9c, 0x6d, - 0x7d, 0x34, 0xc6, 0x58, 0x69, 0x61, 0x9c, 0xf5, 0xc9, 0x10, 0x55, 0xa8, - 0x89, 0xae, 0x55, 0xe5, 0x43, 0x85, 0xc1, 0xe9, 0x7c, 0xb1, 0x2a, 0x4d, - 0x58, 0x6d, 0x4b, 0xab, 0xe2, 0x8b, 0x65, 0x9f, 0xca, 0x20, 0xc1, 0xcb, - 0x7c, 0x71, 0xc5, 0xcd, 0x0c, 0x48, 0x54, 0x42, 0x6f, 0x92, 0x8a, 0x85, - 0x15, 0x50, 0x22, 0xda, 0xdb, 0xa3, 0xaf, 0x40, 0x6a, 0xbf, 0x70, 0x81, - 0x05, 0x2c, 0x33, 0x08, 0xc3, 0xbe, 0xa1, 0xb2, 0xa2, 0x0c, 0x6d, 0x4a, - 0x6e, 0x06, 0x5b, 0xbc, 0x19, 0xb4, 0x3d, 0xc9, 0x94, 0x3a, 0x0c, 0x3f, - 0x42, 0xb7, 0x86, 0x6e, 0x7b, 0xb5, 0x2d, 0xa5, 0x46, 0x27, 0x16, 0x7f, - 0x84, 0x46, 0xd2, 0xac, 0xee, 0x47, 0xed, 0x4b, 0x29, 0xa1, 0xb1, 0x2d, - 0xbc, 0x60, 0xcb, 0xb5, 0x56, 0xbd, 0x9b, 0x22, 0x0d, 0x4e, 0x6e, 0x02, - 0xf4, 0x65, 0x3c, 0xe5, 0xc4, 0xcd, 0x32, 0x62, 0x89, 0xb2, 0x65, 0xb0, - 0xb0, 0xbb, 0x02, 0xc6, 0x7d, 0x41, 0x93, 0x7a, 0xd7, 0xdb, 0xbb, 0x9c, - 0x96, 0x31, 0x30, 0xf0, 0xb8, 0x63, 0xf1, 0x99, 0xdf, 0x46, 0x32, 0x08, - 0x65, 0xc2, 0x31, 0x33, 0x88, 0xa4, 0x31, 0x73, 0x29, 0x65, 0x66, 0x11, - 0x85, 0x0f, 0xcb, 0xce, 0xc2, 0x21, 0xb5, 0x1e, 0x1d, 0xad, 0x71, 0x10, - 0x62, 0x3d, 0x6e, 0xff, 0xc3, 0xd2, 0xaa, 0x2f, 0x1c, 0xfb, 0xe0, 0x69, - 0x8d, 0x20, 0x25, 0xd5, 0xea, 0xdb, 0x59, 0x3e, 0x84, 0x56, 0x8b, 0x44, - 0x3b, 0x1a, 0x5d, 0xd3, 0x89, 0xd4, 0xc8, 0x45, 0xbf, 0xbb, 0x46, 0x85, - 0x56, 0xaa, 0xcf, 0x54, 0x13, 0xc2, 0x66, 0xb3, 0xc9, 0x3f, 0x92, 0xd3, - 0x56, 0x10, 0xb2, 0x4f, 0x10, 0x14, 0xc1, 0xf9, 0xf2, 0xf3, 0xb2, 0xac, - 0xcd, 0xe2, 0x81, 0xfc, 0x03, 0xcf, 0x6f, 0xa3, 0x7d, 0xe0, 0x47, 0x3e, - 0x89, 0xd0, 0xb0, 0x31, 0x9d, 0xee, 0x9d, 0x5f, 0xf8, 0xc0, 0xc8, 0x32, - 0x42, 0xe5, 0x43, 0xbf, 0x30, 0x25, 0x2c, 0xbe, 0xf3, 0x03, 0x3b, 0xf7, - 0x78, 0xe7, 0x96, 0x5a, 0x5b, 0x8c, 0x8e, 0x53, 0xaa, 0xd4, 0x15, 0xa6, - 0x84, 0x79, 0x6c, 0x48, 0x45, 0xef, 0x82, 0xa9, 0x58, 0x2a, 0x1d, 0x91, - 0xde, 0x0f, 0x94, 0x6b, 0x4a, 0xa9, 0x52, 0x52, 0x98, 0x12, 0x16, 0xb1, - 0xe1, 0x80, 0xde, 0xad, 0xb6, 0x20, 0x78, 0x4b, 0xad, 0x22, 0x46, 0xc7, - 0x29, 0x95, 0x3a, 0x4a, 0x09, 0x8b, 0xa0, 0x70, 0x60, 0xef, 0x82, 0xe4, - 0x6d, 0xb5, 0x8e, 0x18, 0x1d, 0xa7, 0x54, 0xea, 0x28, 0x25, 0xcc, 0x28, - 0x95, 0x3a, 0xa2, 0xbd, 0x8b, 0x8b, 0x54, 0xad, 0x23, 0x46, 0xc7, 0x79, - 0x2a, 0x75, 0x94, 0x12, 0x66, 0x94, 0x4a, 0x1d, 0x91, 0xaf, 0x80, 0x48, - 0x94, 0x25, 0x3a, 0xea, 0xc8, 0x33, 0x52, 0xeb, 0x28, 0x21, 0xcc, 0x28, - 0x95, 0x3a, 0x4a, 0x09, 0x33, 0xbf, 0x53, 0xa6, 0xa3, 0x8e, 0x38, 0xf7, - 0x86, 0x5a, 0x47, 0x1d, 0x59, 0xf2, 0x0d, 0xa5, 0x8e, 0x52, 0xc2, 0x8c, - 0xb2, 0x4c, 0x47, 0x9d, 0x83, 0x60, 0x21, 0x0d, 0xb5, 0x8e, 0x3a, 0xb2, - 0xe4, 0x1b, 0x4a, 0x1d, 0xa5, 0x84, 0x19, 0xa5, 0x4a, 0x47, 0xc4, 0xdb, - 0xbf, 0x74, 0xc4, 0xb9, 0x97, 0xe8, 0xe8, 0x45, 0xd2, 0x66, 0x83, 0x5f, - 0x0c, 0xa9, 0x77, 0xd8, 0xec, 0xab, 0x37, 0x3b, 0xb0, 0xbc, 0xc3, 0x32, - 0x08, 0x4a, 0xaf, 0x7c, 0x1c, 0xd3, 0xf8, 0xce, 0x56, 0xfa, 0x4e, 0xb2, - 0x50, 0x06, 0x57, 0x87, 0x77, 0x47, 0xb9, 0x19, 0x38, 0xa5, 0x8e, 0xa7, - 0xdd, 0x0d, 0x3b, 0xa2, 0xdb, 0x52, 0xd1, 0x68, 0xf7, 0x40, 0xba, 0x60, - 0x35, 0xbb, 0x9a, 0xb4, 0x4e, 0x55, 0x8a, 0xa5, 0x7e, 0x47, 0xb3, 0x7f, - 0x51, 0xbf, 0xac, 0xd9, 0x8d, 0x24, 0x77, 0xac, 0x5a, 0x41, 0x74, 0x7b, - 0x29, 0x6c, 0x42, 0x65, 0xe7, 0xa4, 0x54, 0xe4, 0xf8, 0x00, 0x59, 0xd4, - 0x75, 0x47, 0xa3, 0xa7, 0x1e, 0x3e, 0x95, 0x29, 0xc6, 0xa1, 0x55, 0x93, - 0xc1, 0xb7, 0xef, 0xc0, 0x0f, 0xde, 0xa9, 0x53, 0x88, 0xf2, 0x51, 0x44, - 0xfe, 0xb8, 0x4c, 0x95, 0xd2, 0xc5, 0xaa, 0x47, 0xaa, 0x0c, 0xfd, 0xf3, - 0x8d, 0x8e, 0x54, 0xf7, 0xa7, 0x69, 0x56, 0xe8, 0xc7, 0x1c, 0xa7, 0xbe, - 0x01, 0xc6, 0xc2, 0x2e, 0x7c, 0xf2, 0xbc, 0xfa, 0xd9, 0xc9, 0x7e, 0x3f, - 0x3b, 0xfd, 0xa0, 0xb3, 0xd3, 0x8f, 0x39, 0xba, 0xac, 0x49, 0x0d, 0xcb, - 0x22, 0x2b, 0xf2, 0x15, 0x5d, 0x92, 0x4a, 0x43, 0xb9, 0x26, 0xb6, 0xde, - 0x35, 0xe4, 0x5a, 0x58, 0x6d, 0xad, 0x76, 0x68, 0x0b, 0xbb, 0xb9, 0x88, - 0xd8, 0xda, 0xea, 0x14, 0x15, 0xf2, 0x77, 0xdd, 0x13, 0x99, 0x2c, 0xcc, - 0xe5, 0x6c, 0x2c, 0x5e, 0x48, 0xaa, 0x86, 0x7b, 0x09, 0x3a, 0xf1, 0x1e, - 0xfc, 0x20, 0xa4, 0x40, 0x81, 0xe5, 0xbb, 0x4a, 0xca, 0x97, 0x7d, 0xf4, - 0x84, 0xa4, 0x6c, 0x23, 0xb4, 0x74, 0xe3, 0x67, 0xf2, 0xc8, 0x20, 0xef, - 0x09, 0x51, 0xe2, 0x55, 0x49, 0x82, 0x7a, 0xe6, 0xee, 0x9d, 0x90, 0x7e, - 0x57, 0x23, 0x21, 0x61, 0x7f, 0xfb, 0x19, 0x2e, 0xd0, 0xe2, 0x9c, 0xae, - 0x06, 0xba, 0x3d, 0xa1, 0x90, 0x2c, 0xfb, 0xc6, 0xfd, 0xe1, 0xad, 0xaf, - 0x3f, 0xee, 0xb3, 0x29, 0xf7, 0x29, 0x68, 0xd6, 0x1d, 0x51, 0x51, 0x54, - 0xb6, 0x4b, 0x30, 0xec, 0x42, 0xa3, 0x12, 0x2e, 0x40, 0x74, 0x62, 0x37, - 0xc0, 0x46, 0xc3, 0x1d, 0x46, 0x56, 0x6b, 0x01, 0x24, 0xe3, 0xd9, 0x88, - 0x4f, 0xd3, 0xef, 0x49, 0x02, 0x2c, 0xab, 0x3c, 0xf3, 0xaa, 0xaa, 0x82, - 0xc6, 0x5b, 0xdf, 0x40, 0xd1, 0xe1, 0x53, 0x80, 0xcb, 0x08, 0x25, 0x05, - 0x21, 0xb2, 0xf8, 0x89, 0x39, 0x0f, 0x5f, 0xf6, 0xf4, 0x45, 0x6f, 0xfc, - 0xe8, 0x45, 0xe4, 0xd1, 0xa8, 0x83, 0x5a, 0xec, 0x51, 0x2e, 0x9d, 0xca, - 0xff, 0x28, 0x3e, 0xe7, 0xc3, 0x59, 0x23, 0xdf, 0x7d, 0x89, 0x91, 0xdd, - 0x94, 0xbe, 0x79, 0x24, 0x14, 0xc9, 0x1a, 0xa0, 0x10, 0x88, 0xdc, 0xb6, - 0xc1, 0x33, 0x6a, 0xd8, 0x12, 0xb3, 0x6a, 0x68, 0x04, 0x72, 0x80, 0xe5, - 0xff, 0xb0, 0x00, 0xab, 0xf9, 0xbd, 0xb5, 0x67, 0x7f, 0x17, 0xed, 0xed, - 0xbc, 0x75, 0x8d, 0x94, 0x21, 0xbf, 0x9d, 0x06, 0x09, 0xc7, 0xbf, 0xad, - 0x16, 0x5b, 0xdf, 0x5b, 0x8b, 0x8d, 0x32, 0x17, 0xb8, 0x17, 0x00, 0x30, - 0x85, 0xfb, 0xd5, 0x86, 0x76, 0x9a, 0x24, 0xd4, 0xda, 0x4b, 0x41, 0xb2, - 0x2e, 0x28, 0x56, 0x28, 0x95, 0xd8, 0x14, 0x0b, 0xbd, 0x52, 0x3e, 0xac, - 0x16, 0xfe, 0x2b, 0xda, 0xa4, 0x85, 0x92, 0xa0, 0x49, 0xb1, 0x28, 0x97, - 0x7e, 0x76, 0x93, 0x7d, 0xd5, 0x0a, 0xe1, 0x46, 0xd2, 0xfd, 0x16, 0x1e, - 0xd0, 0x44, 0x55, 0x53, 0x6b, 0x70, 0xc1, 0x25, 0x5a, 0x18, 0xb5, 0xd7, - 0xa4, 0xf0, 0xd9, 0xe4, 0x92, 0xeb, 0xaf, 0x63, 0x5e, 0x6d, 0x03, 0xf3, - 0x6a, 0x4a, 0xe6, 0xa5, 0x41, 0x87, 0x66, 0x90, 0xdb, 0x05, 0x80, 0x6b, - 0xa1, 0x08, 0xcb, 0xe0, 0x39, 0x1f, 0x65, 0x02, 0xe2, 0x5c, 0x5b, 0x25, - 0x25, 0x17, 0x9a, 0x69, 0x64, 0x58, 0x6f, 0xf4, 0x22, 0x79, 0x45, 0x40, - 0x55, 0xf9, 0x52, 0x11, 0xd1, 0xaf, 0xe5, 0x0f, 0x66, 0xab, 0x96, 0x06, - 0x6f, 0x91, 0x98, 0xda, 0x38, 0x5c, 0x43, 0xdf, 0x7a, 0xe6, 0xf5, 0x80, - 0xe5, 0x37, 0xdb, 0x74, 0x40, 0x43, 0xc5, 0x33, 0xad, 0x96, 0x41, 0x31, - 0x02, 0xfb, 0x2c, 0x1f, 0xfb, 0x64, 0x32, 0x37, 0xf1, 0xb9, 0x88, 0xa5, - 0x5d, 0xad, 0xa0, 0x4e, 0x64, 0x98, 0x55, 0xcd, 0xaa, 0xf8, 0x19, 0x95, - 0xd6, 0x81, 0x23, 0x9c, 0x95, 0x40, 0x7e, 0x1b, 0xac, 0x43, 0x70, 0x94, - 0x65, 0x3c, 0x8b, 0x65, 0xed, 0x65, 0xca, 0xcd, 0x49, 0x52, 0xfd, 0x79, - 0x3d, 0x83, 0x57, 0xf6, 0x19, 0x53, 0x59, 0x9a, 0x6a, 0x9e, 0x55, 0x4d, - 0xbc, 0x51, 0x66, 0xe2, 0x19, 0xb2, 0x3f, 0x3e, 0x04, 0xc4, 0xb4, 0xa0, - 0xb1, 0xc4, 0xba, 0xf3, 0x28, 0x32, 0xdc, 0x99, 0x19, 0xe1, 0x07, 0xcb, - 0x7d, 0xa9, 0x92, 0x4a, 0xda, 0xe9, 0x11, 0xe7, 0x8f, 0xbb, 0x49, 0x1f, - 0x9f, 0x30, 0x47, 0x9f, 0x9f, 0x74, 0x4b, 0xe5, 0x9e, 0xb2, 0x8f, 0x1a, - 0x24, 0x3a, 0xce, 0x37, 0x6c, 0x7f, 0x28, 0x8c, 0xf6, 0x2a, 0x29, 0xc9, - 0x63, 0x1f, 0x01, 0x99, 0x29, 0x5e, 0xfd, 0xdc, 0x46, 0xae, 0xfc, 0x1d, - 0x8f, 0xec, 0xbb, 0x08, 0x26, 0x6f, 0xe0, 0x00, 0xc3, 0x20, 0xa5, 0x7b, - 0xc1, 0x06, 0x4f, 0x93, 0xc0, 0xb4, 0xb0, 0xe4, 0x09, 0x36, 0x0e, 0x35, - 0x77, 0x95, 0x13, 0x04, 0x4f, 0xa5, 0x7f, 0xe3, 0x32, 0xd1, 0x92, 0x6f, - 0x40, 0xe7, 0x90, 0x90, 0x4a, 0x3e, 0xb0, 0xc9, 0x5f, 0x70, 0x99, 0x7e, - 0xad, 0x59, 0xef, 0xb1, 0x93, 0x3a, 0xb4, 0x95, 0xf2, 0x6b, 0xcd, 0xfa, - 0x67, 0x8a, 0x09, 0x4c, 0xce, 0xd5, 0x00, 0x91, 0x2f, 0x52, 0x93, 0x4f, - 0x96, 0xf2, 0x77, 0x25, 0x6c, 0x94, 0xc0, 0x66, 0xa2, 0x7f, 0x50, 0x99, - 0x01, 0xa8, 0x55, 0x63, 0xac, 0xaf, 0x01, 0x28, 0x8e, 0x37, 0x91, 0xa1, - 0x8a, 0xa5, 0xbe, 0x44, 0x0c, 0x1a, 0xab, 0x86, 0xa9, 0xbe, 0x44, 0x30, - 0xfb, 0x92, 0x33, 0x63, 0x81, 0xd6, 0x01, 0xf6, 0x04, 0xc9, 0x77, 0x10, - 0x80, 0xe5, 0xa9, 0x7f, 0x44, 0x3d, 0x27, 0xdf, 0x91, 0x09, 0x36, 0x1b, - 0xe4, 0xd2, 0xf2, 0xba, 0x3f, 0x10, 0xe6, 0x03, 0xbc, 0x99, 0xd5, 0x3f, - 0xe8, 0xee, 0xe7, 0xd5, 0x80, 0x1e, 0xf1, 0x01, 0x29, 0x4a, 0x33, 0x32, - 0x9e, 0x4f, 0x51, 0x92, 0x08, 0x4a, 0x3c, 0x4b, 0x1a, 0x92, 0x6f, 0x9e, - 0xe6, 0xc2, 0xe5, 0xe2, 0x6e, 0xa3, 0xd3, 0xd7, 0x37, 0xf7, 0x64, 0x82, - 0xff, 0x23, 0x4b, 0xfc, 0x10, 0x61, 0x89, 0x63, 0x7d, 0x6e, 0xd9, 0xbb, - 0x1a, 0xb4, 0x62, 0x0f, 0xa7, 0x3e, 0x93, 0xe5, 0x87, 0xbd, 0xb9, 0x47, - 0xdd, 0x40, 0x1c, 0xb0, 0xdf, 0x07, 0xde, 0x1a, 0x7d, 0xb6, 0x81, 0x05, - 0x54, 0x58, 0x84, 0xc5, 0x8e, 0x79, 0x69, 0x58, 0xf6, 0x32, 0x16, 0x77, - 0x91, 0xfb, 0x94, 0x37, 0x10, 0x54, 0x1c, 0xf3, 0x01, 0x5a, 0x41, 0x52, - 0x91, 0x9b, 0x4c, 0xd7, 0x83, 0x3e, 0x7b, 0x7c, 0xd4, 0x57, 0x9b, 0x99, - 0x46, 0xf4, 0xcc, 0x2b, 0x7f, 0x88, 0xd7, 0x78, 0xd8, 0x06, 0x5f, 0xe5, - 0x95, 0x39, 0x9b, 0x0e, 0xd9, 0xe0, 0x2b, 0xd0, 0x02, 0xc2, 0x6b, 0x72, - 0x30, 0x11, 0xc0, 0xe7, 0xe8, 0xf6, 0x50, 0xfe, 0xfd, 0xf5, 0xb2, 0x48, - 0xc4, 0xe4, 0x7b, 0xf2, 0x04, 0xe3, 0x2a, 0xb5, 0xf6, 0x73, 0x13, 0xa6, - 0x76, 0xed, 0xd9, 0x21, 0x9f, 0x98, 0x26, 0x4e, 0x0b, 0x0e, 0xd8, 0xcf, - 0xf5, 0x7e, 0xa5, 0xa9, 0x67, 0xa2, 0xf7, 0x29, 0x93, 0x30, 0xd8, 0x3b, - 0x0f, 0xc4, 0x92, 0x6e, 0x9c, 0x1b, 0x68, 0xf5, 0xea, 0x1d, 0x45, 0x5e, - 0x42, 0xd5, 0xbe, 0x85, 0x5e, 0x26, 0xa6, 0x4a, 0x5f, 0x76, 0xb7, 0xcd, - 0x3e, 0x77, 0x5d, 0xf9, 0xbb, 0xed, 0xc2, 0x67, 0xd4, 0xcb, 0xf8, 0xbe, - 0xe5, 0x97, 0xc8, 0xcb, 0xf9, 0x56, 0xfb, 0xce, 0x78, 0x09, 0x6e, 0x5c, - 0x69, 0x3c, 0xf4, 0x8d, 0x9f, 0x1e, 0x37, 0xba, 0x05, 0xbd, 0x73, 0x57, - 0x8a, 0xc7, 0x39, 0x06, 0x6f, 0x92, 0xc5, 0x0b, 0x1d, 0x9e, 0x05, 0x6a, - 0x18, 0xbc, 0x7b, 0xe2, 0x53, 0x7b, 0x24, 0x0f, 0x3a, 0x59, 0xfe, 0x5c, - 0x17, 0x86, 0xf2, 0x46, 0x32, 0xbd, 0xea, 0xe2, 0x4b, 0xa0, 0xf7, 0x44, - 0xf8, 0x52, 0xd5, 0x45, 0x24, 0xa7, 0x5f, 0xbe, 0xc6, 0xae, 0xf6, 0x2a, - 0x92, 0x93, 0x47, 0x8f, 0x41, 0x18, 0x6b, 0xeb, 0x21, 0x38, 0x3d, 0xcd, - 0xdf, 0x68, 0x2a, 0x23, 0x24, 0x6a, 0x7b, 0x61, 0xd5, 0xd9, 0xff, 0x81, - 0xef, 0xf0, 0x2a, 0xcb, 0x02, 0x66, 0xde, 0x03, 0x39, 0x7b, 0x90, 0xd0, - 0x39, 0x7e, 0x85, 0xf0, 0x5f, 0x1b, 0x7a, 0xe7, 0x74, 0x43, 0xee, 0x3b, - 0xc9, 0xbb, 0xa4, 0x52, 0x3e, 0x06, 0x38, 0x2a, 0x24, 0x36, 0x74, 0xc8, - 0xe6, 0x1e, 0x9f, 0xb2, 0xfc, 0x55, 0x81, 0x49, 0x21, 0x4a, 0x29, 0x8f, - 0x16, 0xc8, 0x96, 0x92, 0x85, 0x9c, 0x85, 0xb8, 0x0c, 0x48, 0xbc, 0x55, - 0x01, 0xc3, 0xcc, 0xb1, 0xbf, 0x83, 0x22, 0x5a, 0x81, 0xb5, 0xd1, 0x2d, - 0x68, 0x12, 0x28, 0x0f, 0xbc, 0x27, 0x2f, 0x02, 0xd1, 0x0d, 0x0c, 0xf6, - 0x6f, 0x96, 0x07, 0x2d, 0xdd, 0x49, 0x8d, 0x20, 0x32, 0xc9, 0x9e, 0xff, - 0x90, 0x7c, 0xed, 0x30, 0xb9, 0xe9, 0xa7, 0x88, 0x54, 0x91, 0x1b, 0x1f, - 0xf6, 0x90, 0x9f, 0xe1, 0x09, 0x49, 0xc1, 0x43, 0x68, 0x4a, 0xed, 0x0b, - 0x2c, 0xea, 0x45, 0x67, 0xc1, 0x6b, 0xd0, 0x21, 0x1e, 0x45, 0x26, 0x78, - 0xa5, 0x79, 0x7f, 0x00, 0x87, 0x2a, 0xfd, 0x49, 0x85, 0x3c, 0xc5, 0x3f, - 0xae, 0x74, 0x1a, 0x07, 0x47, 0x50, 0x52, 0x40, 0x7f, 0x90, 0x8b, 0x24, - 0x6d, 0x71, 0x14, 0x5f, 0x8e, 0xd8, 0xa4, 0x7e, 0xdd, 0x00, 0xfa, 0x64, - 0xab, 0xa1, 0x77, 0xad, 0x2c, 0x9c, 0xc3, 0x6a, 0x64, 0xe7, 0x65, 0x33, - 0x48, 0xf9, 0x5c, 0x23, 0x43, 0x58, 0xf9, 0x5c, 0xab, 0x23, 0xa0, 0xe5, - 0xc9, 0xde, 0x04, 0x5c, 0x24, 0x80, 0x59, 0xa5, 0x0a, 0xc6, 0x4c, 0xd7, - 0xed, 0xdb, 0xd8, 0xb2, 0x55, 0xcd, 0x0e, 0xf5, 0x47, 0x2d, 0x95, 0x1d, - 0xea, 0x7d, 0xa8, 0xc2, 0x0e, 0xf5, 0x4e, 0xdc, 0x3f, 0xec, 0xd2, 0x76, - 0x2d, 0xc0, 0x7e, 0xd5, 0x37, 0x11, 0xef, 0xf6, 0xfb, 0x23, 0xec, 0x77, - 0xee, 0xbe, 0xc4, 0x07, 0x7c, 0xba, 0x4e, 0xa2, 0x4a, 0x72, 0xa5, 0x87, - 0x7f, 0x4f, 0xee, 0x23, 0xea, 0xa8, 0x7f, 0x71, 0xb9, 0xb8, 0x1e, 0x0f, - 0x86, 0xbf, 0x5a, 0x60, 0x5e, 0xcc, 0x0d, 0x6b, 0xec, 0x80, 0x4e, 0x5e, - 0x18, 0x28, 0x11, 0xe2, 0x1a, 0x85, 0x54, 0x16, 0x10, 0xcb, 0xb9, 0x84, - 0x4d, 0x02, 0xbf, 0x44, 0x6e, 0xe7, 0x42, 0x54, 0x04, 0x49, 0x69, 0x02, - 0x56, 0xa7, 0x0c, 0x0e, 0xf3, 0x0c, 0xe3, 0x72, 0x86, 0x8d, 0xca, 0x0c, - 0xa3, 0x52, 0x86, 0x1c, 0x2c, 0x50, 0x7d, 0x63, 0x87, 0x3e, 0x87, 0xce, - 0x5e, 0x7a, 0x1f, 0x09, 0x81, 0xf8, 0xaa, 0x6d, 0x95, 0x36, 0x27, 0x95, - 0x51, 0x68, 0x3a, 0x9c, 0x0c, 0xbb, 0x73, 0xad, 0x9d, 0xf2, 0x06, 0xfd, - 0x51, 0xf7, 0x7a, 0xa2, 0xb5, 0x50, 0x4e, 0x7f, 0x7d, 0x35, 0x9d, 0x8e, - 0xa7, 0xda, 0x98, 0x97, 0x37, 0xe8, 0x8d, 0xa7, 0x83, 0xe1, 0x54, 0x1b, - 0xf4, 0xe6, 0x7b, 0x58, 0x8c, 0x6f, 0xfa, 0xc3, 0x62, 0xec, 0x5b, 0xb2, - 0x06, 0xe6, 0xa5, 0x52, 0x34, 0x58, 0xf1, 0xef, 0x52, 0x24, 0x91, 0x5d, - 0xa9, 0x14, 0x0d, 0xee, 0x08, 0xde, 0xa5, 0x48, 0x22, 0x78, 0xf7, 0x39, - 0xa9, 0x98, 0x4b, 0xab, 0x25, 0xe0, 0xb7, 0xca, 0xf2, 0x36, 0xad, 0xdd, - 0xed, 0xc9, 0xb1, 0x3c, 0x78, 0x2e, 0xb2, 0xd1, 0xef, 0xd9, 0xfd, 0xc0, - 0xdd, 0x6c, 0xbc, 0x95, 0x47, 0x92, 0x33, 0xdb, 0x20, 0xf8, 0xfd, 0xb0, - 0x57, 0x8c, 0xc8, 0xfc, 0x93, 0x94, 0xdd, 0x43, 0x1c, 0x8c, 0xc6, 0x83, - 0xff, 0x26, 0x49, 0x5a, 0xb4, 0xf4, 0xf0, 0xa1, 0x2a, 0xf0, 0xb7, 0x00, - 0x42, 0x84, 0x3e, 0x7d, 0xd5, 0x23, 0x8d, 0xa3, 0xc3, 0x7e, 0xbf, 0xf5, - 0xa0, 0x90, 0x44, 0x9f, 0xa8, 0xbf, 0x74, 0xc8, 0x83, 0x42, 0x54, 0xfa, - 0x45, 0x5b, 0x7d, 0x64, 0x7e, 0xe1, 0xc6, 0xab, 0xc7, 0x72, 0x26, 0x85, - 0x20, 0xbd, 0xc8, 0x65, 0xc4, 0xa4, 0x0b, 0xe7, 0x24, 0xe4, 0x4c, 0x34, - 0x68, 0x7c, 0xe9, 0x2e, 0x6c, 0x0f, 0xb4, 0x2b, 0x87, 0x93, 0xa6, 0xe8, - 0x1c, 0x9a, 0xa5, 0x93, 0x36, 0x68, 0x0c, 0xb4, 0x8b, 0x26, 0x25, 0xed, - 0x1f, 0x96, 0x04, 0xcf, 0x79, 0xaf, 0x5d, 0x34, 0x69, 0x03, 0x6b, 0xa0, - 0xcd, 0x58, 0x70, 0x52, 0x06, 0x89, 0xa3, 0x4d, 0x59, 0x64, 0x83, 0x79, - 0xf4, 0xb0, 0x9c, 0x69, 0xe9, 0x4d, 0x31, 0x71, 0x21, 0x5d, 0xf6, 0x1d, - 0x11, 0xe4, 0x58, 0x9a, 0x20, 0x27, 0x6d, 0x19, 0xd1, 0xa4, 0x58, 0x48, - 0x53, 0x61, 0x68, 0x49, 0xc0, 0x7c, 0xaa, 0x7e, 0xb3, 0xa1, 0x90, 0x93, - 0x88, 0xc9, 0xbd, 0xd0, 0x33, 0xe1, 0xd7, 0x20, 0xa7, 0xfe, 0x38, 0xe9, - 0x09, 0xbe, 0x52, 0xd4, 0x1f, 0x14, 0x45, 0x86, 0xb6, 0x9e, 0xa1, 0xfe, - 0x00, 0x29, 0x32, 0xb4, 0xf4, 0x0c, 0xf5, 0x37, 0x96, 0x22, 0xc3, 0xba, - 0x9e, 0x21, 0x08, 0xab, 0xaa, 0x55, 0xb1, 0xee, 0xf3, 0x36, 0x23, 0xf7, - 0x09, 0x07, 0x72, 0x75, 0x52, 0x06, 0x46, 0x4e, 0x18, 0xab, 0x78, 0xfb, - 0x0a, 0x7f, 0xef, 0xd3, 0x2e, 0xa2, 0x80, 0x28, 0x99, 0x91, 0x8f, 0x86, - 0xaa, 0xe2, 0x5f, 0xbb, 0xa5, 0x17, 0x75, 0xca, 0xe7, 0xb6, 0xb7, 0x98, - 0x74, 0x81, 0x4a, 0x69, 0xdb, 0xa4, 0x62, 0x98, 0x42, 0x4c, 0x51, 0x4e, - 0x10, 0x03, 0x7d, 0x02, 0xea, 0x82, 0xe4, 0x29, 0x11, 0x71, 0xcb, 0x40, - 0x7a, 0xc8, 0xe6, 0x49, 0x8e, 0xa8, 0xa3, 0x40, 0x3a, 0xbc, 0x76, 0x5e, - 0x58, 0xff, 0xb5, 0x60, 0x53, 0x1b, 0xb8, 0xb1, 0xe3, 0x6d, 0x21, 0x4e, - 0xf5, 0x8e, 0x9e, 0x93, 0xe7, 0x1b, 0x70, 0xb2, 0xce, 0xed, 0x3c, 0x27, - 0x40, 0x2a, 0x41, 0xc8, 0x92, 0xf1, 0xa4, 0xce, 0x8e, 0x3e, 0x88, 0x86, - 0x38, 0x9d, 0xe9, 0xd1, 0x67, 0x24, 0x46, 0x4b, 0xa1, 0x82, 0x5a, 0x42, - 0xbc, 0xd4, 0x8b, 0x59, 0xe2, 0xf3, 0x40, 0x50, 0xfd, 0x21, 0x46, 0x06, - 0xe5, 0x55, 0x12, 0xa3, 0x10, 0x86, 0xd7, 0x37, 0x46, 0x68, 0x98, 0xd1, - 0xeb, 0xdc, 0x39, 0xa2, 0xb0, 0x52, 0xab, 0x60, 0x47, 0x0a, 0x7e, 0x42, - 0xf7, 0x5f, 0x07, 0xf0, 0xaa, 0xda, 0x32, 0x38, 0xf6, 0x53, 0xae, 0xc3, - 0x79, 0x1f, 0xc2, 0x7e, 0xa0, 0xa5, 0x33, 0xea, 0x10, 0x08, 0xe6, 0x95, - 0x3a, 0x8b, 0xaf, 0xa8, 0xfb, 0xe2, 0x41, 0x9f, 0x93, 0xb4, 0x0d, 0xee, - 0xf6, 0x45, 0x46, 0x5f, 0x94, 0x8c, 0x0c, 0xe0, 0x7f, 0x66, 0xcf, 0xde, - 0x1f, 0x7f, 0x90, 0x78, 0x08, 0x88, 0x97, 0x39, 0x72, 0xbd, 0x3a, 0x60, - 0x4e, 0xdb, 0x13, 0x0c, 0x68, 0xed, 0x96, 0x9f, 0x12, 0x8f, 0x85, 0xef, - 0xe3, 0xaa, 0x76, 0xfb, 0x94, 0x76, 0x2a, 0xdc, 0x39, 0xa8, 0xb6, 0xfb, - 0x94, 0xf6, 0x92, 0x59, 0xa1, 0x66, 0xaf, 0x4f, 0xa9, 0x7b, 0xd4, 0xf6, - 0x35, 0xbb, 0x7d, 0x26, 0x1f, 0xb6, 0xe2, 0x2a, 0x3c, 0x97, 0xca, 0xba, - 0x01, 0x24, 0x6b, 0x19, 0x14, 0xc9, 0xa5, 0x73, 0x82, 0x9a, 0x17, 0xde, - 0xcd, 0x29, 0x9b, 0x4f, 0xa1, 0xe6, 0x06, 0x25, 0x8a, 0x0c, 0x4a, 0xb8, - 0x80, 0x61, 0x0f, 0x1c, 0xaa, 0xb2, 0x53, 0x00, 0x04, 0x78, 0x0f, 0xe4, - 0xb4, 0xa6, 0x97, 0x3d, 0xc0, 0x56, 0xeb, 0x06, 0x30, 0x2a, 0xe9, 0xd6, - 0x28, 0xde, 0x9f, 0x08, 0xf9, 0xb4, 0xba, 0x01, 0xf6, 0x18, 0x2b, 0x7c, - 0xa6, 0x93, 0xcb, 0x06, 0x21, 0xc0, 0x86, 0xeb, 0xbd, 0xa7, 0x58, 0x39, - 0x0d, 0x70, 0x30, 0xf8, 0x44, 0xa4, 0x00, 0x08, 0x04, 0x30, 0x68, 0x19, - 0x38, 0x3a, 0x86, 0xc4, 0x98, 0x54, 0x73, 0x9f, 0xb4, 0x9b, 0x35, 0x72, - 0xd3, 0x86, 0xf7, 0x04, 0x7a, 0x53, 0xc5, 0x5f, 0x4c, 0x95, 0x21, 0x23, - 0xab, 0x85, 0x4b, 0x63, 0xc2, 0x3d, 0x29, 0x15, 0xe3, 0x97, 0x34, 0x95, - 0x2f, 0x44, 0x09, 0x98, 0x2e, 0x3e, 0xb0, 0xb1, 0xc3, 0xe3, 0x85, 0xb7, - 0x15, 0x79, 0x15, 0x03, 0x2d, 0xa5, 0xa8, 0xae, 0x9d, 0x07, 0x25, 0x1f, - 0x15, 0x6e, 0x1c, 0x10, 0x5f, 0xb9, 0xfe, 0x61, 0x97, 0x9b, 0x25, 0x45, - 0xb4, 0x64, 0xcf, 0x10, 0xb3, 0xea, 0x6d, 0x28, 0x66, 0x17, 0xe8, 0xd0, - 0x14, 0x80, 0x52, 0x31, 0x68, 0x84, 0x66, 0x37, 0xe3, 0xe9, 0x35, 0x80, - 0x3d, 0xa6, 0x6d, 0x7a, 0x09, 0xbd, 0x5f, 0x36, 0x68, 0x95, 0xeb, 0xb1, - 0x51, 0xa1, 0x6d, 0xaf, 0xdb, 0x01, 0x52, 0x05, 0x46, 0xed, 0x72, 0xbd, - 0xb6, 0xaa, 0xb4, 0x16, 0xe1, 0x57, 0xda, 0x95, 0xba, 0xe5, 0x8f, 0x11, - 0xcf, 0x2a, 0x75, 0xb8, 0xe8, 0xf2, 0xef, 0xc4, 0x77, 0xaa, 0xb4, 0xb4, - 0xea, 0x8b, 0x2e, 0x7f, 0x9e, 0x7e, 0x6e, 0xde, 0x54, 0x78, 0x0e, 0x69, - 0x55, 0xb0, 0x1f, 0xab, 0x9d, 0x37, 0xa0, 0x2a, 0x16, 0x24, 0x76, 0x5a, - 0xc5, 0x86, 0x8a, 0xbd, 0x56, 0xb3, 0x22, 0xb1, 0xdf, 0x6a, 0x76, 0x54, - 0xec, 0xb9, 0x82, 0x25, 0x59, 0xed, 0x0b, 0xde, 0xae, 0x8a, 0x21, 0x49, - 0x0d, 0x2b, 0x59, 0x52, 0x57, 0x6a, 0x5a, 0xc1, 0x94, 0x2c, 0xeb, 0x62, - 0x71, 0x49, 0xfe, 0x81, 0x4d, 0x4a, 0xe0, 0x50, 0xc1, 0xa2, 0x2e, 0x7b, - 0xe7, 0x8b, 0x21, 0x5f, 0x38, 0xb6, 0xb9, 0x55, 0x0d, 0x86, 0x93, 0xf9, - 0x27, 0xd4, 0x1f, 0x5f, 0x4f, 0xc4, 0x47, 0xba, 0xe6, 0x86, 0xc5, 0xdb, - 0x0b, 0xaf, 0x81, 0x6d, 0x73, 0x03, 0xe3, 0xed, 0x1b, 0x36, 0x9f, 0xbb, - 0x6d, 0x6e, 0x63, 0x94, 0x81, 0xdd, 0x5c, 0x7c, 0x11, 0x5c, 0x64, 0x05, - 0x3b, 0x13, 0x06, 0x5d, 0xc5, 0xba, 0x78, 0x2b, 0x6e, 0x5b, 0xa4, 0x34, - 0x3f, 0xbd, 0x37, 0x3d, 0xf8, 0x1b, 0xba, 0x47, 0xe1, 0xe3, 0x27, 0xbd, - 0x71, 0x4b, 0xd3, 0x71, 0xd9, 0xc3, 0x2c, 0x5d, 0x17, 0x33, 0x61, 0x3a, - 0x67, 0xba, 0x2e, 0x92, 0x4f, 0xb4, 0x56, 0xee, 0x43, 0x54, 0x79, 0x47, - 0xd7, 0x49, 0xf2, 0xa5, 0xd2, 0xaa, 0x9d, 0x4c, 0x25, 0xbd, 0x9e, 0xeb, - 0x7a, 0x21, 0x31, 0xcc, 0x31, 0xbd, 0x5c, 0x8a, 0xdd, 0x70, 0xb8, 0x1f, - 0xa5, 0xc4, 0xec, 0xe3, 0xd4, 0x42, 0x96, 0xb9, 0xd4, 0x93, 0x90, 0xe1, - 0x36, 0x68, 0xdb, 0x59, 0xe0, 0xf3, 0xa3, 0x00, 0x87, 0x56, 0xc5, 0x11, - 0xe3, 0xc6, 0x93, 0xdb, 0x9b, 0xfe, 0xa7, 0xf9, 0xa7, 0xe9, 0xf8, 0xf6, - 0xf2, 0xd3, 0xa2, 0x3b, 0x9a, 0x7c, 0x12, 0xb6, 0x2e, 0x06, 0x32, 0x64, - 0xec, 0x71, 0x16, 0xc3, 0x6e, 0x9f, 0xb7, 0x35, 0x5f, 0x30, 0xb3, 0xab, - 0xcb, 0x9b, 0xe1, 0x60, 0x51, 0xe0, 0x50, 0x65, 0x93, 0xcf, 0xb7, 0x35, - 0x77, 0xcf, 0x69, 0xef, 0x05, 0x16, 0x67, 0x95, 0xd4, 0xd0, 0x65, 0x7a, - 0x90, 0x59, 0x98, 0x3b, 0xec, 0xaf, 0xfd, 0x5e, 0x7f, 0xba, 0x18, 0xdd, - 0x5e, 0x77, 0x79, 0x6b, 0x73, 0x67, 0xcd, 0x5a, 0x37, 0xed, 0xfa, 0xa2, - 0x8f, 0x35, 0x29, 0xf0, 0x68, 0xd6, 0xcd, 0x27, 0xd1, 0xeb, 0x73, 0xcd, - 0x37, 0xcd, 0x47, 0xde, 0x13, 0x8c, 0xaf, 0x69, 0x3e, 0xe4, 0x5e, 0xbf, - 0xc1, 0xa3, 0xb9, 0x0a, 0xa3, 0xec, 0xce, 0xe6, 0xfd, 0x45, 0xf3, 0x45, - 0xc0, 0xdd, 0x33, 0x37, 0x34, 0xda, 0xb6, 0x25, 0xb6, 0x35, 0x37, 0xb1, - 0xa4, 0xad, 0x10, 0x49, 0x9a, 0x9b, 0x18, 0x6d, 0xdb, 0x16, 0xdb, 0x9a, - 0x07, 0x01, 0x49, 0x5b, 0xee, 0x55, 0xdb, 0xe6, 0xaa, 0xa1, 0x6d, 0x3b, - 0x62, 0xbf, 0xe6, 0xfa, 0x49, 0xda, 0xf2, 0x7e, 0xcf, 0xcc, 0x03, 0x80, - 0xa4, 0x2d, 0xdf, 0x6e, 0xce, 0xcc, 0x37, 0x7f, 0xda, 0xd6, 0xaa, 0x0b, - 0x83, 0x3e, 0x33, 0xf7, 0x68, 0x69, 0x63, 0x61, 0xd4, 0xe6, 0xbb, 0x7e, - 0xda, 0x58, 0x18, 0x76, 0x45, 0xd3, 0xc2, 0x8d, 0xc5, 0xf2, 0xcf, 0x8a, - 0xc6, 0x65, 0xd9, 0x52, 0xeb, 0x8a, 0xe6, 0x45, 0x5a, 0xf3, 0x85, 0x78, - 0x76, 0x96, 0x1e, 0x55, 0xc9, 0xf1, 0xf4, 0xb7, 0x9f, 0x7e, 0x39, 0x7d, - 0x5a, 0xbd, 0xec, 0xb6, 0xbf, 0xfd, 0xf4, 0x7f, 0xf9, 0x0b, 0x6a, 0x39, - + 0x78, 0x9c, 0xed, 0x7d, 0x6b, 0x53, 0xe3, 0x48, 0xb2, 0xe8, 0xe7, 0x9d, + 0x5f, 0x51, 0xa7, 0xbf, 0x6c, 0xf7, 0xbd, 0xc3, 0x80, 0xe4, 0x07, 0x26, + 0x62, 0x66, 0x6f, 0x18, 0x63, 0x68, 0xe2, 0x00, 0x66, 0x6d, 0xd3, 0x0f, + 0x6e, 0xdc, 0x70, 0x08, 0x5b, 0x06, 0xc5, 0xd8, 0x92, 0x8f, 0x24, 0x37, + 0x30, 0xbf, 0xfe, 0xd6, 0x43, 0x52, 0x55, 0x49, 0x59, 0xca, 0x92, 0xa1, + 0xe7, 0xb5, 0x4c, 0x9c, 0xd8, 0x43, 0x43, 0x56, 0x96, 0x2a, 0x33, 0x2b, + 0x5f, 0x95, 0x95, 0xf5, 0xf3, 0xb7, 0xf9, 0xd3, 0x7a, 0x45, 0xee, 0xfd, + 0xf0, 0x97, 0x77, 0xee, 0x4f, 0xce, 0x3b, 0xb2, 0x0e, 0xc2, 0xd9, 0x37, + 0x3f, 0xa6, 0xff, 0x62, 0xff, 0xf0, 0x9e, 0x8a, 0x7f, 0xfc, 0xeb, 0x87, + 0x1f, 0x08, 0xf9, 0xd9, 0x0f, 0xb7, 0x6b, 0x12, 0x7a, 0x6b, 0xff, 0x97, + 0x77, 0x83, 0x68, 0xbd, 0xf1, 0x62, 0x9f, 0x9c, 0x6e, 0xc3, 0x79, 0x1a, + 0x44, 0xe1, 0x3b, 0xb2, 0x89, 0xfd, 0x65, 0xf0, 0xf4, 0xcb, 0xbb, 0x4f, + 0xad, 0x93, 0xd9, 0x60, 0x74, 0x79, 0xdd, 0x1f, 0x0f, 0x67, 0xa7, 0x37, + 0x57, 0x03, 0x3a, 0x96, 0xd0, 0xff, 0x7e, 0xfe, 0xe6, 0xad, 0xb6, 0x7e, + 0x36, 0xfa, 0x6a, 0xf8, 0x69, 0x38, 0x7e, 0x47, 0xf8, 0xaf, 0x7e, 0x79, + 0x77, 0xf0, 0x6e, 0x1f, 0x80, 0xb9, 0x18, 0x4e, 0x26, 0x05, 0x88, 0x03, + 0x82, 0x0c, 0xff, 0x7d, 0xd3, 0xbf, 0x28, 0x60, 0x5c, 0x03, 0x1a, 0x0d, + 0xa8, 0x05, 0x02, 0x9d, 0x8d, 0x87, 0xfd, 0xa9, 0xf2, 0x45, 0x6d, 0x10, + 0xea, 0x6a, 0x34, 0xd5, 0x91, 0x75, 0x60, 0x64, 0x3a, 0x50, 0x17, 0x04, + 0xea, 0x5f, 0x7c, 0xee, 0x7f, 0x95, 0xeb, 0x3b, 0x14, 0x40, 0x3f, 0xef, + 0x33, 0x12, 0x57, 0x88, 0x7d, 0x1d, 0x07, 0xeb, 0x20, 0x0d, 0xbe, 0xf9, + 0x3a, 0x95, 0xaf, 0xc7, 0xe7, 0x97, 0x10, 0x75, 0xaf, 0x47, 0xe7, 0x57, + 0xd3, 0x09, 0x46, 0xde, 0xf3, 0xab, 0x21, 0x46, 0x5f, 0x06, 0x33, 0xbb, + 0x18, 0x8d, 0xae, 0x31, 0x1a, 0x33, 0xb8, 0xc9, 0x74, 0x7c, 0x7e, 0x8d, + 0xd0, 0x99, 0x82, 0xf4, 0xaf, 0xce, 0x2e, 0x94, 0x89, 0x61, 0x4a, 0xe7, + 0x70, 0x25, 0xa4, 0x30, 0xbd, 0x0b, 0xe0, 0xd3, 0xfe, 0x55, 0x99, 0xea, + 0x2a, 0x41, 0x37, 0xde, 0xfc, 0x57, 0x3f, 0xcd, 0x06, 0x7d, 0xf4, 0x56, + 0xe9, 0x3b, 0x32, 0x8f, 0x16, 0x92, 0x40, 0x3a, 0xc0, 0x15, 0x5b, 0xb5, + 0xf8, 0xbb, 0x03, 0xfd, 0xfd, 0x74, 0xb5, 0x4d, 0x1e, 0x72, 0x88, 0x36, + 0xfd, 0x61, 0xf5, 0xcb, 0xbb, 0x63, 0x23, 0x20, 0xe9, 0xaf, 0x56, 0x64, + 0x92, 0x7a, 0xa9, 0x9f, 0x0f, 0xe9, 0xd4, 0x0c, 0xa1, 0x80, 0x71, 0x4a, + 0xa6, 0xc1, 0xca, 0x27, 0xc7, 0x41, 0x18, 0x06, 0xe1, 0x7d, 0x3e, 0xaa, + 0x5b, 0x33, 0xea, 0x3c, 0x9c, 0xc7, 0xfe, 0xda, 0x0f, 0x53, 0x32, 0xf1, + 0xd7, 0xde, 0xe6, 0x21, 0x8a, 0x8b, 0xc9, 0x0e, 0x21, 0xf8, 0xcf, 0x5e, + 0x90, 0x92, 0x28, 0xac, 0x42, 0xf7, 0x20, 0xe8, 0xe3, 0xd8, 0x0b, 0xe7, + 0xc5, 0x82, 0x9d, 0x6e, 0x2e, 0x78, 0xcb, 0xc0, 0x5f, 0x2d, 0x72, 0xa1, + 0x5e, 0x2c, 0x62, 0x3f, 0x49, 0xde, 0x91, 0x24, 0xf8, 0x8d, 0xc9, 0x80, + 0x4b, 0x7f, 0x62, 0x4b, 0x61, 0x24, 0x26, 0xe9, 0xf3, 0x86, 0xfe, 0xce, + 0xcb, 0x40, 0x32, 0xee, 0x88, 0x29, 0x4c, 0xb3, 0x91, 0x34, 0x22, 0xc9, + 0xf6, 0x6e, 0x6f, 0x15, 0x24, 0x05, 0xb3, 0x9c, 0xc3, 0xef, 0x3b, 0xf3, + 0xd8, 0x4f, 0xb7, 0x71, 0x48, 0x96, 0x71, 0xb4, 0xae, 0xce, 0xcd, 0x29, + 0x03, 0xb0, 0x8b, 0x12, 0x8f, 0x5c, 0x6e, 0x57, 0x69, 0xb0, 0x97, 0x78, + 0xeb, 0x0d, 0x65, 0xdb, 0xd8, 0x4f, 0xa2, 0xd5, 0x37, 0x7f, 0x21, 0x98, + 0x38, 0x88, 0x56, 0x51, 0x4c, 0x8e, 0xb7, 0xcb, 0xa5, 0x1f, 0xe7, 0xb8, + 0xdc, 0x4c, 0x66, 0xc6, 0xb0, 0x00, 0x34, 0xc0, 0x48, 0xbc, 0x70, 0x41, + 0x86, 0xa3, 0xd3, 0x02, 0x73, 0x47, 0xc1, 0x6c, 0x40, 0x7d, 0xba, 0xa5, + 0xf2, 0xc8, 0x51, 0x6e, 0x99, 0xf6, 0xce, 0x64, 0x2d, 0xff, 0x40, 0x3e, + 0x38, 0xc7, 0x66, 0xc3, 0x69, 0xb7, 0x57, 0xd0, 0xbb, 0x0d, 0xd2, 0xbb, + 0x34, 0xfc, 0xc2, 0x4b, 0x84, 0x7c, 0xe7, 0x08, 0x9c, 0x62, 0x7c, 0x2b, + 0x1f, 0x7f, 0x17, 0x45, 0x2b, 0x70, 0xf0, 0x49, 0x90, 0x78, 0x77, 0x8c, + 0x06, 0x2b, 0xdf, 0x8b, 0x99, 0x00, 0x7f, 0x8e, 0x83, 0x14, 0xc0, 0xe4, + 0x5a, 0x63, 0xba, 0xdd, 0x9f, 0xa4, 0x7e, 0x38, 0x0f, 0x56, 0x39, 0x45, + 0x1f, 0x61, 0x8c, 0x8e, 0xfd, 0xb7, 0xa9, 0xfc, 0x31, 0x60, 0x3b, 0xa8, + 0x62, 0x93, 0x62, 0x09, 0xc8, 0xe5, 0xde, 0x2a, 0xf2, 0x16, 0x4d, 0x38, + 0x67, 0xb3, 0x53, 0x9a, 0x72, 0xce, 0x48, 0xb2, 0xd8, 0xf7, 0x16, 0xaf, + 0x46, 0x31, 0x18, 0x59, 0x33, 0x82, 0x09, 0x41, 0x57, 0xc8, 0x43, 0xce, + 0xfc, 0xd0, 0x8f, 0xbd, 0x55, 0x41, 0x9f, 0x5e, 0x4e, 0x30, 0xe0, 0xb3, + 0x2e, 0xfd, 0x75, 0x14, 0x3f, 0x93, 0x3b, 0x2f, 0xf1, 0x49, 0x46, 0x0f, + 0x12, 0x2d, 0xa9, 0x5a, 0xa0, 0x7f, 0xdd, 0x4f, 0x19, 0xd2, 0xc5, 0x76, + 0xbd, 0x21, 0x77, 0x19, 0xe1, 0x2b, 0xc4, 0x74, 0x61, 0xbd, 0x63, 0xda, + 0x07, 0x0c, 0xf7, 0x29, 0xc3, 0x0d, 0x90, 0xf0, 0xc8, 0x9a, 0x86, 0x9f, + 0xce, 0xf6, 0x2e, 0xbd, 0xe4, 0xd7, 0xec, 0xab, 0xf8, 0x17, 0x02, 0xf8, + 0x7a, 0x3b, 0xec, 0x8b, 0x7a, 0x8c, 0x87, 0x0d, 0xb9, 0x5c, 0x8f, 0xad, + 0xbb, 0xeb, 0x7a, 0xe7, 0xb9, 0x42, 0x48, 0x18, 0xeb, 0xf7, 0x0d, 0xe8, + 0x3b, 0xbb, 0x2f, 0xdf, 0x6e, 0x82, 0xf6, 0x6e, 0xd4, 0xb0, 0x43, 0x5e, + 0x51, 0x8f, 0x55, 0xec, 0xd7, 0xc1, 0x93, 0xbf, 0xca, 0x70, 0x9f, 0x46, + 0xf1, 0xda, 0x4b, 0x0b, 0xf9, 0x2c, 0xf0, 0x14, 0x32, 0xb0, 0x0d, 0xc2, + 0x34, 0x93, 0xff, 0x92, 0x5b, 0x15, 0xdf, 0xdf, 0x79, 0x3d, 0xfa, 0x5f, + 0xd5, 0x8f, 0x2c, 0x01, 0xde, 0xdd, 0xc7, 0x9d, 0x6e, 0x87, 0x2c, 0x82, + 0xf4, 0xc1, 0x8f, 0xfd, 0x45, 0xd5, 0xa7, 0x84, 0xe1, 0xc3, 0x28, 0x1b, + 0x02, 0x38, 0x97, 0xfb, 0x7c, 0x3d, 0xd0, 0xe2, 0x2e, 0xe9, 0xd6, 0xad, + 0x2e, 0xa7, 0x8b, 0x2f, 0x67, 0x22, 0xcc, 0xe8, 0x01, 0xba, 0x9c, 0x13, + 0x7f, 0x1e, 0x50, 0x9a, 0xf9, 0xe4, 0xa9, 0x8d, 0x2e, 0x45, 0xc2, 0x32, + 0xa9, 0x6d, 0xb0, 0x0c, 0x13, 0x5f, 0xda, 0xf8, 0x42, 0xc6, 0x54, 0x67, + 0x28, 0x44, 0x33, 0x2d, 0x63, 0x8a, 0x7e, 0xfc, 0xc5, 0xb4, 0xd1, 0x27, + 0x67, 0x4a, 0x94, 0xba, 0x64, 0x5c, 0xb3, 0x16, 0xae, 0x56, 0x55, 0x3d, + 0x9b, 0xbf, 0xfd, 0x2a, 0x0a, 0x7d, 0xf4, 0xcb, 0xb9, 0xe4, 0xa2, 0x5f, + 0x7f, 0xbb, 0x9f, 0x88, 0xcd, 0x59, 0x5d, 0x44, 0x19, 0xb2, 0x1a, 0x94, + 0x94, 0x20, 0x32, 0x3d, 0x02, 0x04, 0x25, 0x39, 0x39, 0x6a, 0x2d, 0xcd, + 0x05, 0xb3, 0xcb, 0x75, 0x86, 0xe6, 0xe8, 0x0f, 0x37, 0x34, 0x06, 0x8d, + 0xc9, 0x3c, 0x8a, 0xd7, 0xb5, 0x10, 0x06, 0x8c, 0x3b, 0x5a, 0x08, 0x03, + 0xb6, 0x8a, 0x85, 0x78, 0x53, 0x82, 0x6f, 0x4a, 0xf0, 0x4d, 0x09, 0xfe, + 0xa1, 0x4a, 0xf0, 0x3c, 0x5c, 0xf8, 0x4f, 0x34, 0x3c, 0x2d, 0x72, 0x55, + 0xe4, 0x42, 0x89, 0x9c, 0x69, 0x40, 0x0e, 0xe9, 0x3e, 0xef, 0x29, 0x58, + 0x6f, 0xd7, 0x84, 0x8f, 0x05, 0x62, 0xf7, 0x43, 0x57, 0xa3, 0x26, 0xa4, + 0x36, 0xfa, 0x52, 0x65, 0x52, 0x2c, 0xc1, 0xdc, 0x4f, 0xb2, 0x79, 0x2b, + 0xc8, 0xda, 0x07, 0x28, 0xb2, 0x0b, 0x3f, 0xbc, 0x4f, 0x1f, 0x80, 0xb1, + 0x3d, 0x74, 0x28, 0x5f, 0x02, 0x07, 0xca, 0x87, 0xb7, 0x9b, 0xc8, 0x73, + 0x6f, 0xef, 0x2e, 0x48, 0x51, 0xa1, 0x70, 0xba, 0x1a, 0x98, 0x03, 0x70, + 0xa8, 0xac, 0x06, 0x0b, 0x6e, 0xac, 0x15, 0x9d, 0xd1, 0xae, 0x8a, 0xab, + 0x4c, 0x31, 0x62, 0x71, 0xd5, 0x27, 0x3f, 0x4e, 0xe9, 0x52, 0xfb, 0x71, + 0xec, 0x3d, 0x4b, 0x6e, 0x27, 0x05, 0xa7, 0x5b, 0x10, 0xa7, 0x05, 0x79, + 0x58, 0x90, 0x13, 0xc4, 0x34, 0xe4, 0x11, 0x38, 0x7e, 0x77, 0x26, 0x7d, + 0x07, 0x6a, 0xe8, 0xe2, 0x5e, 0x98, 0x1a, 0x2d, 0x10, 0xef, 0x80, 0x29, + 0x94, 0x13, 0x2f, 0xf5, 0xc8, 0x74, 0x57, 0x81, 0x11, 0xa2, 0x40, 0x02, + 0xb1, 0x73, 0x10, 0x35, 0xd1, 0x72, 0x39, 0xf0, 0xd3, 0xfe, 0x33, 0x90, + 0x9f, 0x35, 0x2b, 0x3b, 0xb9, 0x36, 0xf8, 0x33, 0x2d, 0x74, 0xdd, 0x75, + 0x44, 0xff, 0x94, 0x6f, 0x49, 0x44, 0xba, 0x2f, 0x82, 0xd0, 0x2f, 0x81, + 0x9a, 0x16, 0x34, 0x8d, 0x03, 0x2f, 0xbc, 0x5f, 0x95, 0xc1, 0x4d, 0xca, + 0x6f, 0xfc, 0xf1, 0xab, 0x0e, 0x58, 0x5d, 0x7d, 0x2d, 0x93, 0xcf, 0x2e, + 0xc8, 0xe4, 0xc1, 0x5b, 0x50, 0xc5, 0xaf, 0xa5, 0x70, 0xbb, 0xed, 0x9c, + 0xaf, 0xff, 0xb5, 0xb7, 0x47, 0xa6, 0x0f, 0xd2, 0x81, 0x13, 0x54, 0x7c, + 0x0c, 0x56, 0xd4, 0x2f, 0xf2, 0xe9, 0xbf, 0x56, 0x2b, 0xaa, 0x19, 0x83, + 0x90, 0xdc, 0x3d, 0x93, 0x5f, 0xfd, 0x38, 0xa4, 0x9e, 0x09, 0xfd, 0x90, + 0x60, 0xe1, 0xf1, 0x0c, 0x0e, 0x43, 0xf6, 0x13, 0xd9, 0xdb, 0x6b, 0x94, + 0xac, 0xc1, 0xf7, 0xc9, 0xf0, 0x89, 0x9a, 0x86, 0x05, 0x9d, 0x37, 0x11, + 0x9f, 0x1e, 0xfb, 0xf3, 0x28, 0x06, 0xbc, 0x29, 0x3c, 0xe1, 0x76, 0xb5, + 0x5d, 0xdf, 0x51, 0x04, 0x74, 0xf7, 0x7a, 0x69, 0x1a, 0x07, 0x77, 0x5b, + 0x6a, 0xeb, 0x3d, 0xb6, 0xfd, 0x13, 0xcc, 0xfe, 0x61, 0xbb, 0x47, 0xa4, + 0xf0, 0xb8, 0xad, 0x4b, 0x4a, 0x9b, 0xc6, 0x71, 0xda, 0xd0, 0xae, 0x11, + 0x23, 0x26, 0xb9, 0xd5, 0x13, 0xd3, 0x4b, 0xb2, 0x1c, 0x75, 0x51, 0xba, + 0x08, 0x0c, 0x9f, 0xce, 0x88, 0xb0, 0x76, 0x65, 0x0c, 0x3d, 0x5c, 0x8d, + 0x08, 0x0c, 0xb7, 0x93, 0x82, 0x2d, 0x72, 0x4b, 0x74, 0xdb, 0x96, 0xa3, + 0x33, 0xfb, 0x2e, 0x10, 0x74, 0x4d, 0x7b, 0x0a, 0xa5, 0x5f, 0x14, 0x2e, + 0x83, 0xfb, 0x6d, 0x2c, 0x04, 0xe9, 0x38, 0x48, 0x0b, 0x35, 0x7c, 0x04, + 0xea, 0x9c, 0xa1, 0x17, 0xaf, 0x9e, 0xc9, 0x2d, 0xd9, 0x6e, 0xa8, 0xec, + 0xd1, 0xdd, 0xe3, 0x87, 0xcc, 0xe7, 0xde, 0xc9, 0x5f, 0xcf, 0x51, 0x19, + 0x51, 0xe0, 0x69, 0x1c, 0x8b, 0xef, 0xb0, 0x48, 0xd6, 0xf8, 0x9b, 0xf4, + 0x61, 0x6f, 0xea, 0x33, 0xe5, 0x5b, 0x9c, 0x45, 0x96, 0xa5, 0xd2, 0x29, + 0x1c, 0x89, 0xca, 0xb9, 0x25, 0xc8, 0xa2, 0xe8, 0x1b, 0x8d, 0xdf, 0xee, + 0x59, 0xd2, 0x9d, 0x46, 0x76, 0xaa, 0xb7, 0xad, 0x7c, 0x9a, 0x03, 0x72, + 0x9a, 0x69, 0x02, 0xaa, 0x05, 0x84, 0xa2, 0x49, 0xe0, 0x5d, 0x5d, 0xa0, + 0xbf, 0x0e, 0x36, 0x3e, 0x99, 0xf8, 0x2b, 0x7f, 0x9e, 0x56, 0x27, 0xc0, + 0x83, 0x30, 0xe1, 0x04, 0x07, 0x09, 0xdd, 0x9b, 0x23, 0x8a, 0x31, 0x3b, + 0x28, 0xb0, 0x09, 0x0e, 0x76, 0xfa, 0x5a, 0x4e, 0x0c, 0xd5, 0x12, 0xc8, + 0x6f, 0xed, 0xec, 0x8c, 0xbd, 0x1f, 0xa6, 0x01, 0x55, 0x85, 0x34, 0xfa, + 0xa5, 0xae, 0xa3, 0x30, 0x16, 0xec, 0x38, 0x83, 0xdb, 0x82, 0xea, 0x3c, + 0x78, 0x6a, 0x6d, 0xc8, 0x25, 0x89, 0x70, 0xa9, 0x20, 0xa3, 0xe5, 0x32, + 0xf1, 0x01, 0xd2, 0xe2, 0x2a, 0x6f, 0xb0, 0x8a, 0xe6, 0xbf, 0x3e, 0x52, + 0xd2, 0x6a, 0x1e, 0x4e, 0xf3, 0x13, 0x86, 0xec, 0x73, 0xc6, 0x3e, 0xe3, + 0x0f, 0x95, 0x3a, 0x6f, 0x1e, 0x84, 0xf7, 0x44, 0x39, 0xcf, 0x6d, 0x9e, + 0x30, 0xcf, 0x50, 0x52, 0x4f, 0xe3, 0xd1, 0x8b, 0x17, 0x16, 0x28, 0x9b, + 0xa5, 0xcd, 0x4f, 0x57, 0x5e, 0x2a, 0xac, 0x1d, 0xa1, 0x3f, 0xde, 0x4b, + 0x85, 0x02, 0x9e, 0x26, 0x30, 0xe8, 0x3d, 0x66, 0x60, 0xd8, 0x37, 0x64, + 0xf0, 0xe6, 0x23, 0x38, 0x2b, 0x9d, 0xc6, 0xa5, 0x80, 0x23, 0x29, 0xa6, + 0xee, 0x41, 0x53, 0x0b, 0xb8, 0x09, 0x87, 0x33, 0x4f, 0xb9, 0x5c, 0x45, + 0x1e, 0x3e, 0x27, 0x13, 0x37, 0x6a, 0xae, 0x17, 0x69, 0x71, 0xc0, 0x79, + 0x74, 0x04, 0xcd, 0xa9, 0xc2, 0xbd, 0x74, 0xce, 0xf1, 0xc7, 0x29, 0xf9, + 0x42, 0xee, 0xa2, 0x6d, 0xb8, 0xf0, 0xe2, 0xe7, 0xc2, 0xec, 0x1d, 0x1c, + 0x40, 0x13, 0x33, 0xe0, 0x4d, 0xe1, 0x8e, 0xa9, 0xc3, 0x32, 0x6e, 0x77, + 0xab, 0x9f, 0x61, 0x43, 0x6c, 0x7d, 0x9f, 0xe4, 0x9f, 0xe0, 0xa8, 0x7e, + 0x4d, 0xfa, 0xe0, 0x27, 0xbe, 0xf0, 0x68, 0xe8, 0xde, 0xa4, 0xaa, 0xf3, + 0x2e, 0xa2, 0x43, 0xf8, 0x1a, 0xf7, 0x9c, 0xbd, 0xde, 0xde, 0x21, 0xd5, + 0xde, 0x6c, 0xe0, 0x82, 0xbc, 0x4f, 0xa3, 0x0d, 0x71, 0xba, 0x84, 0xfa, + 0x9a, 0x3c, 0x20, 0xf3, 0x04, 0x54, 0xcb, 0xfd, 0x00, 0xef, 0x7d, 0x75, + 0x72, 0x72, 0x13, 0x72, 0xeb, 0x55, 0x59, 0x8e, 0x83, 0x5b, 0x74, 0x0d, + 0x0f, 0xdd, 0x0f, 0xa9, 0xb4, 0xac, 0x10, 0x5d, 0x2c, 0x3d, 0x93, 0x60, + 0x43, 0x3e, 0x53, 0xf7, 0x3a, 0x7a, 0x94, 0x74, 0x01, 0x83, 0x58, 0x05, + 0x92, 0x7c, 0xf4, 0x83, 0xfb, 0x07, 0xe6, 0x95, 0x93, 0x0d, 0xcb, 0x3f, + 0x41, 0xeb, 0x69, 0xdb, 0xf8, 0x17, 0x12, 0xe3, 0x67, 0x26, 0x6c, 0xb5, + 0x08, 0x5b, 0x78, 0x90, 0xac, 0x22, 0x3c, 0x8e, 0xd2, 0x34, 0x5a, 0x93, + 0x3c, 0x3f, 0x46, 0x5d, 0xc2, 0x20, 0xf4, 0x94, 0xe3, 0xc9, 0x46, 0x94, + 0x57, 0x11, 0x5f, 0xf8, 0xcb, 0xd4, 0x06, 0x6d, 0x33, 0x3e, 0x7c, 0x0a, + 0xfc, 0xc7, 0x4d, 0x14, 0xa7, 0x15, 0x19, 0x05, 0xc3, 0xcc, 0x02, 0x7a, + 0xe0, 0x87, 0x29, 0x15, 0xd5, 0xaf, 0x7b, 0x73, 0xbb, 0x15, 0x26, 0x8e, + 0xfb, 0x53, 0x1b, 0x5c, 0x62, 0x19, 0xe5, 0x97, 0x7a, 0x94, 0x07, 0x00, + 0xc6, 0x9a, 0xe5, 0xdd, 0xb2, 0x92, 0x2b, 0x6e, 0xf1, 0xd6, 0xde, 0x13, + 0x75, 0x80, 0x83, 0xcd, 0x86, 0x69, 0xd2, 0xcd, 0xca, 0x0b, 0x65, 0x48, + 0xed, 0x1c, 0x80, 0xae, 0x70, 0x9e, 0x3d, 0xb9, 0x7d, 0x04, 0x94, 0x91, + 0x94, 0x0a, 0x45, 0x1b, 0x95, 0x11, 0x04, 0xa1, 0x19, 0x41, 0x43, 0x6d, + 0xc6, 0x24, 0x61, 0x43, 0x1d, 0x91, 0x2f, 0x5f, 0xc9, 0x64, 0x4e, 0x0d, + 0xba, 0x2c, 0x59, 0x71, 0x0e, 0x8a, 0x52, 0x97, 0x3a, 0xf2, 0x7e, 0xf4, + 0x56, 0xcb, 0x3d, 0xb9, 0x7f, 0x9c, 0x7d, 0xa7, 0x4b, 0x05, 0x9f, 0x6a, + 0x11, 0x2e, 0xf8, 0x3b, 0xae, 0x50, 0xc7, 0x5e, 0xec, 0x25, 0x1c, 0xf9, + 0x8e, 0xab, 0xbf, 0xe5, 0x8b, 0xf7, 0x39, 0x43, 0xcb, 0x02, 0xdb, 0xb5, + 0xa1, 0xc2, 0x6d, 0xae, 0xc6, 0xde, 0xdf, 0xce, 0x59, 0x96, 0xf1, 0x36, + 0xf9, 0xf0, 0xd2, 0xa5, 0xe7, 0xdf, 0x54, 0x8b, 0xb1, 0xe1, 0x7a, 0xd5, + 0xd2, 0x24, 0xee, 0x70, 0x12, 0x2d, 0x12, 0x91, 0x31, 0x9c, 0x5b, 0xb3, + 0xe8, 0x93, 0x68, 0x4b, 0x1d, 0x99, 0xbd, 0x2c, 0xd5, 0x4f, 0xd9, 0x12, + 0x46, 0xe1, 0xde, 0x3a, 0xd1, 0x72, 0x33, 0xaa, 0xbf, 0x5d, 0x39, 0x07, + 0xaf, 0xa2, 0xe4, 0xdf, 0xd5, 0x5f, 0x51, 0xe7, 0x2d, 0x8b, 0x88, 0x98, + 0x1b, 0xa7, 0xf9, 0x08, 0xae, 0x82, 0xf0, 0x50, 0xd3, 0x44, 0x70, 0x9a, + 0x9e, 0x23, 0x60, 0x43, 0x09, 0xa3, 0x16, 0x76, 0x08, 0x20, 0xa1, 0xbb, + 0x78, 0xde, 0x5c, 0x81, 0x76, 0xdc, 0x1e, 0x9a, 0xc4, 0x50, 0xc0, 0xdd, + 0x4e, 0xb7, 0x51, 0x22, 0xa7, 0x4c, 0x96, 0x73, 0x6a, 0x6b, 0xa9, 0xd7, + 0x8d, 0x90, 0xa7, 0xf3, 0x9f, 0x42, 0x9e, 0xfe, 0x36, 0x8d, 0xf6, 0x02, + 0x41, 0x13, 0xe6, 0xf2, 0x73, 0x72, 0xf1, 0x4c, 0x0f, 0xe1, 0x49, 0x3a, + 0x9e, 0xea, 0x84, 0x24, 0x12, 0x0f, 0x47, 0xd4, 0x53, 0xc1, 0x6e, 0x9b, + 0x67, 0xe1, 0xc4, 0x99, 0x14, 0xf7, 0x59, 0x20, 0x9c, 0x78, 0x6c, 0xc2, + 0xcb, 0xc2, 0x94, 0x60, 0x8f, 0xbc, 0x6f, 0x3f, 0x7d, 0x80, 0x50, 0x55, + 0xc2, 0x93, 0x2a, 0xae, 0x4c, 0xe1, 0xbe, 0xa7, 0xbb, 0x8f, 0x9d, 0x35, + 0x4a, 0xdd, 0x20, 0x13, 0x22, 0xcc, 0xfa, 0x60, 0x7e, 0x80, 0xd0, 0xac, + 0x75, 0x58, 0xaa, 0x89, 0x19, 0x03, 0xb1, 0xca, 0x74, 0x27, 0xe6, 0xd2, + 0x3e, 0x8b, 0x64, 0x4b, 0x59, 0xf2, 0xd7, 0xe2, 0xb4, 0x35, 0x81, 0xa3, + 0x06, 0x0b, 0x57, 0xca, 0x80, 0xd0, 0xc3, 0xeb, 0x0f, 0x95, 0x75, 0x63, + 0x9a, 0x75, 0xcc, 0x12, 0x77, 0x31, 0xa6, 0x5b, 0x5b, 0x35, 0xa7, 0xca, + 0xcd, 0x74, 0xeb, 0x21, 0x9e, 0xab, 0xe1, 0xe9, 0x9e, 0xbd, 0xdb, 0x7d, + 0xf1, 0xff, 0x07, 0xd1, 0x37, 0xb2, 0x10, 0x07, 0xb6, 0x00, 0x36, 0x3c, + 0x69, 0x93, 0x61, 0x23, 0x37, 0x3c, 0xff, 0x43, 0x4e, 0x82, 0xd8, 0xe7, + 0xd9, 0x18, 0x72, 0x36, 0xdd, 0x3f, 0x1b, 0x02, 0x28, 0xf1, 0x9d, 0x26, + 0xd2, 0x28, 0xa4, 0xc8, 0x56, 0xc0, 0x59, 0x9b, 0x43, 0x7c, 0x7b, 0x65, + 0xf1, 0x75, 0x96, 0x20, 0x2c, 0x4a, 0xeb, 0x2a, 0x98, 0xf0, 0xe0, 0x3f, + 0x3b, 0xda, 0x37, 0x1d, 0x73, 0x1e, 0x5a, 0xe4, 0xcf, 0x7f, 0x9f, 0x73, + 0x4e, 0x20, 0xa2, 0xca, 0x8e, 0x74, 0x0d, 0xc9, 0xa4, 0x4a, 0x0c, 0x03, + 0x24, 0x8d, 0xa9, 0xc0, 0x7d, 0x3c, 0x19, 0x8b, 0xaa, 0xb6, 0x5c, 0x05, + 0xd6, 0x9f, 0xc7, 0x77, 0x2d, 0x4e, 0xb0, 0xe3, 0x62, 0x6b, 0xcc, 0xf9, + 0xae, 0x20, 0xa6, 0x83, 0x77, 0x13, 0xa9, 0x2a, 0x08, 0x2a, 0x47, 0xfc, + 0x26, 0x12, 0x9a, 0xa6, 0xde, 0xed, 0x0c, 0xbf, 0xa9, 0x65, 0xe8, 0xe2, + 0xbb, 0xca, 0xd2, 0x30, 0x74, 0xf1, 0xcd, 0x94, 0x9b, 0x05, 0x11, 0x74, + 0x4a, 0x1c, 0x8d, 0xc2, 0xd8, 0xcc, 0x28, 0x98, 0x71, 0x58, 0xa8, 0xdb, + 0x6c, 0x0b, 0xed, 0x5e, 0xde, 0x0d, 0x2b, 0x58, 0x19, 0xa0, 0xca, 0x20, + 0xcb, 0xe9, 0xd4, 0xe8, 0x53, 0xa1, 0x96, 0x69, 0x94, 0x2b, 0xce, 0x42, + 0x80, 0x63, 0x03, 0x3b, 0xcb, 0x41, 0x59, 0xbc, 0x5d, 0x87, 0x46, 0x2c, + 0xcd, 0x62, 0xe3, 0x33, 0x7f, 0x4d, 0x4d, 0x45, 0x6e, 0x8a, 0x8a, 0x95, + 0xb8, 0x9d, 0x76, 0x8d, 0xd7, 0x9d, 0x99, 0x04, 0x67, 0x37, 0xf3, 0x97, + 0x8d, 0x3e, 0xd8, 0x25, 0xcb, 0x97, 0xa4, 0xf1, 0x76, 0x5e, 0x54, 0xe7, + 0x8a, 0x43, 0xa9, 0xb1, 0x38, 0x94, 0x82, 0x32, 0x8b, 0x54, 0x8b, 0x8b, + 0xcb, 0x0c, 0x02, 0x32, 0x48, 0xe8, 0x94, 0xec, 0xcc, 0x8f, 0xa4, 0x0f, + 0xac, 0x3c, 0xd8, 0xb7, 0x2b, 0x10, 0x36, 0x26, 0x0d, 0xa9, 0x51, 0x9c, + 0xaf, 0xb6, 0x0b, 0x71, 0x2e, 0xc7, 0x8f, 0xc8, 0x16, 0xe4, 0x9b, 0x38, + 0xda, 0xa6, 0x36, 0xc9, 0x7b, 0x41, 0x66, 0x76, 0x90, 0x45, 0xf1, 0x16, + 0xf9, 0x62, 0x7c, 0xd9, 0xf2, 0xec, 0xed, 0x26, 0x0c, 0x96, 0x54, 0x71, + 0x26, 0xe4, 0x7d, 0x18, 0xa5, 0x64, 0xcb, 0x12, 0xe6, 0xf3, 0x6d, 0x4c, + 0x95, 0x52, 0xba, 0x7a, 0x86, 0x76, 0x97, 0x7b, 0x87, 0x72, 0xd3, 0x3c, + 0xd9, 0x27, 0x2f, 0x7e, 0xa6, 0x4b, 0x48, 0xaa, 0x22, 0xda, 0x6a, 0x8e, + 0x76, 0xc0, 0x74, 0x91, 0x79, 0x0b, 0xb7, 0xef, 0xc0, 0x3d, 0x9c, 0xa5, + 0x1f, 0x59, 0x30, 0xbc, 0xdd, 0xb0, 0x93, 0x53, 0xaa, 0x62, 0xf3, 0xd3, + 0x53, 0x30, 0x9d, 0x58, 0x9e, 0xb6, 0x20, 0x98, 0x79, 0xea, 0x5e, 0x65, + 0x31, 0x40, 0x20, 0x2d, 0x84, 0xe2, 0xc5, 0xfc, 0x70, 0x2c, 0x18, 0xa2, + 0xcf, 0xd5, 0x2f, 0x4e, 0x5b, 0x85, 0x27, 0x9c, 0x08, 0x17, 0xe7, 0x4e, + 0x49, 0x94, 0x2a, 0x6e, 0x7a, 0xbb, 0x29, 0xfa, 0x69, 0x94, 0xd2, 0x18, + 0xb0, 0x98, 0x24, 0xd1, 0x02, 0x41, 0x05, 0x71, 0xa7, 0x29, 0x62, 0x84, + 0xdf, 0x4e, 0xf7, 0x95, 0x18, 0xae, 0xcf, 0x6a, 0xc1, 0x6e, 0x65, 0x66, + 0x33, 0xbf, 0xa5, 0x6d, 0x78, 0x85, 0x3d, 0x68, 0xc1, 0x94, 0xea, 0x7c, + 0x8d, 0xf8, 0xee, 0x56, 0xd7, 0x64, 0x31, 0x85, 0x25, 0xef, 0xdd, 0xc3, + 0x5d, 0x90, 0x23, 0xfc, 0x77, 0x7b, 0xaf, 0xc4, 0xff, 0xea, 0xcc, 0x16, + 0x32, 0xd0, 0x82, 0xb6, 0xe1, 0xcf, 0xfb, 0xc2, 0x38, 0x01, 0x86, 0x4a, + 0x32, 0xc3, 0x6c, 0xab, 0x6a, 0xdc, 0x13, 0xe3, 0x52, 0xe1, 0x02, 0x8b, + 0xe3, 0x67, 0xc6, 0x8c, 0x75, 0x10, 0x6e, 0x13, 0x69, 0xa2, 0x7b, 0x80, + 0xaa, 0x34, 0xb2, 0x63, 0x42, 0x3f, 0x77, 0x01, 0xb0, 0xb2, 0xf1, 0x2e, + 0xfe, 0x74, 0x7d, 0x49, 0xbf, 0x48, 0x3d, 0x40, 0x95, 0xc8, 0x76, 0x92, + 0xb9, 0x3a, 0x84, 0x90, 0x9c, 0x29, 0x4c, 0xf9, 0x79, 0x9f, 0xdf, 0x54, + 0xfe, 0xd7, 0x0f, 0x3f, 0x2b, 0x37, 0x96, 0x5b, 0x3f, 0xb5, 0x94, 0x1b, + 0xcb, 0xad, 0x96, 0x72, 0x63, 0xb9, 0xed, 0xbe, 0xdd, 0x58, 0xe6, 0x5f, + 0xfd, 0x47, 0xdd, 0x58, 0x3e, 0x5e, 0xd1, 0x60, 0xa9, 0x38, 0x8b, 0x53, + 0x09, 0x7d, 0x7c, 0x31, 0xbc, 0x3a, 0x99, 0x9d, 0xf6, 0x07, 0xd3, 0xd1, + 0x18, 0x22, 0xf4, 0xed, 0x70, 0x3c, 0x42, 0xe8, 0x3c, 0xba, 0x1a, 0x22, + 0x64, 0x9e, 0x8c, 0x07, 0x94, 0xa3, 0x17, 0xa3, 0x31, 0x42, 0xea, 0xf3, + 0xab, 0x4f, 0xb3, 0x2a, 0x2c, 0x4c, 0xf1, 0x93, 0xc9, 0xb4, 0x04, 0x07, + 0xd3, 0x9c, 0xe1, 0xac, 0xc2, 0xc2, 0x84, 0x67, 0x73, 0xf7, 0x2f, 0xae, + 0x3f, 0xf6, 0x11, 0xda, 0xe7, 0xdf, 0xa9, 0xc3, 0x1e, 0x1a, 0xbf, 0x53, + 0x87, 0xeb, 0xd5, 0x7e, 0xa7, 0x0e, 0x7b, 0x04, 0xc2, 0x0e, 0x46, 0x57, + 0x95, 0x15, 0x39, 0x30, 0x73, 0x18, 0x5a, 0x10, 0x1c, 0xe6, 0x94, 0x00, + 0xd5, 0xbf, 0xc1, 0x31, 0x33, 0x0b, 0x04, 0x87, 0xf9, 0x55, 0xd0, 0x6b, + 0x36, 0xe9, 0x4f, 0x6f, 0xc6, 0x74, 0xb7, 0xc8, 0x11, 0x6d, 0x0b, 0xe1, + 0x15, 0xa9, 0x8f, 0xaa, 0xe8, 0x5e, 0x8e, 0x4e, 0x86, 0x90, 0xe0, 0xf6, + 0x4f, 0x4e, 0x10, 0xb9, 0x9d, 0xdc, 0x1c, 0x23, 0x72, 0x3b, 0x56, 0x41, + 0x60, 0x2a, 0x5c, 0x9e, 0x5f, 0x21, 0x82, 0x7a, 0xd9, 0xff, 0x82, 0x88, + 0xe8, 0xe5, 0x0d, 0xa6, 0x11, 0x26, 0x83, 0xf1, 0x70, 0x58, 0xb9, 0x4d, + 0x5f, 0x96, 0xb4, 0xfe, 0xf8, 0xbf, 0x15, 0x20, 0x58, 0x1c, 0x2f, 0xce, + 0xcf, 0x3e, 0x4e, 0x15, 0xa8, 0x5e, 0x2d, 0xe9, 0xf3, 0xdb, 0x24, 0xa3, + 0x8d, 0x4e, 0xfa, 0x09, 0x45, 0x31, 0x38, 0xbf, 0x98, 0x8d, 0xae, 0x77, + 0xd4, 0x19, 0xff, 0x3d, 0x1c, 0x5e, 0x63, 0xc4, 0x1f, 0x5e, 0x5f, 0xf4, + 0x07, 0x43, 0x54, 0x65, 0x0c, 0x50, 0x4d, 0x31, 0x1c, 0x58, 0x28, 0x89, + 0xe1, 0x78, 0x8a, 0x30, 0x81, 0x4e, 0xf5, 0x79, 0xdc, 0xbf, 0xc6, 0xb8, + 0x30, 0xd4, 0xa1, 0xde, 0x5a, 0x49, 0x7c, 0x9f, 0x56, 0x12, 0x20, 0x65, + 0x66, 0xd3, 0x53, 0xb9, 0x70, 0x18, 0x90, 0x53, 0x47, 0x83, 0x33, 0x6d, + 0x94, 0x8c, 0x42, 0x1a, 0x2c, 0xac, 0xbb, 0x25, 0x95, 0x34, 0x60, 0x58, + 0x79, 0x17, 0x94, 0x52, 0x61, 0x5d, 0x98, 0x95, 0x3a, 0xb5, 0xb4, 0x01, + 0x30, 0x5f, 0x55, 0x8a, 0x69, 0xe0, 0x6e, 0xad, 0x18, 0x4e, 0x2f, 0x6f, + 0xc8, 0x69, 0xb0, 0xe2, 0xb9, 0x6d, 0x55, 0x0e, 0xe9, 0xef, 0x67, 0xa7, + 0xe7, 0x17, 0xdc, 0xb3, 0x29, 0xbc, 0x39, 0x79, 0xa5, 0x80, 0xc5, 0x07, + 0x57, 0x14, 0x81, 0x28, 0x44, 0x5a, 0x07, 0x1b, 0x56, 0x5b, 0x4d, 0x91, + 0xfc, 0xc8, 0xcb, 0x28, 0x8a, 0x9f, 0xbd, 0xfb, 0xec, 0x67, 0x19, 0x37, + 0x94, 0x54, 0xe8, 0x8c, 0x52, 0x70, 0x76, 0x49, 0x57, 0x78, 0x45, 0x9d, + 0x89, 0xd9, 0x65, 0xff, 0x8c, 0xfd, 0x02, 0x11, 0x73, 0x70, 0xd8, 0xd5, + 0xb0, 0x3f, 0x46, 0x44, 0x9f, 0x8d, 0x63, 0x60, 0xe6, 0xf9, 0x8c, 0x9a, + 0x1e, 0x18, 0xa7, 0x4d, 0xd8, 0x92, 0x21, 0xac, 0x79, 0x24, 0xff, 0xa1, + 0x34, 0xa3, 0xc1, 0x2e, 0x80, 0xe3, 0xb4, 0x19, 0xe1, 0x7d, 0xa3, 0x0d, + 0xe4, 0x34, 0x2a, 0xcd, 0x07, 0x6f, 0x0d, 0x70, 0x98, 0x36, 0xdd, 0xa1, + 0x79, 0x81, 0x05, 0x2b, 0xa0, 0xf5, 0xc1, 0xdb, 0x06, 0x1c, 0xa6, 0xcd, + 0x07, 0xef, 0x20, 0x75, 0x1c, 0xb4, 0x3a, 0x83, 0x2b, 0x04, 0x0d, 0xd3, + 0xe5, 0xc5, 0x81, 0x97, 0xd7, 0xbf, 0x3a, 0x9f, 0x8c, 0xa6, 0xe3, 0xd1, + 0xf5, 0xf9, 0x60, 0xe6, 0xce, 0x1c, 0xcc, 0x31, 0x52, 0xc1, 0xdb, 0x2a, + 0x38, 0xac, 0x39, 0x55, 0xf0, 0x9e, 0x0a, 0x0e, 0x0b, 0x85, 0x0a, 0xee, + 0x74, 0x55, 0xf8, 0x4e, 0xbd, 0x17, 0x45, 0xe3, 0xbf, 0xe2, 0xc8, 0x07, + 0x70, 0xa6, 0x46, 0xe3, 0x93, 0xe1, 0x38, 0x77, 0x12, 0x8b, 0x30, 0xae, + 0xed, 0x40, 0x66, 0xe8, 0x80, 0xfe, 0x87, 0xec, 0x4e, 0x0a, 0xe1, 0x20, + 0x1b, 0xd1, 0x71, 0x1c, 0x07, 0xd9, 0x73, 0xa7, 0xd1, 0x6a, 0x15, 0x3d, + 0x26, 0x96, 0xc6, 0xf4, 0x73, 0xec, 0x6d, 0x80, 0xa5, 0x31, 0x73, 0x2c, + 0xdc, 0x44, 0x60, 0x5d, 0xa5, 0x09, 0x39, 0x0a, 0x76, 0x2a, 0x4b, 0xa8, + 0xfb, 0x41, 0x43, 0x3a, 0xf4, 0xfc, 0x4a, 0x0e, 0x18, 0x5c, 0xf4, 0x2f, + 0x01, 0x9f, 0xc6, 0x08, 0x7f, 0x79, 0x3e, 0x1e, 0x43, 0x11, 0x91, 0x71, + 0x80, 0x60, 0x11, 0x7a, 0x71, 0xb0, 0x3c, 0xc3, 0x6c, 0x74, 0xa5, 0x78, + 0x51, 0xf5, 0xae, 0x36, 0xb3, 0x03, 0x65, 0x5f, 0x8f, 0xd9, 0x00, 0xe6, + 0x27, 0x20, 0x32, 0xc1, 0xbb, 0xbe, 0x10, 0xea, 0x75, 0xff, 0x28, 0x2a, + 0xd3, 0xaf, 0x29, 0x0a, 0x3f, 0x65, 0x2d, 0x8a, 0x6a, 0xe5, 0x44, 0x0c, + 0xa3, 0x7e, 0x76, 0x36, 0x8c, 0x5f, 0xc7, 0x40, 0x04, 0x47, 0x8c, 0xf9, + 0x32, 0xf8, 0x78, 0x96, 0x0d, 0xca, 0x9a, 0x3f, 0xd5, 0x8a, 0x92, 0x18, + 0x34, 0xb8, 0xbc, 0x36, 0x8e, 0x83, 0xb7, 0xa7, 0x18, 0x77, 0x43, 0x95, + 0xc7, 0x8f, 0xa2, 0xd9, 0xcb, 0x85, 0x53, 0xfa, 0x48, 0x78, 0x9f, 0xe6, + 0xe3, 0x14, 0xef, 0x1f, 0x56, 0xd6, 0x19, 0x05, 0x2e, 0x51, 0xf5, 0x9c, + 0x03, 0x2a, 0x18, 0x61, 0xd7, 0x25, 0x63, 0xc5, 0x55, 0xce, 0x0a, 0xea, + 0xb8, 0x22, 0x9a, 0x58, 0x8c, 0x18, 0x8d, 0xb3, 0x01, 0xd4, 0x87, 0x45, + 0x54, 0x70, 0xc6, 0x82, 0x62, 0xc4, 0xd5, 0x68, 0x8a, 0xa9, 0xdf, 0xb1, + 0x7f, 0xbf, 0x5d, 0xa9, 0xbc, 0xad, 0xd7, 0x57, 0xd9, 0x91, 0x87, 0xa8, + 0x62, 0x27, 0x7d, 0x20, 0x47, 0xf4, 0xa9, 0x3f, 0xfe, 0x7a, 0x7e, 0x75, + 0x36, 0x3b, 0xbd, 0xe8, 0x9f, 0x4d, 0x66, 0xfd, 0xc1, 0xf4, 0x7c, 0x74, + 0x05, 0x49, 0xe6, 0x36, 0x9c, 0x3f, 0x78, 0xe1, 0x3d, 0x74, 0x18, 0xad, + 0xc1, 0xfd, 0xe6, 0xc7, 0x11, 0x74, 0x55, 0x5c, 0x03, 0xe2, 0xe9, 0x32, + 0x5d, 0xd0, 0x0c, 0x0b, 0x28, 0x95, 0x1b, 0xa8, 0x5f, 0x7e, 0x39, 0xbc, + 0x1c, 0x8d, 0xbf, 0xce, 0x4e, 0x47, 0xe3, 0x4b, 0xaa, 0x62, 0x20, 0x5a, + 0x19, 0xea, 0x0c, 0x2a, 0x17, 0xf4, 0xbc, 0x38, 0xe5, 0x6d, 0x9b, 0x6a, + 0xbf, 0xf9, 0xe6, 0x78, 0x6f, 0xc5, 0x61, 0xc9, 0x7b, 0x87, 0xdc, 0x9c, + 0x9f, 0x12, 0x51, 0x9c, 0xf5, 0x18, 0x2c, 0xfc, 0x0f, 0xc8, 0xae, 0x51, + 0x86, 0xba, 0x72, 0x68, 0x52, 0x1a, 0x0b, 0xef, 0x1c, 0x06, 0xfe, 0xfe, + 0x2a, 0x62, 0x52, 0xf2, 0x01, 0xd9, 0x2c, 0x1c, 0x54, 0x83, 0xab, 0x17, + 0x8e, 0x52, 0x41, 0x84, 0x4a, 0x5b, 0x2a, 0xbb, 0xe7, 0x94, 0xaa, 0x43, + 0x63, 0x62, 0x20, 0x31, 0x5e, 0xba, 0xd7, 0xc0, 0xda, 0xc0, 0x3d, 0x4e, + 0x0d, 0xc0, 0xa3, 0xba, 0x40, 0xe0, 0x4a, 0xca, 0x84, 0x30, 0x7c, 0xf5, + 0x79, 0x48, 0x99, 0x1a, 0x7a, 0xab, 0xec, 0xd6, 0x8e, 0xfa, 0xd5, 0x34, + 0x78, 0x19, 0x8e, 0xaf, 0xfa, 0x17, 0xb3, 0xe9, 0xd7, 0x6b, 0xf0, 0xab, + 0x7b, 0x01, 0xf2, 0xbd, 0xbd, 0x6d, 0x80, 0x7c, 0x30, 0x50, 0xb4, 0x57, + 0xba, 0xc3, 0x1a, 0x20, 0x6c, 0x72, 0xba, 0xca, 0x24, 0xb0, 0x36, 0x73, + 0xba, 0x4b, 0x44, 0x8d, 0xb5, 0xdc, 0x00, 0xd1, 0x46, 0x2d, 0x57, 0x99, + 0x06, 0xd6, 0x3f, 0x2d, 0x77, 0x59, 0xd1, 0x37, 0x18, 0xd5, 0x8f, 0xaf, + 0xaf, 0x0d, 0x44, 0x67, 0x7f, 0x01, 0x27, 0x41, 0x68, 0x0e, 0x95, 0x4d, + 0xea, 0xd4, 0xa8, 0x56, 0x4a, 0x62, 0x5f, 0x29, 0x6e, 0x4f, 0xec, 0x20, + 0x21, 0x0b, 0x36, 0x70, 0xa6, 0x12, 0x06, 0xfe, 0x68, 0x01, 0xe7, 0x62, + 0x9f, 0x2e, 0xc0, 0xaa, 0x2d, 0x24, 0x0c, 0xdf, 0x2f, 0x6a, 0xe4, 0xc8, + 0xd4, 0x8b, 0xef, 0xfd, 0x94, 0x1a, 0x48, 0x6f, 0x5d, 0x72, 0x23, 0xc6, + 0xc3, 0x2b, 0xe6, 0x60, 0x4e, 0xfb, 0xe3, 0xb3, 0xe1, 0x74, 0x96, 0x39, + 0x4b, 0x88, 0x4f, 0x11, 0x96, 0x5b, 0x33, 0x88, 0x90, 0x33, 0x8c, 0xc8, + 0x9c, 0x4d, 0xc0, 0xcc, 0x03, 0x18, 0x51, 0x86, 0x54, 0xe7, 0x6a, 0xcb, + 0x13, 0xe3, 0xfe, 0xef, 0xc1, 0x8f, 0xce, 0xff, 0x23, 0x4b, 0xea, 0xff, + 0x2e, 0x9d, 0x2e, 0x3c, 0x72, 0x13, 0x25, 0xda, 0x82, 0x8b, 0x81, 0xf5, + 0xc3, 0xd8, 0x21, 0x89, 0xd4, 0x01, 0xca, 0xb2, 0x24, 0x0e, 0xfe, 0xc5, + 0xac, 0xe2, 0x9b, 0xc2, 0xfa, 0xf7, 0xac, 0xd6, 0x62, 0xfa, 0xcf, 0x84, + 0xc4, 0xcc, 0x30, 0x65, 0x38, 0x0d, 0x94, 0x1d, 0x6d, 0xd3, 0xcd, 0x36, + 0x25, 0xe7, 0x6b, 0x56, 0x46, 0x07, 0x59, 0x93, 0xd1, 0xcd, 0xf4, 0xfa, + 0x66, 0x3a, 0xa3, 0x5a, 0xef, 0x6c, 0x58, 0xb2, 0x29, 0x74, 0xe2, 0x1f, + 0xfe, 0x21, 0xc6, 0xd0, 0x18, 0x7d, 0xb3, 0x61, 0x8a, 0xfc, 0x31, 0xa0, + 0xf2, 0x95, 0x3e, 0xf8, 0x41, 0x4c, 0x98, 0x5d, 0x0c, 0xfd, 0x55, 0xc2, + 0x67, 0x5a, 0x88, 0x26, 0x8b, 0xec, 0x94, 0x8f, 0xfa, 0xdc, 0xe2, 0xd6, + 0x50, 0x1a, 0xfd, 0xf0, 0x0f, 0xf6, 0x8b, 0x87, 0xe0, 0xfe, 0x81, 0xff, + 0xe6, 0x27, 0x8e, 0x17, 0xa4, 0x41, 0x12, 0xdf, 0xdf, 0xf5, 0x66, 0xde, + 0x6a, 0xf3, 0xe0, 0x01, 0xfd, 0x59, 0x2a, 0xa0, 0x88, 0xf8, 0x51, 0x08, + 0xe7, 0x60, 0xe6, 0xa9, 0x9a, 0x00, 0xd6, 0x5a, 0x39, 0x20, 0x62, 0x8c, + 0xbc, 0xbb, 0xfb, 0xd8, 0xe9, 0x74, 0x3a, 0x88, 0x86, 0xe3, 0x9f, 0xbf, + 0xb7, 0xf6, 0x92, 0x5f, 0x29, 0x3d, 0x2a, 0x63, 0x60, 0x95, 0xc7, 0xc0, + 0xda, 0xf4, 0x3f, 0x44, 0xef, 0x89, 0xf2, 0x34, 0xc4, 0x75, 0x8b, 0x1d, + 0x67, 0x39, 0xbb, 0x67, 0xff, 0x43, 0x57, 0xb5, 0x44, 0xf4, 0x24, 0x2b, + 0x95, 0xe3, 0xfb, 0xbd, 0x5e, 0x57, 0xc6, 0xf7, 0x02, 0x88, 0x94, 0x15, + 0x66, 0x19, 0x2e, 0x07, 0x43, 0xce, 0x08, 0xc4, 0xb4, 0x81, 0x9c, 0xd6, + 0x10, 0x07, 0xb3, 0x79, 0x03, 0x6d, 0x5e, 0x98, 0x35, 0x71, 0x0e, 0x86, + 0x44, 0xbe, 0x62, 0x5e, 0xd5, 0xcc, 0xc1, 0xfc, 0x60, 0xf3, 0x6e, 0x39, + 0xc6, 0x1c, 0x0e, 0x66, 0x48, 0x9c, 0x83, 0x21, 0x99, 0x40, 0x36, 0x2f, + 0x37, 0x6b, 0x48, 0x16, 0x30, 0xbe, 0x17, 0x50, 0x12, 0xce, 0xc0, 0x8f, + 0x1c, 0x0c, 0x49, 0xfe, 0x89, 0x79, 0x15, 0x3a, 0x1b, 0x72, 0x7e, 0x6c, + 0x5e, 0x6d, 0x1d, 0xae, 0x81, 0x1f, 0x39, 0x58, 0x01, 0x67, 0xe0, 0x07, + 0x9f, 0x57, 0xdd, 0x78, 0x26, 0x7e, 0x08, 0x28, 0x89, 0xcf, 0xc0, 0x8f, + 0x1c, 0xac, 0x80, 0x33, 0xf0, 0x83, 0x55, 0x7e, 0x6a, 0x70, 0x46, 0x7e, + 0xf4, 0xf4, 0x75, 0x98, 0xf8, 0x91, 0x81, 0x15, 0x70, 0x06, 0x7e, 0xe4, + 0x60, 0x85, 0x06, 0x31, 0xf3, 0xa3, 0xa7, 0xae, 0xb7, 0x65, 0xe2, 0x47, + 0x4f, 0xa7, 0x73, 0xcb, 0xc0, 0x8f, 0x1c, 0xac, 0x80, 0x33, 0xf3, 0x83, + 0x7b, 0x77, 0x05, 0x9c, 0x89, 0x1f, 0x3d, 0x9d, 0xce, 0x2d, 0x03, 0x3f, + 0x72, 0xb0, 0x02, 0x0e, 0xe6, 0x07, 0xd3, 0xd2, 0x4f, 0x3d, 0x75, 0xbd, + 0x87, 0x7a, 0x16, 0xd8, 0xf0, 0xb1, 0x4f, 0x1a, 0x13, 0x5b, 0x3d, 0x7c, + 0xd0, 0x5d, 0x92, 0xce, 0xf5, 0x2f, 0x3a, 0xd2, 0x7d, 0x03, 0xd0, 0x41, + 0x29, 0xab, 0x2b, 0xd6, 0xac, 0x06, 0x1d, 0xc4, 0xfc, 0x1e, 0x6d, 0x90, + 0x63, 0x31, 0x88, 0x79, 0x41, 0xda, 0x20, 0xd7, 0x6a, 0xa6, 0x44, 0x23, + 0x44, 0xbb, 0x85, 0x0f, 0x4a, 0xca, 0xa2, 0xc8, 0xac, 0x4a, 0x65, 0x90, + 0xc1, 0x51, 0xb8, 0xdd, 0x9f, 0x90, 0x5d, 0x9c, 0x85, 0x19, 0x6b, 0x9d, + 0x01, 0x64, 0xf7, 0xab, 0xde, 0xe0, 0x3c, 0x5a, 0x6f, 0xa8, 0x4b, 0x16, + 0xa6, 0xb6, 0x5e, 0x66, 0x31, 0xa0, 0xe4, 0x6e, 0x0a, 0x97, 0x88, 0xc3, + 0x30, 0x67, 0xe3, 0x47, 0xb2, 0xf1, 0x16, 0xc2, 0xc9, 0x00, 0x5d, 0x8b, + 0x12, 0x32, 0xb0, 0xaf, 0x59, 0x05, 0xde, 0x6d, 0xcf, 0xb2, 0x6e, 0x5c, + 0x3d, 0xcd, 0x37, 0xc8, 0xca, 0x9a, 0xb2, 0x93, 0x4d, 0x3e, 0xbb, 0xf8, + 0x10, 0x65, 0x7e, 0x53, 0xd8, 0xc9, 0xeb, 0xca, 0xa1, 0xa0, 0xf3, 0x7c, + 0xfa, 0x91, 0x3a, 0xb7, 0xa6, 0x90, 0x13, 0x6e, 0x31, 0xa6, 0x47, 0xfc, + 0x67, 0xd8, 0x61, 0x74, 0x1f, 0x59, 0x34, 0xc5, 0xd0, 0x2f, 0x3b, 0x41, + 0x40, 0xbf, 0xf5, 0xbc, 0xc7, 0x7a, 0x36, 0x8a, 0x37, 0x5e, 0x17, 0xb0, + 0x1a, 0x80, 0x93, 0x03, 0xb0, 0xc6, 0xeb, 0xc0, 0xdf, 0xdb, 0xf9, 0xdf, + 0x45, 0x0e, 0x0d, 0x80, 0xe8, 0x68, 0x10, 0x4a, 0xc7, 0x75, 0x00, 0xb6, + 0x9b, 0xc3, 0x4e, 0x58, 0xfd, 0x91, 0xde, 0x6a, 0x1d, 0x00, 0xa7, 0x7a, + 0x28, 0x79, 0x88, 0xe2, 0x34, 0x77, 0xbe, 0xe7, 0xf1, 0x2c, 0x91, 0x5d, + 0xd3, 0xf3, 0x80, 0xaa, 0xda, 0x7e, 0x1d, 0x40, 0xd5, 0xd3, 0x50, 0x3d, + 0x7a, 0x41, 0x5a, 0x45, 0x55, 0xed, 0xcc, 0x0e, 0x20, 0x3a, 0xaa, 0x22, + 0xa2, 0x12, 0xf2, 0x6d, 0xb6, 0x14, 0x6d, 0x84, 0x15, 0x4c, 0x2c, 0x92, + 0x60, 0x7f, 0x0a, 0xa2, 0x6d, 0x22, 0x1a, 0x4b, 0x82, 0x0c, 0x38, 0xd0, + 0x10, 0x8a, 0x96, 0x2c, 0xb3, 0xdf, 0x66, 0x51, 0xb8, 0x7a, 0xce, 0xd1, + 0x65, 0x15, 0xce, 0xb7, 0x7b, 0xec, 0x97, 0xa4, 0xb8, 0x10, 0x01, 0x76, + 0x32, 0xcf, 0xcb, 0xea, 0x35, 0xac, 0xd9, 0xa5, 0xa1, 0x12, 0xda, 0xa2, + 0x9b, 0x64, 0x03, 0xbc, 0x6e, 0xe9, 0x6b, 0x17, 0x95, 0x4f, 0x5d, 0xb0, + 0x82, 0xba, 0x32, 0x4a, 0x56, 0xed, 0x6d, 0x26, 0x41, 0xab, 0x82, 0x54, + 0x0c, 0x2c, 0x21, 0x95, 0x1f, 0xb8, 0x0f, 0x88, 0x3a, 0xbb, 0x16, 0x58, + 0xe6, 0x4c, 0x4a, 0xe3, 0xae, 0x84, 0x95, 0x26, 0xce, 0x96, 0xbe, 0xbf, + 0xb8, 0xa3, 0xe0, 0x15, 0x0e, 0x15, 0x20, 0x44, 0x82, 0x18, 0xab, 0xf8, + 0xc5, 0xcd, 0xcd, 0x79, 0xb4, 0x0d, 0x81, 0x62, 0x3a, 0xdb, 0x5b, 0x04, + 0xd9, 0xe7, 0x76, 0xb4, 0xcf, 0xbd, 0xe3, 0x9d, 0xf7, 0x67, 0xc9, 0xf6, + 0x6e, 0xe6, 0x6d, 0xd3, 0x88, 0x46, 0x6c, 0x41, 0x98, 0x7f, 0xab, 0xec, + 0xca, 0xcf, 0xfe, 0xb4, 0xc7, 0xff, 0xc6, 0x1a, 0x4c, 0xe5, 0x6d, 0xf2, + 0x81, 0x0f, 0xb5, 0xb8, 0x18, 0x87, 0xdf, 0xdc, 0x28, 0xde, 0x1c, 0xd0, + 0xbe, 0xe3, 0x7b, 0x4f, 0x77, 0x68, 0xa0, 0x4b, 0x95, 0x1a, 0x93, 0xdf, + 0x89, 0x00, 0xba, 0xee, 0x88, 0xf9, 0x4b, 0x05, 0xf9, 0xd7, 0x80, 0xef, + 0x16, 0x40, 0x32, 0xae, 0xeb, 0x0d, 0xde, 0x75, 0x7a, 0xf6, 0x6d, 0xbe, + 0x98, 0xcd, 0xbd, 0xf9, 0x83, 0xaf, 0xab, 0xd0, 0x4f, 0x83, 0x13, 0x22, + 0x7e, 0x0d, 0xc9, 0xb9, 0xab, 0x2b, 0x8c, 0x7b, 0xd6, 0xf4, 0x36, 0x98, + 0xcf, 0x58, 0x7e, 0x78, 0x26, 0x5e, 0x4d, 0x50, 0x55, 0xac, 0xd2, 0xa8, + 0xf1, 0x4c, 0x40, 0x0a, 0xad, 0x7b, 0x61, 0xa0, 0x1b, 0x27, 0x92, 0x35, + 0xd5, 0x4a, 0x83, 0xe9, 0xfe, 0xac, 0xbd, 0xdf, 0x62, 0x4b, 0x71, 0xd7, + 0x81, 0x64, 0x20, 0x58, 0x6f, 0x56, 0xc1, 0x9c, 0xed, 0x6a, 0x9e, 0x0a, + 0x2f, 0x4b, 0xc3, 0x79, 0xf6, 0xe7, 0xfa, 0xf5, 0xf1, 0xd6, 0xbe, 0x8c, + 0x4c, 0xbc, 0xe0, 0x39, 0x7c, 0xe1, 0x85, 0xa0, 0xec, 0x73, 0x5d, 0xe8, + 0x73, 0xfd, 0xa7, 0xec, 0x73, 0x93, 0xed, 0xc6, 0x8f, 0xe1, 0x6f, 0x1e, + 0x66, 0x30, 0x54, 0x94, 0x73, 0x18, 0xe0, 0x9b, 0xfb, 0x77, 0xfc, 0xd9, + 0x01, 0xad, 0x51, 0x71, 0x8e, 0x9d, 0x14, 0xd8, 0x33, 0xf5, 0x48, 0x56, + 0x70, 0x1f, 0x4e, 0xd7, 0xea, 0x9d, 0x01, 0x00, 0xad, 0x89, 0x46, 0x16, + 0x7d, 0x4a, 0xe2, 0xe8, 0xd1, 0x38, 0x1c, 0xbf, 0xb9, 0x35, 0x17, 0x97, + 0xb6, 0x5e, 0x89, 0x47, 0xba, 0x8d, 0x29, 0x96, 0x37, 0xe3, 0x6d, 0x45, + 0x92, 0x62, 0xd3, 0x14, 0xcb, 0x56, 0xef, 0xaa, 0xd5, 0x2e, 0x8d, 0x5f, + 0x64, 0xca, 0x87, 0x01, 0x37, 0x05, 0x1a, 0x2e, 0x14, 0x43, 0xd7, 0x70, + 0xd9, 0xba, 0x51, 0xe4, 0x3d, 0xee, 0x99, 0x32, 0x15, 0x07, 0x1a, 0x52, + 0x55, 0xc8, 0x77, 0x4f, 0x26, 0x16, 0x2f, 0xa9, 0x88, 0x86, 0x81, 0xa5, + 0x68, 0xaf, 0x3a, 0x77, 0xa7, 0x6e, 0xee, 0x19, 0x6b, 0xa0, 0xb9, 0xc3, + 0xf4, 0xe4, 0xbd, 0x9f, 0x75, 0x58, 0xfc, 0x00, 0x7e, 0x09, 0x40, 0x5f, + 0xfc, 0x75, 0x90, 0x26, 0xdc, 0xca, 0x9d, 0x31, 0xd3, 0xfb, 0x22, 0x16, + 0x3d, 0xfc, 0x04, 0x86, 0xbc, 0xe8, 0xd2, 0x80, 0x07, 0xbe, 0x1c, 0xce, + 0x62, 0x1a, 0x76, 0x69, 0xb5, 0x43, 0xb6, 0x21, 0xbf, 0x08, 0x03, 0xb7, + 0x78, 0x02, 0xba, 0x7a, 0xbf, 0x4f, 0x3e, 0xc8, 0xc7, 0x0e, 0x0c, 0x73, + 0xda, 0xbf, 0xa1, 0x60, 0x7a, 0xa2, 0xc1, 0x80, 0xd8, 0xfe, 0x79, 0x99, + 0x5b, 0x5b, 0x94, 0xf6, 0xef, 0xcc, 0x2c, 0xd9, 0x73, 0x1f, 0xd1, 0x86, + 0xb5, 0x65, 0xd9, 0x86, 0x54, 0x3b, 0x52, 0x1b, 0xc8, 0x71, 0x92, 0x68, + 0xcb, 0x9b, 0xde, 0xac, 0x95, 0x0b, 0xbc, 0x86, 0x2e, 0x28, 0xe8, 0x5c, + 0x36, 0x4f, 0x8a, 0xd8, 0x76, 0x84, 0x03, 0xb7, 0xcf, 0x5c, 0xd4, 0x22, + 0x88, 0x7f, 0x88, 0x66, 0x96, 0xca, 0x5d, 0x66, 0xd9, 0xc6, 0x13, 0x38, + 0x6a, 0x01, 0x9a, 0x68, 0x96, 0x9e, 0x91, 0xd9, 0x65, 0xc5, 0x02, 0x93, + 0xc7, 0x9f, 0xc5, 0x51, 0xce, 0x84, 0x80, 0x7e, 0x7d, 0x0d, 0xd7, 0xdd, + 0xd5, 0xd6, 0x2d, 0x7a, 0xd1, 0xe7, 0xce, 0xd6, 0xaa, 0xe8, 0xf9, 0x8f, + 0xaa, 0x24, 0x5b, 0x45, 0xa0, 0x36, 0xbb, 0xdf, 0x49, 0x0f, 0xc0, 0xdd, + 0xf2, 0x1b, 0xab, 0x01, 0x18, 0x0d, 0xa0, 0x05, 0xec, 0x69, 0xc7, 0x22, + 0x29, 0x86, 0x36, 0x29, 0x05, 0x52, 0x17, 0xe2, 0x77, 0x80, 0xc4, 0x80, + 0x7a, 0xfc, 0xb0, 0x82, 0x54, 0xf5, 0x66, 0x32, 0x9c, 0x9c, 0x29, 0x97, + 0x5e, 0xfc, 0xab, 0x64, 0x07, 0x88, 0xec, 0x08, 0x30, 0x0a, 0xf7, 0xf9, + 0xc3, 0x0d, 0xaa, 0x3d, 0x80, 0x5f, 0x76, 0xb0, 0xe2, 0x73, 0xb9, 0x7f, + 0xaf, 0xec, 0xf3, 0x6a, 0xe7, 0x05, 0x5d, 0xd3, 0x3f, 0x52, 0xd5, 0xfa, + 0x20, 0xae, 0xe3, 0xd3, 0xc5, 0x45, 0x22, 0xdd, 0x16, 0xf0, 0x74, 0x1b, + 0xd5, 0x18, 0xb2, 0x42, 0xa2, 0xe0, 0x98, 0xd2, 0xf5, 0x14, 0x6e, 0x51, + 0xaa, 0x4e, 0xf0, 0x65, 0x34, 0x66, 0x38, 0x80, 0x6d, 0x87, 0xdf, 0xa5, + 0xb6, 0xd1, 0x34, 0xf6, 0x2f, 0x49, 0x34, 0xb5, 0x10, 0xf6, 0x2f, 0x4a, + 0x34, 0xb4, 0x10, 0xf6, 0xcf, 0x0f, 0x59, 0x5b, 0x08, 0xbc, 0x75, 0xc3, + 0xd8, 0x7b, 0x34, 0x74, 0x2c, 0xc1, 0x2d, 0xa1, 0xe1, 0x4d, 0x82, 0x46, + 0x7d, 0xba, 0x33, 0xcd, 0x99, 0x8a, 0xd3, 0x74, 0xfc, 0x7d, 0x08, 0x1d, + 0x1e, 0x28, 0xbc, 0xac, 0x85, 0x77, 0xab, 0x99, 0xc5, 0x5a, 0xf8, 0x16, + 0x5a, 0x83, 0xa8, 0x25, 0x3c, 0x7b, 0x06, 0x20, 0xf9, 0x06, 0xc2, 0x91, + 0x01, 0x62, 0x52, 0x7a, 0x4d, 0xc1, 0x31, 0xad, 0xff, 0xf6, 0x7f, 0x57, + 0x40, 0xa1, 0x6e, 0xfc, 0x75, 0x1a, 0x12, 0xd0, 0x3f, 0x0d, 0xf4, 0x4e, + 0xbd, 0x71, 0xb5, 0xe9, 0x99, 0xa4, 0xe8, 0x1d, 0xe9, 0xd1, 0x71, 0x4f, + 0x8e, 0x65, 0xa3, 0x9e, 0xc9, 0x92, 0xf5, 0x76, 0x04, 0x9d, 0x3a, 0xd1, + 0x1d, 0x04, 0xb8, 0xee, 0x5c, 0x6d, 0x0a, 0x22, 0x31, 0x3f, 0x14, 0xad, + 0xfd, 0xb6, 0x77, 0x7c, 0x06, 0xaa, 0x76, 0x7e, 0x24, 0x77, 0xcf, 0xd4, + 0xfb, 0x49, 0xf8, 0x95, 0x55, 0xfe, 0xcb, 0x98, 0xd7, 0xa1, 0xd5, 0x4d, + 0xcb, 0xb5, 0xde, 0x31, 0x89, 0x58, 0x13, 0x70, 0xf5, 0xa6, 0x2b, 0xcf, + 0x46, 0xe4, 0x17, 0x8c, 0xf1, 0x5b, 0xde, 0xe3, 0xfd, 0x63, 0x92, 0x3c, + 0x7a, 0xc0, 0x13, 0x5b, 0x2e, 0xae, 0xf9, 0x06, 0xa2, 0x8c, 0x21, 0x6f, + 0xeb, 0x0b, 0x68, 0x4f, 0xfc, 0xcd, 0x36, 0xe1, 0xb5, 0x64, 0x0a, 0xe4, + 0xce, 0x67, 0xa9, 0x49, 0x2e, 0x03, 0xbb, 0xbd, 0xc7, 0x03, 0x1e, 0xc3, + 0x08, 0x3c, 0x6a, 0x07, 0x82, 0x1c, 0x0f, 0x04, 0x0e, 0x92, 0xa9, 0xa8, + 0x7b, 0x53, 0xdd, 0x51, 0x17, 0xb0, 0x12, 0x7a, 0x81, 0x1c, 0x8c, 0x4b, + 0x3d, 0xcc, 0x28, 0x63, 0x2a, 0x96, 0xa8, 0x42, 0x81, 0x68, 0x4e, 0x99, + 0x5c, 0x7e, 0xb5, 0x30, 0x08, 0xd5, 0xa1, 0x60, 0x43, 0xa6, 0x56, 0x55, + 0xd5, 0xea, 0x70, 0x6f, 0x3a, 0xf7, 0xef, 0xa2, 0x73, 0x5b, 0x7a, 0xc6, + 0x92, 0x79, 0xa4, 0x65, 0x97, 0xaf, 0xe6, 0x2d, 0xaf, 0x37, 0x8f, 0xef, + 0x75, 0xbc, 0x94, 0x0b, 0x25, 0xbe, 0x78, 0xdb, 0x30, 0x7f, 0xb5, 0x0d, + 0x63, 0xbf, 0x51, 0xde, 0x5c, 0x94, 0xbf, 0x96, 0x8b, 0x52, 0x45, 0x72, + 0x1e, 0xfe, 0xe9, 0x9d, 0x8a, 0x3f, 0x99, 0x37, 0xf0, 0xa6, 0xdb, 0xfe, + 0x3a, 0xba, 0x4d, 0x3f, 0xdb, 0x4b, 0x97, 0xb3, 0x45, 0xec, 0x3d, 0xce, + 0x96, 0xec, 0xe4, 0x73, 0xe6, 0x85, 0x8b, 0x59, 0x76, 0xba, 0x2e, 0xfe, + 0x3c, 0x2d, 0x4e, 0xe7, 0x4f, 0xb3, 0xd3, 0x79, 0x71, 0x99, 0x8b, 0xb7, + 0xfa, 0x1e, 0x70, 0x48, 0x28, 0xcb, 0xc4, 0xd4, 0x5a, 0xbe, 0x97, 0xe4, + 0xfb, 0x78, 0xf9, 0xd3, 0x78, 0xfc, 0x74, 0x1f, 0xf3, 0x28, 0xf2, 0x2e, + 0xed, 0x81, 0xe1, 0x91, 0x3c, 0x9b, 0xfe, 0xbc, 0x59, 0x86, 0x4f, 0x3e, + 0xe8, 0x35, 0xf6, 0xf9, 0x68, 0x20, 0x47, 0xca, 0x3a, 0xeb, 0xa3, 0x8d, + 0x26, 0xb3, 0xce, 0xf3, 0xfa, 0x27, 0x41, 0xbd, 0x51, 0x5f, 0xf5, 0xdd, + 0xbe, 0xda, 0x97, 0xb4, 0xad, 0x5f, 0x85, 0x83, 0xd4, 0x5c, 0xf9, 0xed, + 0x3e, 0xd3, 0xbb, 0x39, 0xa0, 0x28, 0xca, 0xe1, 0xc4, 0xee, 0x19, 0x3f, + 0x65, 0x80, 0xe9, 0x45, 0x3f, 0xf3, 0x08, 0xf1, 0x96, 0x1b, 0x50, 0x9a, + 0x65, 0x6e, 0x35, 0xaa, 0xaa, 0xd9, 0x4e, 0x55, 0x29, 0xd9, 0x3c, 0x76, + 0xd7, 0x40, 0x9a, 0xeb, 0xcd, 0xbe, 0x58, 0x89, 0xfe, 0x30, 0x4f, 0xed, + 0xfb, 0x7f, 0x2f, 0x12, 0xe6, 0x16, 0x1e, 0x87, 0x97, 0x04, 0x07, 0x48, + 0x5d, 0xbe, 0x09, 0x8e, 0x6e, 0xf1, 0x77, 0x11, 0x9c, 0x76, 0x59, 0x70, + 0xce, 0x43, 0x8a, 0x2d, 0x9c, 0xef, 0xa2, 0x10, 0x9b, 0x28, 0xb3, 0x96, + 0x45, 0xd7, 0x5c, 0x44, 0x99, 0xd9, 0xe8, 0x57, 0x7b, 0x6d, 0x26, 0x55, + 0xa3, 0x5d, 0x43, 0xb8, 0x9c, 0x4e, 0x60, 0xe3, 0x4c, 0xfc, 0x11, 0xc0, + 0x7c, 0x38, 0x79, 0xd3, 0x8f, 0xbf, 0x87, 0x7e, 0x6c, 0x26, 0xe6, 0x2f, + 0xd2, 0x94, 0x16, 0x36, 0xf6, 0xd5, 0xa4, 0xe8, 0x75, 0x35, 0xae, 0x49, + 0x26, 0xdf, 0x54, 0xef, 0x77, 0x51, 0xbd, 0x45, 0xd5, 0x64, 0xe5, 0xe1, + 0xde, 0xa4, 0xa6, 0xc0, 0xf4, 0x0f, 0x79, 0xb0, 0xb7, 0x9e, 0x0c, 0x40, + 0xe9, 0x51, 0x03, 0x32, 0xf4, 0x40, 0x32, 0xe8, 0xfb, 0xf3, 0x35, 0x08, + 0xf2, 0x7b, 0xee, 0xcb, 0x57, 0xd1, 0xee, 0xaf, 0x46, 0x62, 0x76, 0xdf, + 0x24, 0x8b, 0x87, 0xbd, 0xc4, 0xcf, 0x28, 0x44, 0xf8, 0xcf, 0xf9, 0x87, + 0xd6, 0x55, 0x34, 0xeb, 0x70, 0x16, 0xcd, 0xc9, 0x0d, 0x38, 0x8c, 0x9c, + 0x69, 0x56, 0xb0, 0xd6, 0xd6, 0x75, 0x79, 0x9e, 0xe5, 0x9a, 0xf8, 0xe9, + 0x76, 0x63, 0xab, 0xc2, 0x9b, 0xb6, 0xad, 0x2f, 0x0d, 0x57, 0x7b, 0xf2, + 0x22, 0x6d, 0xda, 0x6b, 0x16, 0xd2, 0x29, 0x14, 0x40, 0x61, 0x82, 0xf2, + 0x5c, 0x06, 0x30, 0x67, 0x1a, 0x07, 0x3c, 0xd9, 0xb5, 0x61, 0xe9, 0xab, + 0xa5, 0x17, 0x56, 0x35, 0x3c, 0x7e, 0xf0, 0x2e, 0x1f, 0x2a, 0x54, 0xf5, + 0xb3, 0xe9, 0x05, 0x38, 0x50, 0x79, 0xf2, 0xaf, 0x14, 0xef, 0x81, 0xa2, + 0xaa, 0x99, 0xc3, 0x66, 0x0f, 0x86, 0x22, 0x3a, 0x99, 0x83, 0x16, 0x8f, + 0x47, 0xd7, 0x28, 0xe4, 0x5a, 0x8a, 0x76, 0xf5, 0x5a, 0xc6, 0xfb, 0xd5, + 0x4c, 0x3c, 0xb1, 0x9c, 0xd3, 0xb9, 0xfc, 0x5c, 0x34, 0x40, 0xa2, 0x52, + 0x55, 0x38, 0xaf, 0x6c, 0x29, 0xd5, 0x0a, 0xd4, 0x49, 0x46, 0x88, 0xbe, + 0xc8, 0x0c, 0xf8, 0x31, 0x56, 0xd2, 0x72, 0x58, 0xdc, 0xc3, 0xf9, 0x34, + 0xb8, 0x24, 0x03, 0x56, 0xfc, 0x9d, 0xf5, 0x86, 0x46, 0x64, 0x5d, 0x2a, + 0x35, 0x6a, 0x1f, 0xb3, 0x46, 0xfa, 0x77, 0x5e, 0x4a, 0xc7, 0x27, 0x22, + 0x6d, 0x2a, 0x2f, 0x75, 0x94, 0xd3, 0x63, 0xb8, 0x7f, 0x8d, 0x21, 0xbf, + 0xcb, 0xae, 0xee, 0x20, 0x99, 0x37, 0x74, 0xf1, 0x2d, 0xe3, 0xe2, 0xeb, + 0x43, 0x92, 0xbf, 0xd7, 0xe2, 0x81, 0x5c, 0x57, 0x5e, 0xde, 0x86, 0x08, + 0x41, 0xa6, 0x24, 0xeb, 0xba, 0x6f, 0xdb, 0x88, 0x77, 0xae, 0x6b, 0x03, + 0xfe, 0x4c, 0x43, 0xe6, 0x3e, 0x91, 0x47, 0x51, 0x1f, 0x9d, 0xe1, 0x54, + 0x72, 0xe9, 0x28, 0x05, 0x33, 0x7c, 0xfa, 0xab, 0x1b, 0xbb, 0x1a, 0x86, + 0xc3, 0x76, 0x0d, 0x9d, 0x86, 0xd9, 0x43, 0xd6, 0x88, 0xbc, 0xc8, 0xfd, + 0x9b, 0xad, 0x2d, 0xcb, 0x9d, 0xeb, 0xf4, 0xa3, 0xdc, 0x65, 0xdd, 0xc8, + 0x14, 0xde, 0xca, 0xec, 0x34, 0x5e, 0x16, 0x18, 0xaa, 0x62, 0xa3, 0xcc, + 0xc1, 0x9f, 0xd6, 0x9a, 0x6c, 0xfc, 0x39, 0x80, 0x5f, 0x6a, 0x0d, 0xe8, + 0x24, 0x71, 0x57, 0xa2, 0xf0, 0xc9, 0x50, 0xd9, 0x19, 0x1a, 0xde, 0x00, + 0xc7, 0xed, 0xcd, 0xd5, 0x8b, 0x56, 0xda, 0x90, 0xfb, 0xa5, 0x5b, 0x86, + 0xc0, 0x72, 0xd9, 0xb4, 0x79, 0x32, 0x58, 0x6b, 0x25, 0x0f, 0xc0, 0x96, + 0xbf, 0x14, 0x95, 0x1c, 0xe1, 0x7d, 0x4e, 0xc4, 0x7b, 0x25, 0x99, 0x8b, + 0xf5, 0x89, 0x5b, 0xb8, 0x34, 0xca, 0xce, 0x8a, 0x6b, 0x9c, 0x39, 0x0b, + 0x1d, 0x33, 0x8f, 0xc2, 0xc4, 0x9f, 0x6f, 0xb9, 0xf9, 0x56, 0xf1, 0x27, + 0x72, 0x02, 0xe2, 0x25, 0xb9, 0xdc, 0x72, 0x03, 0x9a, 0x54, 0x55, 0x8f, + 0x2e, 0x9e, 0xa2, 0xa1, 0xfd, 0x2c, 0x0a, 0xb9, 0x83, 0xb1, 0xf5, 0xeb, + 0x4a, 0x58, 0xe4, 0x59, 0x8a, 0x28, 0x8d, 0x4e, 0x23, 0xe0, 0x84, 0x08, + 0xf4, 0x80, 0x8c, 0x2d, 0xfc, 0xed, 0xe8, 0x5e, 0x2f, 0x9d, 0x6f, 0x74, + 0x37, 0xd0, 0xbd, 0xec, 0xb3, 0xa6, 0xb1, 0xef, 0xad, 0x4b, 0x77, 0x65, + 0x14, 0x0c, 0x80, 0xb9, 0xdb, 0x89, 0x73, 0xb9, 0x89, 0xc1, 0x7d, 0x2b, + 0x8b, 0x1b, 0x77, 0xea, 0xfc, 0xfa, 0x65, 0xdd, 0x03, 0x59, 0x92, 0x27, + 0x8a, 0x48, 0x07, 0xcb, 0x7b, 0x68, 0xce, 0xfc, 0xcf, 0xa2, 0x4d, 0x1d, + 0x7b, 0x38, 0xae, 0x2a, 0x0d, 0x16, 0xcf, 0x2b, 0x1d, 0xb3, 0x15, 0x8a, + 0xe7, 0xfe, 0xaa, 0x8a, 0xd0, 0xc5, 0x53, 0x2b, 0xa7, 0x71, 0x14, 0xa6, + 0x66, 0x04, 0x78, 0x1d, 0x59, 0xbe, 0x8e, 0x6b, 0x8f, 0x9a, 0x9f, 0xd1, + 0xa6, 0x6a, 0x77, 0xdc, 0xc2, 0x3f, 0x55, 0x5a, 0x75, 0x43, 0x98, 0xb2, + 0xb6, 0x52, 0x3e, 0x8b, 0x36, 0xbc, 0xac, 0xa3, 0x77, 0x05, 0x99, 0x6b, + 0x89, 0x2c, 0xff, 0x73, 0x3d, 0x3a, 0x79, 0xa4, 0xdd, 0x08, 0x5d, 0xf1, + 0x1e, 0x44, 0x05, 0x5f, 0x91, 0x48, 0xaa, 0xbc, 0x1d, 0x81, 0x62, 0x85, + 0x45, 0x00, 0xb7, 0xda, 0x39, 0x92, 0xb1, 0xbf, 0x14, 0xfb, 0xdf, 0x4a, + 0xab, 0xd4, 0x18, 0xac, 0x9e, 0x8c, 0xca, 0x79, 0x5b, 0x7b, 0x61, 0x66, + 0x71, 0x73, 0x0c, 0x2f, 0xa0, 0xe1, 0xdc, 0x6d, 0x7d, 0x6e, 0xb6, 0x79, + 0x30, 0x03, 0x97, 0xd5, 0x81, 0x73, 0xf8, 0x05, 0x25, 0xe4, 0x52, 0x7b, + 0xcf, 0x5d, 0x29, 0xa7, 0x2a, 0x3e, 0x45, 0x7b, 0x6b, 0x02, 0xac, 0x85, + 0x50, 0x50, 0x26, 0xf1, 0xdc, 0x88, 0x52, 0xf2, 0xbb, 0x11, 0x4a, 0x35, + 0x81, 0xd2, 0x06, 0x74, 0xa5, 0xf2, 0x9c, 0x00, 0x78, 0x76, 0xc0, 0x3a, + 0x40, 0x59, 0x2c, 0xb8, 0x67, 0xfd, 0x71, 0x2a, 0xc6, 0xba, 0xf5, 0xb6, + 0x77, 0xc2, 0x08, 0x2f, 0xf7, 0xc0, 0xb4, 0xda, 0xc6, 0xe2, 0x51, 0x2f, + 0x96, 0x7a, 0xdb, 0x37, 0x55, 0x48, 0xa1, 0x4a, 0xbb, 0x9a, 0xd7, 0x69, + 0xde, 0xa4, 0xec, 0x3f, 0x45, 0xca, 0xf4, 0xab, 0x48, 0x1c, 0xfd, 0x6c, + 0x3e, 0x67, 0xa4, 0x2d, 0x89, 0x5f, 0xc4, 0xb3, 0x8f, 0xd9, 0x3b, 0x9c, + 0x60, 0x3e, 0x8f, 0x7f, 0xe0, 0xfb, 0x53, 0xa7, 0xbb, 0xe3, 0x93, 0x98, + 0xc7, 0xcc, 0x61, 0x34, 0x8d, 0xb7, 0xf0, 0x0f, 0xce, 0x62, 0xdf, 0x0f, + 0x8d, 0x08, 0x2c, 0x2e, 0x42, 0x8f, 0xa9, 0xf7, 0x6a, 0x1a, 0xde, 0x50, + 0xb7, 0xeb, 0x97, 0xb1, 0x38, 0x3d, 0x67, 0x8f, 0xac, 0x91, 0x5d, 0x71, + 0xc9, 0x4b, 0x88, 0xaf, 0x74, 0x89, 0x40, 0x6f, 0x4d, 0xdd, 0xc2, 0x3b, + 0x27, 0x6b, 0x7b, 0x45, 0x76, 0xff, 0xd6, 0x8f, 0x23, 0xde, 0xfa, 0x65, + 0xe0, 0x87, 0x69, 0x1c, 0x05, 0x0b, 0xd1, 0xcf, 0x17, 0xbf, 0x5c, 0xd6, + 0x3b, 0x2a, 0x3e, 0xbb, 0x66, 0x24, 0xb4, 0x49, 0x35, 0x70, 0x9e, 0x91, + 0xf9, 0x96, 0xbd, 0x9e, 0x48, 0x3e, 0x1d, 0xfc, 0x2f, 0x5e, 0x01, 0x5c, + 0xae, 0x05, 0xc6, 0x25, 0x45, 0xf4, 0x1f, 0xe6, 0xd8, 0x4a, 0x13, 0xd0, + 0x58, 0x81, 0x35, 0x0e, 0xa2, 0x4a, 0x50, 0x38, 0xd9, 0xec, 0xdd, 0xca, + 0xd2, 0x6b, 0x8d, 0xc0, 0x51, 0x18, 0xd8, 0xdd, 0xb8, 0xf1, 0xc4, 0x34, + 0x86, 0xb6, 0x9b, 0xb7, 0xdd, 0x78, 0xde, 0x1c, 0x50, 0xbc, 0x10, 0x46, + 0x29, 0xf7, 0xd2, 0x7c, 0xd6, 0x51, 0x91, 0xc9, 0xcc, 0xae, 0x72, 0x8b, + 0x64, 0x2c, 0xca, 0xce, 0xec, 0x01, 0xe9, 0xda, 0xfd, 0xb5, 0x74, 0x7a, + 0x87, 0xe0, 0x2a, 0x60, 0x83, 0xd4, 0xf0, 0xc3, 0xf5, 0x2e, 0x0e, 0xd1, + 0x7c, 0xbe, 0xda, 0x26, 0x94, 0x6c, 0xb3, 0xff, 0xd9, 0xfa, 0xf1, 0xb3, + 0x28, 0x4b, 0xf3, 0xe3, 0x99, 0x9f, 0xe5, 0x4b, 0xb2, 0x28, 0x2e, 0x87, + 0x22, 0xff, 0x66, 0x50, 0xa2, 0x24, 0xcd, 0x07, 0xb5, 0xd8, 0x2b, 0x76, + 0x24, 0x39, 0x2a, 0xce, 0x16, 0xa8, 0xed, 0x26, 0xc7, 0xec, 0x81, 0x42, + 0x28, 0x14, 0xe0, 0xcf, 0x7b, 0xb7, 0x4e, 0xc8, 0x75, 0x1c, 0x7d, 0x8b, + 0x7e, 0x65, 0x5c, 0xd6, 0x0f, 0x69, 0x94, 0x10, 0x05, 0xbf, 0xee, 0x5b, + 0x60, 0xfb, 0x27, 0x3f, 0x1f, 0xd8, 0x5b, 0x06, 0xab, 0xd5, 0x3f, 0x0d, + 0xd7, 0xa5, 0x2d, 0x0a, 0x65, 0x85, 0xee, 0xf7, 0x0d, 0xc9, 0x27, 0x8b, + 0x8b, 0x3c, 0xb9, 0xc7, 0x6e, 0x44, 0x81, 0x47, 0x5d, 0xfc, 0x39, 0x74, + 0x72, 0x4b, 0xb6, 0xfc, 0x39, 0xf4, 0xc4, 0x8c, 0xca, 0xe2, 0x2e, 0x6f, + 0x86, 0xca, 0x88, 0x02, 0xbf, 0xde, 0x68, 0xf1, 0x1d, 0x78, 0x55, 0x0d, + 0x0f, 0xff, 0xf6, 0xb0, 0x00, 0xab, 0xb0, 0x78, 0x56, 0x01, 0x56, 0xc1, + 0xf9, 0xcf, 0xf4, 0x07, 0xde, 0xc4, 0x89, 0xa4, 0xf9, 0x59, 0x8e, 0xe9, + 0xbe, 0x3c, 0x2e, 0x4f, 0xa2, 0xf5, 0x39, 0x1d, 0x17, 0x93, 0x11, 0xab, + 0x95, 0x96, 0xef, 0x67, 0xd7, 0xa8, 0x53, 0xf3, 0x61, 0x77, 0x10, 0xfa, + 0x24, 0x47, 0xe9, 0xa9, 0xcb, 0x06, 0x94, 0x23, 0x56, 0x70, 0x21, 0x62, + 0x68, 0xbd, 0x04, 0xa4, 0x49, 0x2b, 0x83, 0x01, 0xbb, 0x27, 0xf2, 0x18, + 0x24, 0x4a, 0xe9, 0x06, 0x50, 0xb2, 0x81, 0xf7, 0x2f, 0xc8, 0x3e, 0x27, + 0xab, 0x25, 0x67, 0x2e, 0x1c, 0xdb, 0xc3, 0xca, 0x53, 0x52, 0x15, 0xb2, + 0xdb, 0xa2, 0x3c, 0x8d, 0xe2, 0x47, 0x2f, 0x5e, 0x58, 0xa0, 0x6c, 0x76, + 0x77, 0xff, 0x48, 0xf7, 0x4e, 0x58, 0xa7, 0xfd, 0x99, 0xb7, 0x5a, 0xcd, + 0x96, 0x2b, 0x2f, 0xe5, 0x87, 0x75, 0xec, 0xa7, 0xfb, 0xa4, 0xe2, 0x35, + 0x50, 0x33, 0x95, 0x65, 0xf9, 0x32, 0xeb, 0x0f, 0xb9, 0x0a, 0x47, 0x7a, + 0x1f, 0x26, 0x03, 0xce, 0x0a, 0x2a, 0x28, 0x5f, 0x53, 0x82, 0xf9, 0x0e, + 0xde, 0x43, 0x65, 0x8a, 0xdf, 0xcf, 0x7f, 0x80, 0xa6, 0xfe, 0x4b, 0x79, + 0x10, 0x47, 0xb0, 0x10, 0x85, 0xd1, 0x86, 0xee, 0x83, 0x0d, 0xd5, 0x45, + 0x54, 0x52, 0x0d, 0x82, 0x74, 0x15, 0x85, 0x7b, 0x0a, 0x94, 0xad, 0x17, + 0xea, 0x1c, 0xe8, 0x37, 0x6e, 0x6a, 0xa6, 0xb2, 0x98, 0x01, 0x4a, 0x38, + 0x43, 0xa3, 0xbe, 0x83, 0xd8, 0xc1, 0xf3, 0xfc, 0x7e, 0xb2, 0x67, 0x9c, + 0xff, 0xaf, 0x24, 0x80, 0xbc, 0xf4, 0x34, 0xab, 0xdd, 0xe0, 0x0f, 0xd7, + 0x33, 0x74, 0x10, 0x57, 0xe5, 0xb3, 0xf6, 0x75, 0x5e, 0xdd, 0x72, 0x15, + 0x79, 0x36, 0x93, 0x16, 0x47, 0x5c, 0xdc, 0x98, 0x3d, 0x06, 0x8b, 0x14, + 0xec, 0xb5, 0xa7, 0xfc, 0xf5, 0x05, 0x93, 0xaa, 0xd9, 0xe2, 0xdc, 0xd2, + 0xe5, 0x1f, 0xd2, 0xc5, 0x1b, 0xa9, 0x28, 0xe3, 0xd8, 0xeb, 0xcf, 0x4a, + 0x49, 0x62, 0x23, 0xbf, 0x5d, 0xc3, 0x73, 0xaa, 0x65, 0x32, 0xa0, 0x08, + 0x59, 0xe2, 0xd9, 0x69, 0x4d, 0xf5, 0x5b, 0xf4, 0x82, 0xd9, 0x40, 0x80, + 0xa4, 0x32, 0x3f, 0xa0, 0xd0, 0xf4, 0x2f, 0x41, 0x0f, 0xad, 0x7b, 0x50, + 0xb0, 0xc9, 0xc5, 0x8b, 0xfd, 0x3c, 0x7b, 0x0c, 0xc2, 0x45, 0xf4, 0x28, + 0xe9, 0x73, 0x08, 0x37, 0x0b, 0x0a, 0x36, 0xd4, 0xeb, 0x63, 0x90, 0x44, + 0xde, 0xb1, 0xdb, 0x04, 0x4f, 0xfe, 0x0a, 0x5a, 0xa0, 0x45, 0x26, 0x46, + 0xc5, 0xf8, 0x99, 0xc9, 0x70, 0x2d, 0x42, 0x8b, 0xd4, 0x8c, 0x8a, 0xf0, + 0x38, 0x4a, 0xd3, 0x68, 0x4d, 0xae, 0x19, 0x3a, 0xa5, 0x7f, 0xdb, 0x6e, + 0x29, 0x1b, 0x15, 0xf1, 0x85, 0xbf, 0x4c, 0x6d, 0xd0, 0xda, 0xaa, 0x99, + 0x4c, 0x6f, 0x05, 0xfe, 0x23, 0xeb, 0x49, 0x55, 0x91, 0xd5, 0x1e, 0xba, + 0xff, 0x8a, 0xa1, 0x3c, 0x57, 0xe0, 0x93, 0xaf, 0x7b, 0xf3, 0xca, 0x77, + 0x81, 0x22, 0x9c, 0xb8, 0xed, 0x9f, 0x7a, 0xb0, 0x16, 0x2d, 0xa1, 0xfc, + 0x52, 0x8f, 0xf2, 0x00, 0xc0, 0xb8, 0xeb, 0x5a, 0xb1, 0xcc, 0x80, 0xc7, + 0xbc, 0x5f, 0x79, 0xd9, 0x50, 0x96, 0xa0, 0x74, 0x70, 0x97, 0xde, 0x86, + 0x52, 0x2e, 0x48, 0x29, 0xc7, 0x44, 0xa9, 0xec, 0x83, 0xbe, 0x00, 0x1f, + 0xe4, 0xe2, 0x02, 0x6b, 0x43, 0x67, 0x17, 0xa2, 0xb3, 0x53, 0x4f, 0xe7, + 0xd2, 0x66, 0xff, 0xed, 0x9d, 0x22, 0xc7, 0xd4, 0x22, 0xd3, 0xd8, 0x94, + 0xd2, 0x79, 0x9f, 0xca, 0x15, 0x61, 0x7f, 0xe6, 0x6f, 0xaa, 0x6c, 0x56, + 0x1e, 0xaf, 0xde, 0xcb, 0x79, 0x71, 0x04, 0x27, 0x0a, 0xc5, 0x3d, 0x8d, + 0xdb, 0xc7, 0x1d, 0x75, 0x63, 0x7e, 0x91, 0x0e, 0x44, 0x60, 0x6d, 0xaf, + 0x4a, 0xcb, 0xa3, 0x2b, 0x9a, 0x3d, 0x3d, 0x97, 0xd7, 0xf8, 0xe5, 0x2b, + 0x99, 0xcc, 0xbd, 0x95, 0x68, 0x61, 0x9c, 0xf5, 0x41, 0x3e, 0xa8, 0x29, + 0x7e, 0x2d, 0x78, 0xf1, 0xd1, 0x5b, 0x2d, 0xf7, 0xa4, 0x86, 0x73, 0xf6, + 0xdd, 0x4e, 0x97, 0xea, 0x26, 0xea, 0xb7, 0x70, 0xdd, 0xb4, 0xe3, 0xca, + 0x75, 0xf4, 0x85, 0xba, 0xb3, 0xc0, 0xfe, 0x12, 0xb2, 0x00, 0x9c, 0x67, + 0x44, 0xf1, 0xf9, 0x95, 0xc9, 0xd2, 0xf6, 0x63, 0x71, 0x3a, 0x4e, 0x9d, + 0xdb, 0xdc, 0x22, 0xbd, 0xbf, 0x9d, 0xb3, 0x4a, 0x85, 0xdb, 0xe4, 0xc3, + 0x4b, 0x29, 0x92, 0x7f, 0x53, 0x2d, 0xc6, 0x86, 0xce, 0x8c, 0x2c, 0xea, + 0xb8, 0xf0, 0x9e, 0x45, 0x4b, 0xbc, 0x6c, 0x95, 0x47, 0x0d, 0xca, 0x28, + 0xf3, 0xb1, 0xf5, 0x47, 0xb0, 0x70, 0x89, 0x47, 0x9d, 0x7b, 0xe7, 0x16, + 0x35, 0x0d, 0x6a, 0xd7, 0x73, 0x9e, 0xf0, 0x60, 0x27, 0x70, 0xe4, 0xfd, + 0x35, 0x9d, 0xc6, 0xf9, 0x80, 0xbb, 0x5e, 0xd1, 0x96, 0x46, 0xf0, 0x7b, + 0x59, 0x07, 0x1b, 0x2a, 0x4e, 0x21, 0x75, 0xb9, 0xd7, 0xa6, 0x44, 0x4c, + 0xd7, 0xe2, 0x56, 0xa9, 0xd2, 0xfd, 0x90, 0x7f, 0xcd, 0xfb, 0xf6, 0xd3, + 0x07, 0x00, 0x53, 0x25, 0x5f, 0x61, 0xd6, 0x15, 0xc7, 0xd7, 0xd7, 0xbc, + 0x48, 0x96, 0x06, 0x64, 0xb1, 0x7a, 0xa1, 0x19, 0x8a, 0x36, 0x0a, 0xba, + 0x6a, 0xef, 0x77, 0x81, 0xe8, 0x25, 0x93, 0xe0, 0x8e, 0x83, 0xd2, 0xdf, + 0xef, 0xe0, 0xf6, 0x3d, 0xdb, 0xed, 0xef, 0x29, 0x05, 0x79, 0xa7, 0x55, + 0xb9, 0x64, 0x25, 0x16, 0xc1, 0xed, 0x8b, 0xd8, 0xd5, 0xb5, 0x58, 0x6c, + 0x4a, 0xe8, 0xb9, 0x4c, 0xf0, 0x4c, 0xb9, 0x28, 0x8e, 0x12, 0xd7, 0x24, + 0x78, 0x61, 0x7d, 0xb9, 0xb5, 0x89, 0x74, 0x37, 0x8a, 0x45, 0x56, 0x1a, + 0x36, 0x68, 0xa5, 0xe5, 0x0c, 0x35, 0x65, 0x45, 0x34, 0xe7, 0x79, 0xb1, + 0xec, 0x51, 0xc0, 0x44, 0x09, 0x5a, 0x4c, 0x29, 0x32, 0xb1, 0x5c, 0xa2, + 0xd7, 0x72, 0x9b, 0xd1, 0x91, 0x6e, 0xfb, 0x0e, 0xad, 0x1a, 0xaf, 0x19, + 0xee, 0xb8, 0x3d, 0xe0, 0xb5, 0x28, 0xfb, 0xf1, 0x54, 0xab, 0xde, 0xd5, + 0xd6, 0x96, 0x23, 0x84, 0xa1, 0x76, 0x2a, 0x0d, 0xa8, 0xfc, 0xd5, 0x11, + 0xc8, 0x6d, 0x4e, 0xa0, 0x2a, 0xda, 0x9d, 0x08, 0x05, 0xa0, 0xd9, 0x89, + 0x60, 0x00, 0x9e, 0xa6, 0x84, 0xe3, 0x5d, 0xe8, 0x33, 0x3c, 0x6c, 0x3c, + 0x9f, 0x22, 0xe1, 0xc2, 0xbb, 0x60, 0xc2, 0xcb, 0x4b, 0xe2, 0xb1, 0xec, + 0x24, 0x59, 0xf8, 0x4b, 0x8f, 0xaa, 0x1e, 0xe5, 0xcb, 0xb5, 0x49, 0x58, + 0x33, 0xf5, 0x00, 0xe8, 0xca, 0x55, 0xd2, 0xc3, 0x05, 0x96, 0x83, 0x17, + 0xab, 0xe0, 0xb2, 0x91, 0xa8, 0xd5, 0x19, 0x22, 0x66, 0x01, 0x95, 0xc6, + 0x0e, 0xc5, 0x80, 0x52, 0x8b, 0x98, 0xf1, 0x96, 0xd4, 0x08, 0x84, 0xf7, + 0xa5, 0xd6, 0xc2, 0xe2, 0x80, 0xc1, 0xd2, 0x5a, 0xc8, 0x82, 0xc3, 0x57, + 0xb5, 0x16, 0x8e, 0xc5, 0xfe, 0xd3, 0x5b, 0x68, 0xac, 0xb3, 0x49, 0x5a, + 0xee, 0xdd, 0x66, 0xd3, 0xb0, 0xbd, 0x47, 0x3e, 0x96, 0x6e, 0x57, 0x65, + 0xac, 0x5d, 0xab, 0x8f, 0x7c, 0x2c, 0xdb, 0xa3, 0xca, 0x60, 0x9b, 0x3b, + 0x88, 0xf6, 0x66, 0x0e, 0x97, 0xb4, 0x37, 0x73, 0xf0, 0x66, 0x0e, 0x5e, + 0xdd, 0x1c, 0xbc, 0xd8, 0xcd, 0x75, 0x3f, 0xd8, 0x36, 0x1d, 0xe0, 0x48, + 0xfa, 0xf2, 0x73, 0xb3, 0xa6, 0x40, 0x2f, 0xbd, 0xe9, 0x62, 0x40, 0x8b, + 0x65, 0x72, 0xcd, 0xfe, 0x5b, 0x53, 0x6b, 0xe5, 0x58, 0x58, 0x2b, 0x47, + 0xa3, 0xe4, 0xb8, 0x78, 0x4a, 0x47, 0xd2, 0x72, 0x10, 0xad, 0xd7, 0x51, + 0xd8, 0xb8, 0x0f, 0xbe, 0x5e, 0xcc, 0xc7, 0x3b, 0x29, 0x02, 0x01, 0x8f, + 0x85, 0x0f, 0x5d, 0xb4, 0xc0, 0xd6, 0xba, 0x31, 0x2a, 0x0d, 0x78, 0x71, + 0x7b, 0x52, 0x6a, 0x82, 0x6d, 0x42, 0x64, 0x61, 0x4e, 0xf8, 0x11, 0xfc, + 0xde, 0x2d, 0xc9, 0xde, 0x3a, 0xaa, 0x22, 0x69, 0x57, 0xce, 0xe0, 0xcd, + 0x48, 0xf8, 0x09, 0x3a, 0x0b, 0x98, 0x6f, 0xf8, 0x99, 0x3c, 0x11, 0x67, + 0xe0, 0xca, 0xb1, 0xb2, 0x82, 0xb6, 0x83, 0x2b, 0x01, 0xf9, 0x6d, 0x19, + 0x1a, 0x72, 0x31, 0xdd, 0xbf, 0x18, 0xa2, 0xbb, 0xbe, 0x3a, 0xee, 0x6c, + 0xba, 0x7f, 0x36, 0xac, 0xee, 0xf2, 0x1a, 0x73, 0xd2, 0xcc, 0x05, 0x68, + 0xbf, 0x5a, 0xc0, 0xd8, 0xfe, 0x3e, 0x01, 0x63, 0xe9, 0x7e, 0xf6, 0xdf, + 0xd3, 0x05, 0x10, 0xcd, 0xdc, 0x72, 0x77, 0xb3, 0xec, 0x13, 0xca, 0x08, + 0xd0, 0xa2, 0xe4, 0x56, 0xa0, 0xca, 0x1c, 0x4c, 0x33, 0x26, 0x3c, 0x75, + 0x6f, 0xef, 0x96, 0xb4, 0x77, 0x70, 0x4b, 0x74, 0x05, 0x6a, 0x3a, 0xb9, + 0x6b, 0xe6, 0xee, 0xef, 0xa0, 0x40, 0xeb, 0xb3, 0x44, 0xd7, 0x4a, 0x87, + 0x7e, 0x29, 0x91, 0x1d, 0x8b, 0xf8, 0x5e, 0xd4, 0x07, 0xf1, 0xe3, 0x9d, + 0xe2, 0xe9, 0x85, 0x81, 0x78, 0xd1, 0xa1, 0xa2, 0xeb, 0xf0, 0x2a, 0x0e, + 0xf0, 0x11, 0xf1, 0x0a, 0x17, 0x8a, 0xaa, 0x25, 0x08, 0xfc, 0x4d, 0x85, + 0xbe, 0xa9, 0x50, 0x9b, 0x9c, 0xdb, 0x9b, 0x26, 0xfa, 0xbd, 0x34, 0xd1, + 0x2a, 0x8a, 0xad, 0x3d, 0xb9, 0x86, 0xfe, 0x6f, 0xad, 0x26, 0x53, 0x6e, + 0x5d, 0x58, 0xb4, 0x2d, 0x31, 0x35, 0xfe, 0x74, 0x5f, 0xde, 0xf9, 0x53, + 0x8a, 0x50, 0xa5, 0xf5, 0x27, 0xe4, 0xcb, 0xd6, 0x74, 0x35, 0x97, 0xc7, + 0x70, 0x68, 0x5b, 0xf3, 0x91, 0xda, 0xe7, 0x79, 0x69, 0x6a, 0xb6, 0x5a, + 0xa8, 0xbd, 0x57, 0x6b, 0xb6, 0x5a, 0xac, 0xd5, 0xa2, 0xd9, 0x6a, 0xb1, + 0x4b, 0x61, 0x45, 0xef, 0x54, 0xb7, 0x73, 0xae, 0xe2, 0xcd, 0xa8, 0xd8, + 0x86, 0xaf, 0x7c, 0x55, 0xcf, 0xa4, 0x17, 0x2a, 0x78, 0xf4, 0x10, 0x42, + 0xbf, 0xe1, 0xdf, 0xa4, 0xc9, 0x42, 0xd3, 0xcd, 0xe6, 0x7e, 0x97, 0xcd, + 0x86, 0xa4, 0xfd, 0x94, 0xcd, 0xe2, 0x2a, 0xf7, 0x4a, 0x2b, 0xab, 0xc3, + 0xc8, 0xd4, 0xa2, 0x26, 0x9f, 0xea, 0xfc, 0x2a, 0xdd, 0xe5, 0xa6, 0xd5, + 0x07, 0x08, 0x70, 0x9c, 0xfe, 0x2d, 0x82, 0x88, 0x48, 0xab, 0x81, 0x88, + 0x18, 0x51, 0x83, 0x22, 0xe3, 0x1a, 0x65, 0x06, 0xc3, 0xec, 0x9a, 0xa8, + 0xe1, 0x76, 0x5f, 0x46, 0x0d, 0x17, 0xa3, 0x86, 0x54, 0x0f, 0x4d, 0xa9, + 0xe1, 0x62, 0xd4, 0x68, 0x60, 0x59, 0x75, 0xcc, 0x8e, 0x89, 0x1a, 0xb2, + 0x8e, 0x7d, 0x37, 0x6a, 0x38, 0x18, 0x35, 0xa4, 0x2a, 0x6a, 0x4a, 0x0d, + 0x07, 0xa1, 0x86, 0x53, 0xa5, 0xb3, 0x25, 0x35, 0x0e, 0x8c, 0xd4, 0x38, + 0x78, 0x19, 0x35, 0x0e, 0x30, 0x6a, 0x74, 0x77, 0x25, 0xc6, 0x01, 0x42, + 0x8c, 0x2a, 0x95, 0x8d, 0xb4, 0x68, 0xaa, 0x14, 0x5f, 0x27, 0x99, 0x54, + 0xbc, 0x09, 0xb7, 0xab, 0x17, 0xa2, 0x9c, 0x4c, 0xb6, 0x7a, 0xb6, 0x5e, + 0xc8, 0x0b, 0x5e, 0x5d, 0x70, 0x3b, 0xb8, 0x02, 0xc6, 0x5c, 0x0e, 0xb7, + 0x81, 0xcb, 0xd1, 0xd0, 0x55, 0xa0, 0xf4, 0x24, 0xaf, 0xef, 0x2e, 0xd4, + 0xb5, 0x66, 0x6c, 0xea, 0x25, 0x60, 0xe1, 0xa0, 0x2a, 0xa9, 0xe4, 0x7d, + 0x70, 0x1f, 0xb2, 0x77, 0x72, 0x3e, 0x54, 0xbf, 0x0e, 0xf6, 0xd8, 0x59, + 0x6b, 0xff, 0xc4, 0x5f, 0xd1, 0xa0, 0x2b, 0x21, 0x77, 0x7e, 0xfa, 0xc8, + 0xae, 0x50, 0xca, 0x77, 0x07, 0xe7, 0xbc, 0x59, 0x02, 0xc9, 0xa4, 0x94, + 0x85, 0x89, 0x13, 0x7f, 0xe3, 0xc5, 0x8c, 0x04, 0x39, 0x88, 0xf8, 0xdb, + 0x4f, 0x70, 0xcb, 0x7f, 0x89, 0xe9, 0xfc, 0x04, 0xf5, 0xfb, 0xcb, 0xbe, + 0xfa, 0x9f, 0x63, 0xbf, 0x4d, 0x44, 0x06, 0x20, 0xeb, 0x37, 0x62, 0xbd, + 0xeb, 0xc4, 0xbb, 0x9f, 0x40, 0xe0, 0x64, 0x7a, 0x63, 0x41, 0x23, 0x9b, + 0x3a, 0x27, 0x10, 0x3e, 0x28, 0x35, 0xaa, 0x79, 0xcd, 0x4d, 0x15, 0x89, + 0x96, 0xc0, 0x30, 0xb5, 0x4b, 0xc0, 0xc3, 0xb8, 0xa6, 0x64, 0x6f, 0x7d, + 0x67, 0xb2, 0xd7, 0xe7, 0x7e, 0xfe, 0x63, 0xc9, 0xfe, 0x4a, 0x2e, 0x37, + 0xff, 0x68, 0xee, 0x78, 0x27, 0x24, 0x2f, 0x75, 0x32, 0x0b, 0x3c, 0x53, + 0x1e, 0xc3, 0xa7, 0x0d, 0x6f, 0xc7, 0x95, 0x3e, 0x04, 0x09, 0xeb, 0xc1, + 0xe3, 0x91, 0x8e, 0xe8, 0x33, 0xc5, 0x57, 0xf3, 0x7f, 0x60, 0xbd, 0xa0, + 0xcc, 0x43, 0x42, 0xff, 0x89, 0xba, 0x6c, 0x6d, 0xf6, 0x5e, 0x2e, 0xf4, + 0x32, 0x90, 0x45, 0xa7, 0x4f, 0x15, 0xdb, 0x2a, 0x7a, 0x24, 0x2d, 0x57, + 0x43, 0xd6, 0xac, 0xe3, 0xa7, 0xee, 0x2f, 0x84, 0xbf, 0x5b, 0xcc, 0xd4, + 0xfe, 0xfe, 0x0c, 0xac, 0x6e, 0x9d, 0x37, 0x06, 0xfe, 0xd9, 0x14, 0x5f, + 0x85, 0x81, 0xee, 0xf7, 0xdf, 0x81, 0xeb, 0x60, 0xb1, 0xc7, 0x6e, 0x1e, + 0xbd, 0x1e, 0x13, 0x19, 0xc6, 0xbf, 0x2c, 0x23, 0x3b, 0xdf, 0x9f, 0x91, + 0xdf, 0x69, 0x27, 0xbe, 0x31, 0xf2, 0xf7, 0x50, 0xa9, 0x2d, 0x6b, 0x27, + 0x70, 0xa3, 0x9c, 0x44, 0x29, 0x47, 0x47, 0x2d, 0x74, 0xa5, 0x2c, 0xa2, + 0xda, 0x68, 0x61, 0x17, 0x16, 0x66, 0x19, 0xf8, 0xca, 0xc4, 0x4a, 0x84, + 0x42, 0x39, 0x1e, 0x71, 0x9f, 0xf1, 0x2b, 0x7f, 0x1e, 0x8c, 0xdf, 0x2f, + 0x00, 0xa5, 0x4a, 0x5c, 0xd2, 0x26, 0x63, 0xca, 0x7a, 0xf1, 0x4c, 0x17, + 0xeb, 0x78, 0xac, 0x9d, 0x32, 0xd0, 0x0f, 0xba, 0x36, 0xdd, 0x08, 0xb2, + 0xe9, 0x31, 0xa4, 0x08, 0x19, 0x17, 0x59, 0xa7, 0xab, 0x49, 0x58, 0xdd, + 0x51, 0xc3, 0x9f, 0x47, 0xc2, 0xba, 0xdf, 0x5f, 0xc2, 0xea, 0xfd, 0xdd, + 0x37, 0x09, 0xfb, 0x9b, 0x4b, 0x98, 0x8d, 0x31, 0x62, 0x58, 0x94, 0xb7, + 0xba, 0xa8, 0x98, 0xcd, 0xf8, 0x6d, 0xa5, 0x44, 0x93, 0x3c, 0x79, 0x27, + 0x0e, 0xbc, 0x6d, 0xcf, 0x4b, 0xce, 0x62, 0xca, 0x0d, 0x7d, 0x6d, 0x0e, + 0x94, 0x28, 0x34, 0xae, 0x8e, 0x23, 0x99, 0x47, 0xab, 0xed, 0x3a, 0x34, + 0xe3, 0x69, 0x78, 0xcd, 0x97, 0x65, 0x7f, 0x94, 0xf3, 0xd8, 0x39, 0x7b, + 0xfd, 0x59, 0xee, 0xa2, 0xc9, 0x76, 0xe3, 0xc7, 0x7c, 0x5a, 0x5e, 0x1b, + 0x2c, 0x76, 0x4d, 0xed, 0x69, 0xe4, 0x31, 0x95, 0x2b, 0x4e, 0x10, 0xd6, + 0xef, 0x5c, 0x5a, 0x34, 0x99, 0x5b, 0xd4, 0x9b, 0xfb, 0x5a, 0x55, 0x06, + 0xcb, 0xaf, 0xc8, 0xc4, 0x7a, 0x14, 0x2f, 0x94, 0xb5, 0x4b, 0xdc, 0x78, + 0xcb, 0x15, 0xb9, 0x48, 0x53, 0xcf, 0xdf, 0x8e, 0xc5, 0xf1, 0xfe, 0x34, + 0x4a, 0xbd, 0x95, 0x78, 0x77, 0x5e, 0xd9, 0x4e, 0x6c, 0xd9, 0x09, 0xc0, + 0x11, 0x8b, 0x1b, 0x14, 0x2a, 0xc2, 0xe2, 0x8e, 0x94, 0x09, 0x9f, 0xd5, + 0x5d, 0x0a, 0xf0, 0x0b, 0x0b, 0x42, 0x02, 0xa5, 0x6e, 0x16, 0x7b, 0x1e, + 0xfc, 0xca, 0x3a, 0x9c, 0xd5, 0x2b, 0xa6, 0x75, 0xcc, 0x35, 0x50, 0xd2, + 0x14, 0xd7, 0x37, 0x14, 0x1d, 0x98, 0xac, 0xaf, 0x78, 0xb7, 0xa9, 0xa5, + 0xe9, 0x89, 0x75, 0x2e, 0x68, 0xb3, 0xa2, 0x01, 0xfb, 0x8c, 0xeb, 0x8e, + 0x15, 0xdd, 0x17, 0xb3, 0x3b, 0x2f, 0xf1, 0xeb, 0xf6, 0x5d, 0xb1, 0x83, + 0xd8, 0xa3, 0x0f, 0xfc, 0x0a, 0x4c, 0xcd, 0xe6, 0x2b, 0x37, 0xf4, 0xaf, + 0xbf, 0x1c, 0x53, 0xe5, 0xaa, 0x36, 0x97, 0xe9, 0x18, 0x13, 0x55, 0x2b, + 0xcc, 0x52, 0xd1, 0x69, 0x84, 0x37, 0x9d, 0x64, 0x56, 0xa9, 0x4c, 0xa3, + 0x8e, 0x46, 0xa3, 0x60, 0xbd, 0x59, 0x05, 0xf3, 0x20, 0x9d, 0x59, 0x28, + 0x55, 0x6a, 0xbc, 0x04, 0x70, 0x26, 0x45, 0x65, 0xcc, 0xdd, 0x77, 0x95, + 0xe5, 0x9c, 0x67, 0x65, 0xbd, 0xc7, 0xbc, 0xac, 0x97, 0xd7, 0xb5, 0x42, + 0xa6, 0x3a, 0xf1, 0x09, 0xbf, 0xcc, 0x31, 0x7f, 0xf0, 0x82, 0x90, 0x1a, + 0x6c, 0x2e, 0x2d, 0x2b, 0x55, 0x7b, 0xd5, 0xf4, 0xab, 0x01, 0x24, 0x8e, + 0x95, 0x0f, 0x53, 0x45, 0xb8, 0xe4, 0x5d, 0x9b, 0x45, 0x49, 0x31, 0x95, + 0x3a, 0x33, 0x76, 0x93, 0xea, 0xfe, 0xbb, 0x95, 0x9a, 0xeb, 0xe2, 0xa2, + 0xf5, 0x5a, 0x2e, 0xbd, 0x5a, 0x41, 0x37, 0x02, 0xdd, 0x0f, 0x0b, 0x34, + 0x00, 0x90, 0x8d, 0x29, 0x18, 0x85, 0x13, 0xd1, 0x20, 0x3b, 0x7b, 0xa5, + 0x80, 0x5d, 0xc2, 0xa9, 0xf2, 0x0f, 0x37, 0x10, 0x59, 0x2d, 0x6e, 0x7e, + 0x3f, 0xb8, 0x8a, 0x02, 0xaf, 0x4c, 0xcb, 0x5a, 0x68, 0x9f, 0x9f, 0x90, + 0xd8, 0xf7, 0x16, 0xe4, 0xee, 0x99, 0xc8, 0xdb, 0xcd, 0x24, 0x7f, 0xae, + 0x03, 0x95, 0xac, 0x0a, 0xda, 0xe2, 0xc5, 0x9d, 0x66, 0x88, 0xf1, 0x42, + 0xac, 0xea, 0xf7, 0x66, 0x34, 0x34, 0xa1, 0xac, 0x14, 0x22, 0x5b, 0x7d, + 0x2b, 0x82, 0x14, 0x2f, 0x93, 0xa6, 0x86, 0xe7, 0x7e, 0xed, 0x33, 0x8e, + 0x0b, 0x59, 0x59, 0x44, 0x54, 0x2d, 0xdc, 0x8a, 0x9e, 0xe1, 0xc0, 0x5e, + 0xc5, 0xbb, 0x8d, 0x4d, 0xb7, 0x71, 0xc8, 0x3a, 0xa6, 0x10, 0x9f, 0xd7, + 0xc7, 0xfd, 0x46, 0x28, 0x1e, 0xa0, 0xd9, 0x15, 0xde, 0xf9, 0x6c, 0x50, + 0x66, 0x03, 0x79, 0xf0, 0x12, 0x92, 0xe4, 0x87, 0x39, 0x01, 0x7f, 0xcb, + 0x98, 0x9d, 0xef, 0x64, 0x67, 0x7b, 0x9f, 0xae, 0x2f, 0xcb, 0x91, 0x40, + 0xd5, 0xc8, 0x61, 0xfc, 0x7a, 0xf1, 0x4c, 0x36, 0x3d, 0xbd, 0x75, 0x8a, + 0x6f, 0x13, 0x4a, 0x71, 0xca, 0xcf, 0x95, 0xb8, 0xa2, 0x45, 0xe6, 0xe2, + 0xfa, 0xfe, 0x67, 0xb6, 0xfd, 0xa8, 0xee, 0x0f, 0xb8, 0x4e, 0x48, 0x23, + 0xf1, 0x7b, 0xd6, 0xbd, 0xf1, 0xb3, 0x0b, 0x6c, 0xa0, 0xca, 0x26, 0xac, + 0xf3, 0x27, 0x8b, 0xd6, 0x40, 0x74, 0x8a, 0xe2, 0x73, 0x26, 0x9a, 0x0c, + 0x29, 0x3e, 0xcc, 0x1d, 0x1e, 0xb7, 0x48, 0x56, 0x65, 0x2a, 0x47, 0xa1, + 0x54, 0xe2, 0x67, 0xcb, 0x0d, 0x7e, 0x03, 0x8e, 0x15, 0xda, 0xbb, 0x60, + 0x17, 0x1c, 0xc1, 0x91, 0x77, 0x70, 0xe4, 0x19, 0xdf, 0x9b, 0x7e, 0x76, + 0xb7, 0x29, 0x66, 0xdb, 0x4f, 0x3e, 0xc4, 0x11, 0x2b, 0x8f, 0x53, 0x66, + 0x31, 0x97, 0xf2, 0x6a, 0x90, 0xfe, 0x90, 0x80, 0x9a, 0xf4, 0xba, 0xb3, + 0xf1, 0x5b, 0x4a, 0xd2, 0x40, 0x9d, 0x85, 0x45, 0xf5, 0xa2, 0xf0, 0x91, + 0x94, 0xf6, 0xa3, 0x5d, 0x90, 0xba, 0x7b, 0x8f, 0xde, 0x33, 0x49, 0x1f, + 0x98, 0x12, 0x83, 0xe3, 0x85, 0x23, 0x5c, 0xcf, 0x94, 0x91, 0xb6, 0x71, + 0xa4, 0xb8, 0xce, 0x29, 0x23, 0xbd, 0x8e, 0xa3, 0x8d, 0x77, 0xcf, 0x24, + 0xef, 0xca, 0xbb, 0x82, 0x76, 0x3b, 0xae, 0x58, 0xca, 0x28, 0x6f, 0xc2, + 0x80, 0x1d, 0xf1, 0x27, 0x35, 0x57, 0x8d, 0x9c, 0xae, 0x15, 0xaf, 0x74, + 0x01, 0x83, 0x38, 0xa5, 0xe0, 0x74, 0x0f, 0x76, 0xc0, 0x89, 0x33, 0xca, + 0xb1, 0x08, 0x0f, 0x75, 0x9c, 0x38, 0x9f, 0x9c, 0xae, 0xb5, 0x3b, 0x60, + 0xc9, 0x26, 0xa7, 0xda, 0x63, 0x00, 0xc1, 0x68, 0xc1, 0x25, 0xb7, 0x6d, + 0x45, 0xd1, 0xaa, 0xf6, 0xc2, 0x38, 0x65, 0xb7, 0x53, 0xab, 0x78, 0x71, + 0x6e, 0xb9, 0x2e, 0xee, 0x65, 0x54, 0xf1, 0xe2, 0x1c, 0x73, 0x5d, 0xdc, + 0xd1, 0xa8, 0xe2, 0xc5, 0xb8, 0xe6, 0xba, 0xb8, 0x16, 0xa8, 0x62, 0xb5, + 0xe0, 0x5c, 0xcb, 0x85, 0x29, 0x5c, 0xf3, 0x70, 0x89, 0xd1, 0x99, 0x46, + 0xee, 0x75, 0xfc, 0x29, 0x9c, 0xe9, 0xbf, 0xbe, 0x37, 0xad, 0x3d, 0x26, + 0xd9, 0x10, 0x3b, 0x2e, 0xf2, 0x8d, 0x7d, 0x75, 0x5c, 0xda, 0x77, 0xf0, + 0xd5, 0x71, 0x61, 0x37, 0x52, 0x01, 0xc1, 0x6c, 0x51, 0x41, 0xdf, 0x30, + 0x0c, 0xc0, 0xcd, 0x9e, 0x65, 0x18, 0x80, 0xbb, 0xcb, 0xaf, 0x19, 0x06, + 0x54, 0xbd, 0xe4, 0xef, 0x16, 0x07, 0x58, 0x34, 0x2a, 0xfe, 0x3e, 0x81, + 0x00, 0xbe, 0x4b, 0xf3, 0x9b, 0xb1, 0xe2, 0x96, 0xd0, 0x38, 0xd7, 0x9d, + 0xb0, 0x2e, 0xc1, 0xf7, 0x66, 0x3f, 0x7c, 0xce, 0x57, 0xc0, 0xe4, 0x31, + 0xa1, 0x44, 0x8b, 0x17, 0x8f, 0x5e, 0xec, 0xef, 0x31, 0xe9, 0x49, 0xfd, + 0x50, 0x79, 0x67, 0x5a, 0x96, 0xd4, 0xd5, 0x75, 0x74, 0x80, 0x76, 0x13, + 0x65, 0x8b, 0x86, 0x87, 0x1d, 0x36, 0x8b, 0x6c, 0x50, 0x16, 0xcc, 0x30, + 0xca, 0x2c, 0x75, 0x8a, 0x02, 0x73, 0xe1, 0x3b, 0xb7, 0x10, 0xdc, 0x84, + 0xa5, 0x0f, 0xef, 0x22, 0x2f, 0x06, 0x6e, 0x5f, 0x5b, 0x74, 0xdd, 0x3e, + 0x89, 0x14, 0x0c, 0xe4, 0xd1, 0x0b, 0x52, 0xc2, 0x5a, 0x99, 0xf2, 0x4f, + 0x16, 0xb6, 0x94, 0x24, 0x8f, 0x41, 0x3a, 0x7f, 0x00, 0xb0, 0xe3, 0x8e, + 0x6a, 0x7e, 0xe3, 0x3a, 0xcf, 0xf6, 0x91, 0x0d, 0xb3, 0x34, 0xfb, 0x2b, + 0xd6, 0xc2, 0xb3, 0xdc, 0x02, 0xb5, 0x51, 0xeb, 0xf2, 0xab, 0x88, 0xb0, + 0xe7, 0x5e, 0x79, 0x8d, 0x24, 0x80, 0xa0, 0xb2, 0x5f, 0x5f, 0x2d, 0xcc, + 0x6c, 0x55, 0x02, 0x9f, 0x57, 0x88, 0x33, 0x95, 0x63, 0x2e, 0x3c, 0xae, + 0xba, 0xa4, 0x9f, 0xc9, 0x67, 0x28, 0x21, 0xcf, 0x10, 0xb3, 0xbd, 0xf9, + 0x3f, 0xdb, 0x80, 0x35, 0x99, 0x65, 0xed, 0x54, 0x56, 0xd4, 0x27, 0x2a, + 0x6d, 0x4c, 0xf6, 0xc8, 0xe8, 0x9c, 0x3f, 0x32, 0x0a, 0x7f, 0x43, 0xcb, + 0x22, 0x73, 0xdf, 0x34, 0xd8, 0x55, 0x5a, 0x53, 0xed, 0xb0, 0x42, 0x81, + 0xdb, 0xb8, 0x40, 0x80, 0x8c, 0xbb, 0x5c, 0x7c, 0x6b, 0x14, 0x63, 0x2b, + 0x15, 0xf3, 0x76, 0x0b, 0x02, 0xb1, 0xbf, 0x1a, 0xcf, 0x6c, 0xee, 0xe0, + 0x36, 0x89, 0xf4, 0x25, 0x66, 0x8b, 0x48, 0xbf, 0xba, 0xbc, 0xc6, 0x0c, + 0xeb, 0xe2, 0x47, 0x30, 0xdf, 0x35, 0xc3, 0xf0, 0x07, 0xa5, 0x18, 0x2c, + 0xb2, 0x01, 0xcd, 0x53, 0x0c, 0x7c, 0x24, 0x23, 0xf5, 0x32, 0x60, 0xc5, + 0xeb, 0xb9, 0x16, 0x37, 0x5d, 0x3e, 0xfe, 0x8b, 0xe7, 0x1b, 0x76, 0x49, + 0x38, 0x28, 0x7c, 0x73, 0x64, 0x87, 0x40, 0xfb, 0x84, 0x83, 0x4d, 0x72, + 0xa0, 0x69, 0xc2, 0xa1, 0x21, 0xd7, 0xfe, 0xd2, 0xd9, 0x87, 0x5d, 0xd3, + 0x0f, 0x0a, 0xdf, 0x5c, 0x79, 0xe1, 0xb6, 0x59, 0xfa, 0xc1, 0x26, 0x4d, + 0xb0, 0x4b, 0xfa, 0xa1, 0x21, 0xff, 0xfe, 0x03, 0x72, 0x11, 0x7e, 0xb4, + 0xf6, 0x53, 0xd6, 0x55, 0x68, 0x87, 0x8c, 0x44, 0x31, 0x98, 0xd5, 0x94, + 0xf0, 0x7a, 0x2e, 0xbb, 0xac, 0x94, 0x5d, 0xfa, 0x10, 0x97, 0x01, 0x7c, + 0xf7, 0x4e, 0x1a, 0xee, 0x57, 0x14, 0x21, 0xca, 0x5b, 0x14, 0x83, 0x91, + 0x68, 0x16, 0x0c, 0xb6, 0xcb, 0x12, 0x16, 0x33, 0x64, 0x45, 0x5b, 0x0d, + 0x38, 0x63, 0x97, 0x2e, 0xac, 0x9b, 0xc0, 0xc6, 0x44, 0x34, 0x17, 0xd3, + 0x29, 0x05, 0xf2, 0x57, 0x2b, 0x71, 0xa6, 0xbd, 0x8b, 0xa8, 0x6a, 0x08, + 0x0a, 0xca, 0x0f, 0x22, 0x16, 0xfd, 0xae, 0x5e, 0x55, 0x6c, 0xad, 0x66, + 0x7a, 0x35, 0x5e, 0x6b, 0xb3, 0xa9, 0xec, 0x68, 0xb6, 0x34, 0x3b, 0xbe, + 0xdb, 0x4e, 0xb6, 0xb3, 0x0c, 0xd8, 0x52, 0x73, 0xc8, 0xfc, 0x46, 0x4d, + 0x18, 0x90, 0xf5, 0x59, 0x9e, 0x82, 0xd8, 0xce, 0x66, 0x63, 0x53, 0x77, + 0x90, 0x16, 0x95, 0xa4, 0x8d, 0x97, 0x68, 0x79, 0x84, 0xd0, 0x60, 0x42, + 0x9b, 0x55, 0x1a, 0x04, 0xa7, 0x41, 0xf6, 0xbb, 0x5f, 0x04, 0x03, 0x96, + 0x45, 0x25, 0x35, 0x1b, 0xd4, 0xd2, 0xf3, 0x9c, 0x6b, 0x51, 0x54, 0x5d, + 0xdd, 0x5e, 0x95, 0x7c, 0xcf, 0xf2, 0xda, 0xaa, 0xac, 0x99, 0x2c, 0x75, + 0x59, 0x00, 0x2b, 0x73, 0xe4, 0x3a, 0x1f, 0x58, 0xa3, 0x75, 0x71, 0x85, + 0x0e, 0x2b, 0xe7, 0x91, 0x83, 0x74, 0x78, 0x17, 0x87, 0x0f, 0x9e, 0xd8, + 0x45, 0xc0, 0x0c, 0xbe, 0x85, 0xc2, 0xdf, 0x3d, 0xb3, 0xce, 0xfe, 0x19, + 0x78, 0x1b, 0x05, 0xe7, 0x45, 0x62, 0x05, 0x7c, 0x07, 0x85, 0xe7, 0xf1, + 0x62, 0x06, 0xdd, 0xb5, 0x81, 0x76, 0x67, 0xce, 0x81, 0xf8, 0xbf, 0x62, + 0x9c, 0x7c, 0x8d, 0xc4, 0xd8, 0x1e, 0x73, 0x12, 0xdc, 0x87, 0x3c, 0x82, + 0x4d, 0x39, 0x3f, 0x80, 0xe3, 0x01, 0x3c, 0x8e, 0xba, 0x62, 0x37, 0xa0, + 0x59, 0xcb, 0xe0, 0x5a, 0x3c, 0x78, 0xf0, 0x34, 0x66, 0xae, 0x86, 0xc7, + 0x12, 0x56, 0xe9, 0xbe, 0x88, 0x97, 0x2b, 0x48, 0x1a, 0x66, 0xc0, 0x58, + 0xac, 0x5c, 0xe4, 0xe9, 0x2b, 0xb9, 0x6c, 0x20, 0xc1, 0x82, 0x5f, 0x76, + 0x31, 0xa2, 0xff, 0x04, 0x1d, 0x03, 0x18, 0x73, 0x37, 0xe0, 0xa7, 0x17, + 0xa7, 0x0b, 0x27, 0xc1, 0xb7, 0x20, 0x01, 0x1f, 0x89, 0xb1, 0x48, 0xcb, + 0x88, 0xea, 0xf8, 0x5a, 0x9b, 0xa5, 0x56, 0x3c, 0xbe, 0x44, 0xef, 0xd4, + 0xbb, 0x10, 0x6f, 0x7a, 0xe7, 0x4d, 0xef, 0xbc, 0xe9, 0x9d, 0x37, 0xbd, + 0x03, 0xe9, 0x9d, 0x72, 0xae, 0x35, 0x6b, 0x77, 0x77, 0x4e, 0xdd, 0xab, + 0x27, 0x00, 0x85, 0x03, 0xd5, 0xc1, 0xd5, 0xe8, 0x2e, 0x96, 0x00, 0xbe, + 0xf7, 0x43, 0x3f, 0x0e, 0xe6, 0x59, 0x45, 0x2f, 0x3f, 0x4c, 0xa5, 0x81, + 0x6c, 0xba, 0xdd, 0x40, 0xba, 0x4a, 0x5e, 0xb1, 0x51, 0xb4, 0x0c, 0xd2, + 0x1b, 0xae, 0x82, 0xe2, 0xa0, 0xaa, 0x70, 0x64, 0x3e, 0x07, 0xc2, 0x51, + 0x45, 0x42, 0x77, 0x6b, 0xf0, 0x1b, 0x10, 0x25, 0xe3, 0xb9, 0x1b, 0xf6, + 0xea, 0x0f, 0x70, 0x58, 0xe6, 0xe2, 0x67, 0x88, 0x89, 0x0f, 0x1d, 0x57, + 0xb9, 0x78, 0x64, 0x9e, 0x68, 0x1c, 0x3f, 0x94, 0xdc, 0x2a, 0x92, 0x40, + 0x46, 0x91, 0x83, 0xf5, 0xba, 0x3c, 0xf0, 0x34, 0xab, 0x67, 0x91, 0xdb, + 0xa7, 0x6c, 0x14, 0x95, 0x1d, 0x3d, 0x76, 0xe1, 0x15, 0xad, 0x12, 0x2f, + 0x0d, 0x72, 0xba, 0xda, 0x28, 0x93, 0x52, 0x2f, 0x8d, 0x6a, 0xb9, 0xda, + 0x28, 0x9b, 0x8e, 0xaf, 0xcc, 0xbe, 0x15, 0xa4, 0x95, 0x52, 0x01, 0x5e, + 0x3d, 0x68, 0x20, 0xcc, 0x59, 0x52, 0xe6, 0x35, 0x64, 0xd9, 0x69, 0x26, + 0x87, 0x78, 0xc9, 0x80, 0x49, 0x0e, 0x71, 0x3d, 0x6c, 0x90, 0x43, 0xdc, + 0x10, 0x84, 0xdb, 0x75, 0x3e, 0xae, 0x03, 0xc8, 0xaf, 0xf9, 0x6e, 0xdd, + 0x9b, 0xfc, 0xfe, 0x1e, 0xf2, 0x3b, 0xf5, 0x9f, 0xd2, 0x6d, 0xec, 0xe7, + 0xe1, 0x31, 0xbb, 0xb1, 0x4a, 0x7f, 0xcf, 0x6e, 0xbd, 0x1d, 0x90, 0xc1, + 0xe9, 0xd9, 0xec, 0x72, 0x74, 0x32, 0xfc, 0xc5, 0xc1, 0xef, 0x46, 0xf8, + 0xf1, 0x9e, 0xa8, 0xcd, 0x58, 0x7b, 0xc9, 0xaf, 0xc6, 0xe7, 0xb4, 0x5b, + 0x16, 0x15, 0x58, 0xf4, 0x8b, 0x28, 0x9a, 0xec, 0x65, 0x51, 0x76, 0xf9, + 0x34, 0x26, 0xd5, 0xe7, 0xda, 0xda, 0x80, 0x08, 0x1a, 0xbd, 0xcd, 0x32, + 0xc2, 0xb4, 0x1e, 0x61, 0xab, 0x31, 0xc2, 0xa4, 0x16, 0xa1, 0x2c, 0x0d, + 0x30, 0x5f, 0x48, 0x25, 0x9f, 0x63, 0x6f, 0xa3, 0xb5, 0xd6, 0x94, 0x0c, + 0x2d, 0x5d, 0x6b, 0x03, 0xa5, 0x89, 0x0f, 0x67, 0x8d, 0xac, 0xc8, 0x78, + 0x78, 0x3d, 0xec, 0x4f, 0x51, 0xa1, 0x95, 0x03, 0x06, 0x17, 0xfd, 0xcb, + 0x6b, 0x54, 0x5c, 0x25, 0xfc, 0xe5, 0xf9, 0x78, 0x3c, 0x1a, 0xa3, 0x4e, + 0xb4, 0x1c, 0x70, 0x3c, 0x1a, 0x9f, 0x0c, 0xc7, 0xa8, 0x17, 0x5d, 0x9e, + 0x61, 0x36, 0xba, 0x1a, 0x0c, 0xab, 0xce, 0x74, 0xcd, 0x86, 0x98, 0xd6, + 0x52, 0xd1, 0x62, 0xfb, 0xbf, 0x51, 0x91, 0xb9, 0x8a, 0xb5, 0x54, 0xb4, + 0xb8, 0x34, 0xf6, 0x46, 0x45, 0x16, 0x12, 0xf8, 0x8f, 0x59, 0xc3, 0xb5, + 0x6d, 0x2c, 0xf2, 0x90, 0x70, 0xe7, 0x6a, 0xdd, 0x66, 0xa3, 0xa6, 0x9f, + 0x05, 0xfd, 0xd1, 0x63, 0x15, 0x0d, 0x6e, 0xc0, 0x07, 0x91, 0xbf, 0x5c, + 0x06, 0xf3, 0x80, 0x1d, 0x80, 0xaf, 0xa2, 0xe8, 0xd7, 0xed, 0xc6, 0xf0, + 0x45, 0xf6, 0x25, 0x56, 0xfd, 0x6d, 0x1a, 0x5d, 0x8c, 0x4e, 0x7e, 0x64, + 0xf5, 0x79, 0xe4, 0x2e, 0xa0, 0x51, 0x5a, 0x14, 0xae, 0x80, 0x57, 0xa8, + 0x2c, 0xea, 0x37, 0xd9, 0xe0, 0x64, 0xbb, 0xd9, 0xac, 0x02, 0xc8, 0x3f, + 0xc1, 0xcf, 0x2d, 0xcf, 0x3c, 0xde, 0x74, 0x38, 0xeb, 0xef, 0x6d, 0x68, + 0x12, 0x8e, 0x57, 0x08, 0xf8, 0xe9, 0xfc, 0xa1, 0x1e, 0x49, 0xc5, 0x63, + 0xaf, 0x62, 0xb9, 0x10, 0xd4, 0x85, 0x93, 0x1c, 0x16, 0xfb, 0x27, 0x37, + 0xc9, 0xee, 0x09, 0xba, 0x73, 0x24, 0x68, 0xfe, 0x02, 0x18, 0xb2, 0x75, + 0xf2, 0x01, 0xad, 0x13, 0x74, 0xd3, 0xe4, 0xa0, 0x83, 0xed, 0x1d, 0xdd, + 0x06, 0xde, 0x06, 0xdd, 0x34, 0xf9, 0x00, 0xe7, 0x04, 0x4d, 0x81, 0x48, + 0x50, 0xf1, 0xec, 0x1e, 0x9a, 0x03, 0x29, 0x3e, 0xe6, 0x21, 0xa0, 0x74, + 0xe6, 0x9d, 0x25, 0xaa, 0x99, 0x10, 0xed, 0xf6, 0xe7, 0x0e, 0x1e, 0x8f, + 0xd3, 0xc4, 0xe3, 0xc9, 0xd1, 0x24, 0x3c, 0xff, 0x16, 0xf3, 0xac, 0x1b, + 0x61, 0x17, 0xad, 0x49, 0xf9, 0x82, 0x74, 0xaf, 0x2a, 0x81, 0x75, 0x67, + 0x1a, 0x63, 0xea, 0x14, 0xc6, 0x21, 0x79, 0x64, 0xd7, 0x93, 0x59, 0x4a, + 0x21, 0xcd, 0x26, 0x52, 0xab, 0xe2, 0x91, 0x8b, 0xd2, 0xe6, 0xb5, 0x5f, + 0xde, 0xb0, 0xe3, 0x2d, 0xd6, 0x06, 0x52, 0x71, 0xf4, 0x2c, 0xce, 0x1b, + 0xd5, 0xb5, 0x7a, 0x8d, 0x52, 0x87, 0x7f, 0xfc, 0xfa, 0x1c, 0x74, 0x7d, + 0xa2, 0xe0, 0x37, 0x7e, 0x9d, 0xf5, 0x59, 0xba, 0xc2, 0x78, 0x04, 0x7f, + 0x13, 0x86, 0x32, 0x89, 0x36, 0x57, 0x1a, 0x7e, 0xec, 0x70, 0xd2, 0x9f, + 0x75, 0x45, 0x65, 0x3a, 0xa9, 0x08, 0x35, 0x2c, 0x0a, 0x10, 0x9a, 0x92, + 0xda, 0xd5, 0x49, 0x2d, 0xf7, 0x10, 0xfa, 0xb8, 0x87, 0xd2, 0xd5, 0x0a, + 0xef, 0xa7, 0x38, 0xda, 0x54, 0x05, 0x45, 0xf6, 0x81, 0x66, 0x5f, 0x36, + 0x82, 0x3b, 0x13, 0x67, 0x8f, 0xea, 0x8e, 0x01, 0x27, 0xbd, 0x8b, 0x79, + 0xfd, 0xd9, 0xd8, 0x29, 0x30, 0xd6, 0xb5, 0x1c, 0x3b, 0xa9, 0x8e, 0xed, + 0x61, 0x43, 0x33, 0xcb, 0x76, 0xb9, 0xa3, 0xad, 0xce, 0x86, 0x0f, 0xa2, + 0xf5, 0x26, 0x0a, 0x7d, 0x99, 0x3f, 0x95, 0x42, 0x5d, 0x69, 0xe9, 0x5b, + 0xeb, 0x3a, 0xc0, 0xdf, 0x81, 0x9b, 0xd6, 0xac, 0xa6, 0x5e, 0xef, 0xf7, + 0xe0, 0x56, 0x77, 0x83, 0xf1, 0x23, 0x4a, 0x4e, 0xc7, 0x4e, 0x9b, 0x40, + 0x70, 0x41, 0x34, 0x05, 0x26, 0xbd, 0xef, 0xbf, 0x03, 0x5c, 0x4c, 0xe8, + 0xa5, 0x5f, 0x70, 0x84, 0x12, 0x80, 0x2e, 0x9a, 0xfc, 0x7b, 0xeb, 0xc7, + 0x80, 0x83, 0x85, 0x7b, 0x7f, 0x6f, 0x3b, 0xe6, 0x6d, 0xc7, 0xfc, 0x09, + 0x76, 0x4c, 0x66, 0xea, 0xd5, 0xa3, 0x4b, 0xd4, 0xd1, 0x62, 0x7d, 0xcc, + 0xbe, 0x8c, 0xc6, 0xe6, 0x17, 0x92, 0x5c, 0x8b, 0x37, 0xef, 0x2e, 0xfc, + 0x6f, 0xd4, 0x20, 0x1f, 0xb0, 0x7e, 0x66, 0x2c, 0xb1, 0x38, 0x4f, 0x57, + 0xcf, 0xac, 0x41, 0x1a, 0x84, 0x0c, 0xe7, 0x4c, 0x8e, 0x8c, 0x7d, 0x95, + 0xd1, 0xbc, 0x77, 0x70, 0x03, 0x9f, 0xe3, 0xb9, 0x39, 0x9e, 0x5d, 0xf7, + 0x81, 0x96, 0xda, 0x6e, 0xb5, 0xcf, 0xb1, 0xc9, 0xb0, 0x9b, 0x6c, 0xba, + 0x5b, 0x7d, 0x3e, 0xaa, 0xb1, 0xa0, 0xd9, 0x9c, 0x52, 0xf1, 0x0b, 0x78, + 0x7c, 0x3d, 0xd0, 0x32, 0xf0, 0x13, 0xb4, 0x53, 0x76, 0xd0, 0x4a, 0x58, + 0x18, 0x58, 0xac, 0x41, 0xe9, 0x0f, 0x27, 0x4f, 0x58, 0x92, 0xde, 0x4f, + 0x3d, 0xd3, 0x21, 0x95, 0x98, 0x7f, 0x2f, 0x5a, 0xee, 0x9d, 0xf8, 0xa9, + 0x17, 0xac, 0x20, 0x4c, 0x07, 0x3d, 0x1c, 0x53, 0x10, 0x5a, 0x60, 0x72, + 0x8e, 0xdc, 0x32, 0x26, 0x80, 0x2a, 0x51, 0x2c, 0x6a, 0x9d, 0x58, 0xdb, + 0x3a, 0x6f, 0xb5, 0x79, 0xf0, 0x20, 0x4c, 0x87, 0xf8, 0xab, 0x8f, 0x1a, + 0xa2, 0x3b, 0xa5, 0x0b, 0xb5, 0x8a, 0xa7, 0x8b, 0x93, 0x59, 0xc3, 0x73, + 0x1f, 0xfb, 0x7e, 0x08, 0x21, 0xb2, 0xe8, 0x20, 0xa6, 0x21, 0x8a, 0xc1, + 0x26, 0xdd, 0x8e, 0xf5, 0xdb, 0x46, 0x13, 0x7e, 0x75, 0x70, 0x4a, 0xf8, + 0xdb, 0xa8, 0xf3, 0x68, 0xcd, 0xee, 0xac, 0xb1, 0xfb, 0x1b, 0xe0, 0xbd, + 0x48, 0xc7, 0xe2, 0xcc, 0x81, 0x63, 0x1d, 0x4e, 0x07, 0xd0, 0xab, 0x49, + 0x4e, 0xa9, 0x5e, 0x19, 0x7b, 0x14, 0x9b, 0xe3, 0xca, 0x63, 0x94, 0xaf, + 0xa4, 0xff, 0x14, 0x40, 0x0e, 0xb8, 0x45, 0x69, 0xb5, 0x86, 0xe8, 0x8b, + 0x11, 0x51, 0x45, 0xfd, 0x00, 0x1b, 0xf6, 0x31, 0xf8, 0xed, 0x37, 0xa6, + 0xd8, 0x81, 0xfc, 0x9c, 0xab, 0x37, 0xbc, 0x03, 0x83, 0xe9, 0x7c, 0xfc, + 0xad, 0x1f, 0x47, 0x68, 0x8a, 0x21, 0x07, 0x1e, 0x85, 0x3e, 0x9a, 0x5d, + 0xc8, 0x61, 0xc7, 0x4a, 0xd1, 0x84, 0x29, 0xbd, 0x90, 0xc3, 0x9e, 0x09, + 0x29, 0x44, 0x72, 0x0b, 0x39, 0xf4, 0x31, 0x97, 0x7d, 0x24, 0xbb, 0x50, + 0xd0, 0x47, 0xec, 0xb8, 0x72, 0x6a, 0xa1, 0x2e, 0xf7, 0x99, 0x4f, 0x03, + 0x50, 0xd6, 0xc1, 0x95, 0x71, 0xb1, 0x26, 0x68, 0x38, 0xee, 0x35, 0x14, + 0xe4, 0x83, 0x86, 0x5b, 0xdc, 0xb6, 0x12, 0x8f, 0x4b, 0x30, 0xc7, 0xc5, + 0xa3, 0x22, 0x76, 0xba, 0x0d, 0xb5, 0xc2, 0x70, 0x35, 0x89, 0x5b, 0x78, + 0x9b, 0x15, 0x60, 0xf8, 0x40, 0x6d, 0x7c, 0x76, 0x0c, 0xc8, 0xea, 0x81, + 0xc5, 0xf5, 0xe9, 0xdc, 0xe4, 0xab, 0x05, 0x20, 0xca, 0x61, 0xde, 0x81, + 0xc5, 0x43, 0xbf, 0xa2, 0x8f, 0x28, 0x5f, 0x5c, 0xf1, 0x11, 0x8a, 0x3b, + 0x88, 0x6b, 0x4f, 0xb5, 0x11, 0x29, 0x80, 0xe1, 0x10, 0x77, 0xa5, 0x94, + 0x77, 0xf4, 0x00, 0x04, 0x1d, 0x0b, 0x45, 0xc7, 0xd3, 0x5c, 0x79, 0x73, + 0xd4, 0xf7, 0xdd, 0xf6, 0x1e, 0x2b, 0x15, 0xa2, 0x36, 0x81, 0x97, 0xda, + 0xc8, 0x07, 0x3e, 0x94, 0xf7, 0x5c, 0x6c, 0xda, 0x2e, 0x66, 0xc4, 0xe5, + 0x69, 0x27, 0x7e, 0xcf, 0x55, 0x1a, 0x70, 0x76, 0xa8, 0x5c, 0x76, 0x15, + 0xeb, 0x6f, 0x9f, 0x05, 0xab, 0xb4, 0xb6, 0x15, 0x1f, 0x8b, 0x12, 0x32, + 0xa0, 0x1d, 0x1d, 0x3d, 0xeb, 0xa7, 0x3e, 0x3b, 0x8a, 0x19, 0xa9, 0xde, + 0x0d, 0x6d, 0xee, 0x22, 0x3a, 0xad, 0x57, 0x74, 0x11, 0x9d, 0xd6, 0xeb, + 0xb8, 0x88, 0x4e, 0xeb, 0xe5, 0x2e, 0xa2, 0x95, 0x91, 0xad, 0x73, 0xce, + 0x1c, 0x8b, 0x46, 0x9c, 0x85, 0x6f, 0x05, 0x0d, 0xb7, 0xd8, 0xc0, 0x75, + 0xf6, 0xca, 0x39, 0x7c, 0xb3, 0x57, 0xdf, 0xc9, 0x5e, 0xe1, 0x8c, 0xad, + 0xb5, 0x57, 0xce, 0x8b, 0xec, 0xd5, 0x01, 0x6e, 0x2d, 0x87, 0x4f, 0x29, + 0xab, 0xd8, 0x87, 0x9a, 0x08, 0x7c, 0x17, 0xcb, 0xf2, 0x66, 0x58, 0x5e, + 0xc7, 0xb0, 0x34, 0x2d, 0x15, 0x1e, 0x53, 0xd5, 0x11, 0x27, 0xec, 0x91, + 0x29, 0xea, 0xe6, 0xb3, 0x96, 0x0f, 0x6a, 0xf0, 0x50, 0x65, 0x3e, 0xae, + 0xa9, 0xfb, 0x1f, 0x4f, 0xc6, 0xd5, 0x71, 0xb8, 0x52, 0x86, 0xdd, 0x18, + 0xbc, 0x06, 0xaf, 0x79, 0x90, 0x82, 0x2b, 0x76, 0xbb, 0xb0, 0xe2, 0x75, + 0x82, 0x8a, 0x66, 0x49, 0x9a, 0xfc, 0x30, 0xc4, 0xce, 0x68, 0x67, 0xbc, + 0x9c, 0xf3, 0x40, 0xb0, 0xaf, 0x86, 0xb8, 0xda, 0x85, 0x25, 0xeb, 0xd0, + 0x54, 0x20, 0x3a, 0x36, 0xbc, 0xd9, 0x54, 0xb5, 0x76, 0xf5, 0x78, 0xce, + 0xd4, 0x10, 0x57, 0x41, 0x74, 0x64, 0x1d, 0x72, 0x0b, 0x3c, 0x63, 0xa9, + 0xa5, 0x14, 0x2c, 0x5d, 0x8b, 0xc4, 0x48, 0x5e, 0x3c, 0xdb, 0x0f, 0x83, + 0x24, 0x4a, 0xe3, 0x68, 0x53, 0xa4, 0x6f, 0x15, 0x3c, 0xb8, 0xaa, 0xd5, + 0xe2, 0x6d, 0xb8, 0x34, 0x43, 0x2a, 0x8b, 0x2a, 0x30, 0x84, 0x92, 0xd7, + 0x38, 0x9c, 0x67, 0x9b, 0x11, 0xd8, 0x86, 0x78, 0x98, 0xcd, 0x31, 0x00, + 0xca, 0x5f, 0xa6, 0xd0, 0x64, 0x25, 0x89, 0x71, 0xfc, 0x14, 0x18, 0xef, + 0x34, 0x18, 0x3f, 0xa9, 0x8e, 0x97, 0x69, 0x33, 0x6d, 0x7c, 0xc3, 0xac, + 0x53, 0xab, 0x92, 0xe0, 0x31, 0x3b, 0x46, 0x40, 0xaa, 0x48, 0xbd, 0x3c, + 0x57, 0xb0, 0xb7, 0xbd, 0x43, 0xce, 0x49, 0xa9, 0xd5, 0x2e, 0xe3, 0x81, + 0x55, 0x1c, 0x39, 0x31, 0xb9, 0xc1, 0x16, 0x56, 0xd5, 0x36, 0x86, 0x2c, + 0x58, 0x6c, 0x17, 0x41, 0x4a, 0xf1, 0x37, 0x76, 0xc2, 0xc7, 0xf5, 0xf0, + 0x25, 0xd5, 0x75, 0x4b, 0x1e, 0x80, 0x90, 0x2b, 0x9f, 0xce, 0xb9, 0x9b, + 0xe6, 0xbd, 0xe4, 0x17, 0xa8, 0xeb, 0xb1, 0xe0, 0x8a, 0xf7, 0xd2, 0xbb, + 0x47, 0xb1, 0xa0, 0x7a, 0xd7, 0x0f, 0xa9, 0x66, 0xd0, 0x2d, 0xee, 0x89, + 0x97, 0x7a, 0x59, 0xbe, 0xbd, 0x78, 0xd9, 0xe1, 0xbf, 0xf6, 0xf6, 0x7e, + 0xf8, 0xc7, 0x3a, 0x4a, 0xd2, 0xec, 0x09, 0xcc, 0x84, 0x3c, 0xf8, 0x31, + 0xbb, 0x01, 0xf3, 0x8d, 0xfa, 0x5e, 0xec, 0x3e, 0x78, 0xfa, 0xe0, 0xf3, + 0xa7, 0xb6, 0xd8, 0x8b, 0x18, 0x3f, 0x92, 0x7e, 0xfe, 0x2b, 0xfe, 0x50, + 0x06, 0xfb, 0xdd, 0x4f, 0x3f, 0xfc, 0x63, 0xf8, 0x34, 0xa7, 0x9c, 0xa5, + 0xfc, 0x49, 0x48, 0x18, 0xa5, 0xfe, 0xe2, 0x27, 0x8e, 0xba, 0x78, 0xcc, + 0x03, 0xaa, 0xb5, 0x50, 0x3e, 0x85, 0x8c, 0x7b, 0x55, 0xc7, 0xdb, 0x62, + 0x10, 0x99, 0x5c, 0x8d, 0xc6, 0x97, 0x55, 0x3f, 0x1c, 0x1f, 0x7a, 0xd6, + 0xab, 0x7a, 0xe4, 0x36, 0xa3, 0x4a, 0x33, 0xb6, 0x1a, 0x8c, 0x3d, 0xee, + 0xf7, 0x80, 0x12, 0x2f, 0xab, 0x71, 0xa5, 0x59, 0x3b, 0x4d, 0x46, 0x77, + 0xba, 0x1d, 0xad, 0x94, 0x45, 0xf4, 0xb6, 0x3f, 0x66, 0x4c, 0xcc, 0x79, + 0xda, 0x80, 0x4f, 0xf4, 0x6b, 0xda, 0xda, 0x5d, 0x1f, 0x81, 0xae, 0xcf, + 0x70, 0xfd, 0x48, 0xa5, 0x85, 0xcb, 0x44, 0x13, 0x74, 0x9d, 0x59, 0xdf, + 0x29, 0x10, 0xf6, 0x5e, 0x01, 0xa1, 0x73, 0x30, 0xeb, 0xbb, 0x05, 0xc6, + 0xa3, 0x02, 0xe3, 0x58, 0x60, 0xec, 0x37, 0xc5, 0xc8, 0x54, 0x76, 0x2e, + 0x5f, 0x0d, 0x64, 0xd3, 0xe9, 0x96, 0x85, 0xb3, 0x89, 0x74, 0xaa, 0x93, + 0x36, 0x91, 0xcf, 0xea, 0xac, 0xcd, 0x24, 0x54, 0x9d, 0xb7, 0x99, 0x8c, + 0x56, 0x67, 0x6e, 0x20, 0xa5, 0x4e, 0xf7, 0x54, 0x8e, 0xeb, 0x36, 0x5a, + 0xaf, 0x32, 0xf0, 0xb0, 0xe1, 0x07, 0x2b, 0x43, 0x7b, 0x0d, 0xbe, 0xd5, + 0x39, 0x9d, 0x9d, 0xb1, 0xff, 0xa1, 0x92, 0xa6, 0x60, 0x38, 0x6a, 0x32, + 0xf9, 0xd1, 0x6c, 0x28, 0x37, 0xa5, 0x6b, 0x2f, 0x55, 0x27, 0xc3, 0xeb, + 0xe9, 0x47, 0x32, 0x18, 0x5d, 0x5e, 0x2b, 0x8c, 0x72, 0xed, 0x05, 0x4b, + 0x8e, 0x77, 0xe5, 0x2e, 0x76, 0xed, 0x05, 0x4c, 0x8e, 0x6f, 0xb9, 0x72, + 0xed, 0xae, 0xbd, 0x8c, 0x71, 0x04, 0x6e, 0x7b, 0xf6, 0x45, 0x51, 0xbf, + 0xed, 0x62, 0x8b, 0x7e, 0x11, 0x5b, 0xf4, 0xa4, 0xe9, 0x16, 0x55, 0xd6, + 0xd2, 0x44, 0xe8, 0xe4, 0x28, 0x29, 0x72, 0xec, 0x33, 0xf2, 0xfb, 0x36, + 0xdb, 0x50, 0x58, 0x60, 0xea, 0xc3, 0xf1, 0x9b, 0x1a, 0x79, 0xe5, 0xa6, + 0xf5, 0x87, 0x4d, 0x94, 0x55, 0x1e, 0x62, 0x53, 0x88, 0x7b, 0x1d, 0xcd, + 0xe7, 0x50, 0x25, 0xa1, 0x87, 0x4d, 0x22, 0xce, 0x71, 0x1b, 0x4f, 0x32, + 0xd6, 0xd8, 0x7d, 0x84, 0xcd, 0xc2, 0xb2, 0x04, 0xbb, 0xcc, 0x72, 0xa6, + 0x4e, 0xd3, 0x3a, 0x40, 0x29, 0xe6, 0xee, 0xc6, 0x16, 0xb6, 0xfb, 0xb5, + 0x99, 0x94, 0x62, 0x68, 0x8b, 0xb1, 0xbd, 0xd9, 0x70, 0x3a, 0x90, 0x16, + 0xa6, 0xd5, 0x44, 0x3f, 0xd3, 0xc1, 0xd7, 0x37, 0x57, 0x83, 0x8f, 0xd3, + 0x8f, 0xe3, 0xd1, 0xcd, 0xd9, 0xc7, 0x59, 0xff, 0xe2, 0xfa, 0xa3, 0x62, + 0xff, 0x5a, 0xad, 0x06, 0x5f, 0xe2, 0x38, 0xb3, 0x61, 0x7f, 0x20, 0xc7, + 0xda, 0xeb, 0xeb, 0xc9, 0xf9, 0xd9, 0xd5, 0xf0, 0x64, 0x56, 0xc1, 0xd0, + 0xc4, 0xaf, 0x28, 0x8f, 0xb5, 0xd7, 0xda, 0xf9, 0xec, 0x15, 0x14, 0x87, + 0x8d, 0xd8, 0xd0, 0x17, 0x7c, 0xd0, 0x51, 0xd8, 0xeb, 0xf1, 0xaf, 0x83, + 0xe3, 0xc1, 0x78, 0x76, 0x71, 0x73, 0xd9, 0x97, 0xa3, 0xed, 0x75, 0xb8, + 0x18, 0xdd, 0x76, 0x0f, 0x66, 0x03, 0xca, 0x49, 0x05, 0x47, 0xfb, 0xc0, + 0x7e, 0x11, 0xc7, 0x03, 0xc9, 0xf9, 0xb6, 0xfd, 0x97, 0x1f, 0x2b, 0xc2, + 0xd7, 0xb6, 0xff, 0xe4, 0xe3, 0x41, 0x4b, 0x3a, 0x90, 0x0d, 0xbe, 0xb2, + 0x3f, 0x99, 0x0e, 0x66, 0xed, 0x27, 0xa9, 0x63, 0xbb, 0xf6, 0x82, 0xc6, + 0xc7, 0x76, 0xd4, 0xb1, 0xf6, 0x22, 0x96, 0x8d, 0x55, 0x9c, 0x57, 0x7b, + 0x11, 0xe3, 0x63, 0xbb, 0xea, 0x58, 0x7b, 0xdf, 0x20, 0x1b, 0x2b, 0xb5, + 0x6a, 0xd7, 0x9e, 0x35, 0x7c, 0x6c, 0x4f, 0x9d, 0xd7, 0x9e, 0x3f, 0xd9, + 0x58, 0x39, 0xef, 0xa1, 0xbd, 0x5f, 0x90, 0x8d, 0x95, 0xe6, 0xe6, 0xd0, + 0xde, 0x27, 0xe0, 0x63, 0x9d, 0x03, 0xe5, 0xa3, 0x0f, 0xed, 0x35, 0x5a, + 0x3e, 0x58, 0xf9, 0x6a, 0x7b, 0x67, 0x20, 0x1f, 0xac, 0x7c, 0x76, 0x43, + 0xd1, 0xa2, 0x83, 0xd5, 0xd6, 0x03, 0x0d, 0x85, 0xcb, 0x71, 0xb5, 0xd1, + 0x0d, 0xc5, 0x8b, 0x8d, 0x96, 0x1b, 0xf1, 0xb0, 0x89, 0xf2, 0xea, 0x9d, + 0xcb, 0xf8, 0xa4, 0x81, 0xb7, 0xdb, 0xbb, 0x51, 0xc6, 0x35, 0x71, 0x76, + 0xd5, 0xf9, 0x1a, 0x78, 0xba, 0x67, 0xda, 0x84, 0x8d, 0x1c, 0xdc, 0xbe, + 0x32, 0x25, 0x3b, 0x2a, 0x69, 0x34, 0xf4, 0x46, 0x1d, 0xdb, 0xc4, 0x36, + 0x3b, 0x5d, 0x75, 0x64, 0x03, 0xbb, 0xec, 0x74, 0xb5, 0x39, 0x9b, 0xc4, + 0x4c, 0xfa, 0x9c, 0x4d, 0x62, 0xa6, 0xd2, 0xa4, 0x8d, 0x82, 0xfa, 0xbe, + 0x3e, 0x6d, 0x93, 0x90, 0x89, 0x8d, 0xd5, 0x26, 0x6e, 0x22, 0xb9, 0x2d, + 0x57, 0x1d, 0xd9, 0x40, 0x96, 0x5a, 0xae, 0x36, 0x67, 0x13, 0x61, 0xd2, + 0xe6, 0x6c, 0x12, 0x82, 0x9f, 0xe9, 0x93, 0x36, 0x0a, 0xc0, 0x99, 0x87, + 0xa8, 0x8e, 0x6d, 0xe4, 0xe4, 0xf5, 0x4b, 0x13, 0x37, 0x8a, 0xc1, 0x79, + 0xfe, 0x42, 0x1b, 0xde, 0xce, 0x18, 0xf4, 0xf3, 0x3e, 0x4b, 0xe8, 0xfd, + 0xeb, 0x87, 0x9f, 0xf7, 0xbf, 0xcd, 0x9f, 0xd6, 0xab, 0x7f, 0xfd, 0xf0, + 0xff, 0x01, 0x87, 0x8b, 0x46, 0xb8, }; diff --git a/lib/mesa/src/broadcom/cle/v3dx_pack.h b/lib/mesa/src/broadcom/cle/v3dx_pack.h new file mode 100644 index 000000000..5762e5aaa --- /dev/null +++ b/lib/mesa/src/broadcom/cle/v3dx_pack.h @@ -0,0 +1,44 @@ +/* + * Copyright © 2015 Intel Corporation + * Copyright © 2015 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef V3DX_PACK_H +#define V3DX_PACK_H + +#ifndef V3D_VERSION +# error "The V3D_VERSION macro must be defined" +#endif + +#if (V3D_VERSION == 21) +# include "cle/v3d_packet_v21_pack.h" +#elif (V3D_VERSION == 33) +# include "cle/v3d_packet_v33_pack.h" +#elif (V3D_VERSION == 41) +# include "cle/v3d_packet_v41_pack.h" +#elif (V3D_VERSION == 42) +# include "cle/v3d_packet_v42_pack.h" +#else +# error "Need to add a pack header include for this v3d version" +#endif + +#endif /* V3DX_PACK_H */ diff --git a/lib/mesa/src/broadcom/clif/clif_dump.c b/lib/mesa/src/broadcom/clif/clif_dump.c index 339fc3835..2bc73e60f 100644 --- a/lib/mesa/src/broadcom/clif/clif_dump.c +++ b/lib/mesa/src/broadcom/clif/clif_dump.c @@ -24,61 +24,15 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "drm-uapi/v3d_drm.h" #include "clif_dump.h" +#include "clif_private.h" #include "util/list.h" #include "util/ralloc.h" #include "broadcom/cle/v3d_decoder.h" -#define __gen_user_data void -#define __gen_address_type uint32_t -#define __gen_address_offset(reloc) (*reloc) -#define __gen_emit_reloc(cl, reloc) -#define __gen_unpack_address(cl, s, e) (__gen_unpack_uint(cl, s, e) << (31 - (e - s))) - -enum reloc_worklist_type { - reloc_gl_shader_state, -}; - -struct reloc_worklist_entry { - struct list_head link; - - enum reloc_worklist_type type; - uint32_t addr; - - union { - struct { - uint32_t num_attrs; - } shader_state; - }; -}; - -struct clif_dump { - const struct v3d_device_info *devinfo; - bool (*lookup_vaddr)(void *data, uint32_t addr, void **vaddr); - FILE *out; - /* Opaque data from the caller that is passed to the callbacks. */ - void *data; - - struct v3d_spec *spec; - - /* List of struct reloc_worklist_entry */ - struct list_head worklist; -}; - -static void -out(struct clif_dump *clif, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vfprintf(clif->out, fmt, args); - va_end(args); -} - -#include "broadcom/cle/v3d_packet_v33_pack.h" - -static struct reloc_worklist_entry * +struct reloc_worklist_entry * clif_dump_add_address_to_worklist(struct clif_dump *clif, enum reloc_worklist_type type, uint32_t addr) @@ -98,17 +52,14 @@ clif_dump_add_address_to_worklist(struct clif_dump *clif, struct clif_dump * clif_dump_init(const struct v3d_device_info *devinfo, - FILE *out, - bool (*lookup_vaddr)(void *data, uint32_t addr, void **vaddr), - void *data) + FILE *out, bool pretty) { struct clif_dump *clif = rzalloc(NULL, struct clif_dump); clif->devinfo = devinfo; - clif->lookup_vaddr = lookup_vaddr; clif->out = out; - clif->data = data; clif->spec = v3d_spec_load(devinfo); + clif->pretty = pretty; list_inithead(&clif->worklist); @@ -121,85 +72,92 @@ clif_dump_destroy(struct clif_dump *clif) ralloc_free(clif); } -#define out_uint(_clif, field) out(_clif, " /* %s = */ %u\n", \ - #field, values-> field); +struct clif_bo * +clif_lookup_bo(struct clif_dump *clif, uint32_t addr) +{ + for (int i = 0; i < clif->bo_count; i++) { + struct clif_bo *bo = &clif->bo[i]; + + if (addr >= bo->offset && + addr < bo->offset + bo->size) { + return bo; + } + } + + return NULL; +} static bool -clif_dump_packet(struct clif_dump *clif, uint32_t offset, const uint8_t *cl, - uint32_t *size) +clif_lookup_vaddr(struct clif_dump *clif, uint32_t addr, void **vaddr) { - struct v3d_group *inst = v3d_spec_find_instruction(clif->spec, cl); - if (!inst) { - out(clif, "0x%08x: Unknown packet %d!\n", offset, *cl); + struct clif_bo *bo = clif_lookup_bo(clif, addr); + if (!bo) return false; - } - *size = v3d_group_get_length(inst); + *vaddr = bo->vaddr + addr - bo->offset; + return true; +} - out(clif, "%s\n", v3d_group_get_name(inst)); - v3d_print_group(clif->out, inst, 0, cl, ""); +#define out_uint(_clif, field) out(_clif, " /* %s = */ %u\n", \ + #field, values-> field); - switch (*cl) { - case V3D33_GL_SHADER_STATE_opcode: { - struct V3D33_GL_SHADER_STATE values; - V3D33_GL_SHADER_STATE_unpack(cl, &values); +static bool +clif_dump_packet(struct clif_dump *clif, uint32_t offset, const uint8_t *cl, + uint32_t *size, bool reloc_mode) +{ + if (clif->devinfo->ver >= 41) + return v3d41_clif_dump_packet(clif, offset, cl, size, reloc_mode); + else + return v3d33_clif_dump_packet(clif, offset, cl, size, reloc_mode); +} - struct reloc_worklist_entry *reloc = - clif_dump_add_address_to_worklist(clif, - reloc_gl_shader_state, - values.address); - if (reloc) { - reloc->shader_state.num_attrs = - values.number_of_attribute_arrays; - } - return true; +static uint32_t +clif_dump_cl(struct clif_dump *clif, uint32_t start, uint32_t end, + bool reloc_mode) +{ + struct clif_bo *bo = clif_lookup_bo(clif, start); + if (!bo) { + out(clif, "Failed to look up address 0x%08x\n", + start); + return 0; } - case V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_opcode: { - struct V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED values; - V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_unpack(cl, &values); + void *start_vaddr = bo->vaddr + start - bo->offset; - if (values.last_tile_of_frame) - return false; - break; + /* The end address is optional (for example, a BRANCH instruction + * won't set an end), but is used for BCL/RCL termination. + */ + void *end_vaddr = NULL; + if (end && !clif_lookup_vaddr(clif, end, &end_vaddr)) { + out(clif, "Failed to look up address 0x%08x\n", + end); + return 0; } - case V3D33_TRANSFORM_FEEDBACK_ENABLE_opcode: { - struct V3D33_TRANSFORM_FEEDBACK_ENABLE values; - V3D33_TRANSFORM_FEEDBACK_ENABLE_unpack(cl, &values); - struct v3d_group *spec = v3d_spec_find_struct(clif->spec, - "Transform Feedback Output Data Spec"); - struct v3d_group *addr = v3d_spec_find_struct(clif->spec, - "Transform Feedback Output Address"); - assert(spec); - assert(addr); - - cl += *size; - - for (int i = 0; i < values.number_of_16_bit_output_data_specs_following; i++) { - v3d_print_group(clif->out, spec, 0, cl, ""); - cl += v3d_group_get_length(spec); - *size += v3d_group_get_length(spec); - } + if (!reloc_mode) + out(clif, "@format ctrllist /* [%s+0x%08x] */\n", + bo->name, start - bo->offset); - for (int i = 0; i < values.number_of_32_bit_output_buffer_address_following; i++) { - v3d_print_group(clif->out, addr, 0, cl, ""); - cl += v3d_group_get_length(addr); - *size += v3d_group_get_length(addr); - } - break; - } + uint32_t size; + uint8_t *cl = start_vaddr; + while (clif_dump_packet(clif, start, cl, &size, reloc_mode)) { + cl += size; + start += size; - case V3D33_HALT_opcode: - return false; + if (cl == end_vaddr) + break; } - return true; + return (void *)cl - bo->vaddr; } -static void +/* Walks the worklist, parsing the relocs for any memory regions that might + * themselves have additional relocations. + */ +static uint32_t clif_dump_gl_shader_state_record(struct clif_dump *clif, - struct reloc_worklist_entry *reloc, void *vaddr) + struct reloc_worklist_entry *reloc, + void *vaddr) { struct v3d_group *state = v3d_spec_find_struct(clif->spec, "GL Shader State Record"); @@ -207,75 +165,280 @@ clif_dump_gl_shader_state_record(struct clif_dump *clif, "GL Shader State Attribute Record"); assert(state); assert(attr); + uint32_t offset = 0; - out(clif, "GL Shader State Record at 0x%08x\n", reloc->addr); - v3d_print_group(clif->out, state, 0, vaddr, ""); - vaddr += v3d_group_get_length(state); + out(clif, "@format shadrec_gl_main\n"); + v3d_print_group(clif, state, 0, vaddr + offset); + offset += v3d_group_get_length(state); for (int i = 0; i < reloc->shader_state.num_attrs; i++) { - out(clif, " Attribute %d\n", i); - v3d_print_group(clif->out, attr, 0, vaddr, ""); - vaddr += v3d_group_get_length(attr); + out(clif, "@format shadrec_gl_attr /* %d */\n", i); + v3d_print_group(clif, attr, 0, vaddr + offset); + offset += v3d_group_get_length(attr); } + + return offset; } static void clif_process_worklist(struct clif_dump *clif) { - while (!list_empty(&clif->worklist)) { - struct reloc_worklist_entry *reloc = - list_first_entry(&clif->worklist, - struct reloc_worklist_entry, link); - list_del(&reloc->link); - + list_for_each_entry_safe(struct reloc_worklist_entry, reloc, + &clif->worklist, link) { void *vaddr; - if (!clif->lookup_vaddr(clif->data, reloc->addr, &vaddr)) { + if (!clif_lookup_vaddr(clif, reloc->addr, &vaddr)) { out(clif, "Failed to look up address 0x%08x\n", reloc->addr); continue; } switch (reloc->type) { + case reloc_cl: + clif_dump_cl(clif, reloc->addr, reloc->cl.end, true); + break; + case reloc_gl_shader_state: - clif_dump_gl_shader_state_record(clif, reloc, vaddr); + break; + case reloc_generic_tile_list: + clif_dump_cl(clif, reloc->addr, + reloc->generic_tile_list.end, true); break; } - out(clif, "\n"); } } -void -clif_dump_add_cl(struct clif_dump *clif, uint32_t start, uint32_t end) +static int +worklist_entry_compare(const void *a, const void *b) { - uint32_t size; + return ((*(struct reloc_worklist_entry **)a)->addr - + (*(struct reloc_worklist_entry **)b)->addr); +} - void *start_vaddr; - if (!clif->lookup_vaddr(clif->data, start, &start_vaddr)) { - out(clif, "Failed to look up address 0x%08x\n", - start); - return; +static bool +clif_dump_if_blank(struct clif_dump *clif, struct clif_bo *bo, + uint32_t start, uint32_t end) +{ + for (int i = start; i < end; i++) { + if (((uint8_t *)bo->vaddr)[i] != 0) + return false; } - /* The end address is optional (for example, a BRANCH instruction - * won't set an end), but is used for BCL/RCL termination. - */ - void *end_vaddr = NULL; - if (end && !clif->lookup_vaddr(clif->data, end, &end_vaddr)) { - out(clif, "Failed to look up address 0x%08x\n", - end); + out(clif, "\n"); + out(clif, "@format blank %d /* [%s+0x%08x..0x%08x] */\n", end - start, + bo->name, start, end - 1); + return true; +} + +/* Dumps the binary data in the BO from start to end (relative to the start of + * the BO). + */ +static void +clif_dump_binary(struct clif_dump *clif, struct clif_bo *bo, + uint32_t start, uint32_t end) +{ + if (start == end) return; + + if (clif_dump_if_blank(clif, bo, start, end)) + return; + + out(clif, "@format binary /* [%s+0x%08x] */\n", + bo->name, start); + + uint32_t offset = start; + int dumped_in_line = 0; + while (offset < end) { + if (clif_dump_if_blank(clif, bo, offset, end)) + return; + + if (end - offset >= 4) { + out(clif, "0x%08x ", *(uint32_t *)(bo->vaddr + offset)); + offset += 4; + } else { + out(clif, "0x%02x ", *(uint8_t *)(bo->vaddr + offset)); + offset++; + } + + if (++dumped_in_line == 8) { + out(clif, "\n"); + dumped_in_line = 0; + } } + if (dumped_in_line) + out(clif, "\n"); +} - uint8_t *cl = start_vaddr; - while (clif_dump_packet(clif, start, cl, &size)) { - cl += size; - start += size; +/* Walks the list of relocations, dumping each buffer's contents (using our + * codegenned dump routines for pretty printing, and most importantly proper + * address references so that the CLIF parser can relocate buffers). + */ +static void +clif_dump_buffers(struct clif_dump *clif) +{ + int num_relocs = 0; + list_for_each_entry(struct reloc_worklist_entry, reloc, + &clif->worklist, link) { + num_relocs++; + } + struct reloc_worklist_entry **relocs = + ralloc_array(clif, struct reloc_worklist_entry *, num_relocs); + int i = 0; + list_for_each_entry(struct reloc_worklist_entry, reloc, + &clif->worklist, link) { + relocs[i++] = reloc; + } + qsort(relocs, num_relocs, sizeof(*relocs), worklist_entry_compare); - if (cl == end_vaddr) + struct clif_bo *bo = NULL; + uint32_t offset = 0; + + for (i = 0; i < num_relocs; i++) { + struct reloc_worklist_entry *reloc = relocs[i]; + struct clif_bo *new_bo = clif_lookup_bo(clif, reloc->addr); + + if (!new_bo) { + out(clif, "Failed to look up address 0x%08x\n", + reloc->addr); + continue; + } + + if (new_bo != bo) { + if (bo) { + /* Finish out the last of the last BO. */ + clif_dump_binary(clif, bo, + offset, + bo->size); + } + + out(clif, "\n"); + out(clif, "@buffer %s\n", new_bo->name); + bo = new_bo; + offset = 0; + bo->dumped = true; + } + + int reloc_offset = reloc->addr - bo->offset; + if (offset != reloc_offset) + clif_dump_binary(clif, bo, offset, reloc_offset); + offset = reloc_offset; + + switch (reloc->type) { + case reloc_cl: + offset = clif_dump_cl(clif, reloc->addr, reloc->cl.end, + false); + out(clif, "\n"); + break; + + case reloc_gl_shader_state: + offset += clif_dump_gl_shader_state_record(clif, + reloc, + bo->vaddr + + offset); + break; + case reloc_generic_tile_list: + offset = clif_dump_cl(clif, reloc->addr, + reloc->generic_tile_list.end, + false); break; + } + out(clif, "\n"); } - out(clif, "\n"); + if (bo) { + clif_dump_binary(clif, bo, offset, bo->size); + } + + /* For any BOs that didn't have relocations, just dump them raw. */ + for (int i = 0; i < clif->bo_count; i++) { + bo = &clif->bo[i]; + if (bo->dumped) + continue; + out(clif, "@buffer %s\n", bo->name); + clif_dump_binary(clif, bo, 0, bo->size); + out(clif, "\n"); + } +} + +void +clif_dump_add_cl(struct clif_dump *clif, uint32_t start, uint32_t end) +{ + struct reloc_worklist_entry *entry = + clif_dump_add_address_to_worklist(clif, reloc_cl, start); + + entry->cl.end = end; +} + +static int +clif_bo_offset_compare(const void *a, const void *b) +{ + return ((struct clif_bo *)a)->offset - ((struct clif_bo *)b)->offset; +} +void +clif_dump(struct clif_dump *clif, const struct drm_v3d_submit_cl *submit) +{ + clif_dump_add_cl(clif, submit->bcl_start, submit->bcl_end); + clif_dump_add_cl(clif, submit->rcl_start, submit->rcl_end); + + qsort(clif->bo, clif->bo_count, sizeof(clif->bo[0]), + clif_bo_offset_compare); + + /* A buffer needs to be defined before we can emit a CLIF address + * referencing it, so emit them all now. + */ + for (int i = 0; i < clif->bo_count; i++) { + out(clif, "@createbuf_aligned 4096 %s\n", clif->bo[i].name); + } + + /* Walk the worklist figuring out the locations of structs based on + * the CL contents. + */ clif_process_worklist(clif); + + /* Dump the contents of the buffers using the relocations we found to + * pretty-print structures. + */ + clif_dump_buffers(clif); + + out(clif, "@add_bin 0\n "); + out_address(clif, submit->bcl_start); + out(clif, "\n "); + out_address(clif, submit->bcl_end); + out(clif, "\n "); + out_address(clif, submit->qma); + out(clif, "\n %d\n ", submit->qms); + out_address(clif, submit->qts); + out(clif, "\n"); + out(clif, "@wait_bin_all_cores\n"); + + out(clif, "@add_render 0\n "); + out_address(clif, submit->rcl_start); + out(clif, "\n "); + out_address(clif, submit->rcl_end); + out(clif, "\n "); + out_address(clif, submit->qma); + out(clif, "\n"); + out(clif, "@wait_render_all_cores\n"); +} + +void +clif_dump_add_bo(struct clif_dump *clif, const char *name, + uint32_t offset, uint32_t size, void *vaddr) +{ + if (clif->bo_count >= clif->bo_array_size) { + clif->bo_array_size = MAX2(4, clif->bo_array_size * 2); + clif->bo = reralloc(clif, clif->bo, struct clif_bo, + clif->bo_array_size); + } + + /* CLIF relocs use the buffer name, so make sure they're unique. */ + for (int i = 0; i < clif->bo_count; i++) + assert(strcmp(clif->bo[i].name, name) != 0); + + clif->bo[clif->bo_count].name = ralloc_strdup(clif, name); + clif->bo[clif->bo_count].offset = offset; + clif->bo[clif->bo_count].size = size; + clif->bo[clif->bo_count].vaddr = vaddr; + clif->bo[clif->bo_count].dumped = false; + clif->bo_count++; } diff --git a/lib/mesa/src/broadcom/clif/clif_dump.h b/lib/mesa/src/broadcom/clif/clif_dump.h index d46cc8471..8de3a2cbe 100644 --- a/lib/mesa/src/broadcom/clif/clif_dump.h +++ b/lib/mesa/src/broadcom/clif/clif_dump.h @@ -29,14 +29,15 @@ struct v3d_device_info; struct clif_dump; +struct drm_v3d_submit_cl; struct clif_dump *clif_dump_init(const struct v3d_device_info *devinfo, - FILE *output, - bool (*lookup_vaddr)(void *data, uint32_t addr, - void **vaddr), - void *data); + FILE *output, bool pretty); +void clif_dump(struct clif_dump *clif, const struct drm_v3d_submit_cl *submit); void clif_dump_destroy(struct clif_dump *clif); +void clif_dump_add_bo(struct clif_dump *clif, const char *name, + uint32_t offset, uint32_t size, void *vaddr); void clif_dump_add_cl(struct clif_dump *clif, uint32_t start, uint32_t end); #endif diff --git a/lib/mesa/src/broadcom/clif/clif_private.h b/lib/mesa/src/broadcom/clif/clif_private.h new file mode 100644 index 000000000..597d0b506 --- /dev/null +++ b/lib/mesa/src/broadcom/clif/clif_private.h @@ -0,0 +1,123 @@ +/* + * Copyright © 2016-2018 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CLIF_PRIVATE_H +#define CLIF_PRIVATE_H + +#include <stdint.h> +#include <stdarg.h> +#include "util/list.h" + +struct clif_bo { + const char *name; + uint32_t offset; + uint32_t size; + void *vaddr; + bool dumped; +}; + +struct clif_dump { + const struct v3d_device_info *devinfo; + FILE *out; + + struct v3d_spec *spec; + + /* List of struct reloc_worklist_entry */ + struct list_head worklist; + + struct clif_bo *bo; + int bo_count; + int bo_array_size; + + /** + * Flag to switch from CLIF ABI to slightly more human-readable + * output. + */ + bool pretty; +}; + +enum reloc_worklist_type { + reloc_cl, + reloc_gl_shader_state, + reloc_generic_tile_list, +}; + +struct reloc_worklist_entry { + struct list_head link; + + enum reloc_worklist_type type; + uint32_t addr; + + union { + struct { + uint32_t end; + } cl; + struct { + uint32_t num_attrs; + } shader_state; + struct { + uint32_t end; + } generic_tile_list; + }; +}; + +struct clif_bo * +clif_lookup_bo(struct clif_dump *clif, uint32_t addr); + +struct reloc_worklist_entry * +clif_dump_add_address_to_worklist(struct clif_dump *clif, + enum reloc_worklist_type type, + uint32_t addr); + +bool v3d33_clif_dump_packet(struct clif_dump *clif, uint32_t offset, + const uint8_t *cl, uint32_t *size, bool reloc_mode); +bool v3d41_clif_dump_packet(struct clif_dump *clif, uint32_t offset, + const uint8_t *cl, uint32_t *size, bool reloc_mode); +bool v3d42_clif_dump_packet(struct clif_dump *clif, uint32_t offset, + const uint8_t *cl, uint32_t *size, bool reloc_mode); + +static inline void +out(struct clif_dump *clif, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(clif->out, fmt, args); + va_end(args); +} + +static inline void +out_address(struct clif_dump *clif, uint32_t addr) +{ + struct clif_bo *bo = clif_lookup_bo(clif, addr); + if (bo) { + out(clif, "[%s+0x%08x] /* 0x%08x */", + bo->name, addr - bo->offset, addr); + } else if (addr) { + out(clif, "/* XXX: BO unknown */ 0x%08x", addr); + } else { + out(clif, "[null]"); + } +} + +#endif /* CLIF_PRIVATE_H */ diff --git a/lib/mesa/src/broadcom/clif/v3dx_dump.c b/lib/mesa/src/broadcom/clif/v3dx_dump.c new file mode 100644 index 000000000..9cf59f889 --- /dev/null +++ b/lib/mesa/src/broadcom/clif/v3dx_dump.c @@ -0,0 +1,174 @@ +/* + * Copyright © 2016-2018 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#include "util/macros.h" +#include "broadcom/cle/v3d_decoder.h" +#include "clif_dump.h" +#include "clif_private.h" + +#define __gen_user_data void +#define __gen_address_type uint32_t +#define __gen_address_offset(reloc) (*reloc) +#define __gen_emit_reloc(cl, reloc) +#define __gen_unpack_address(cl, s, e) (__gen_unpack_uint(cl, s, e) << (31 - (e - s))) +#include "broadcom/cle/v3dx_pack.h" +#include "broadcom/common/v3d_macros.h" + +static char * +clif_name(const char *xml_name) +{ + char *name = malloc(strlen(xml_name) + 1); + + int j = 0; + for (int i = 0; i < strlen(xml_name); i++) { + if (xml_name[i] == ' ') { + name[j++] = '_'; + } else if (xml_name[i] == '(' || xml_name[i] == ')') { + /* skip */ + } else { + name[j++] = toupper(xml_name[i]); + } + } + name[j++] = 0; + + return name; +} + +bool +v3dX(clif_dump_packet)(struct clif_dump *clif, uint32_t offset, + const uint8_t *cl, uint32_t *size, bool reloc_mode) +{ + struct v3d_group *inst = v3d_spec_find_instruction(clif->spec, cl); + if (!inst) { + out(clif, "0x%08x: Unknown packet %d!\n", offset, *cl); + return false; + } + + *size = v3d_group_get_length(inst); + + if (!reloc_mode) { + char *name = clif_name(v3d_group_get_name(inst)); + out(clif, "%s\n", name); + free(name); + v3d_print_group(clif, inst, 0, cl); + } + + switch (*cl) { + case V3DX(GL_SHADER_STATE_opcode): { + struct V3DX(GL_SHADER_STATE) values; + V3DX(GL_SHADER_STATE_unpack)(cl, &values); + + if (reloc_mode) { + struct reloc_worklist_entry *reloc = + clif_dump_add_address_to_worklist(clif, + reloc_gl_shader_state, + values.address); + if (reloc) { + reloc->shader_state.num_attrs = + values.number_of_attribute_arrays; + } + } + return true; + } + +#if V3D_VERSION < 40 + case V3DX(STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_opcode): { + struct V3DX(STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED) values; + V3DX(STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_unpack)(cl, &values); + + if (values.last_tile_of_frame) + return false; + break; + } +#endif /* V3D_VERSION < 40 */ + +#if V3D_VERSION > 40 + case V3DX(TRANSFORM_FEEDBACK_SPECS_opcode): { + struct V3DX(TRANSFORM_FEEDBACK_SPECS) values; + V3DX(TRANSFORM_FEEDBACK_SPECS_unpack)(cl, &values); + struct v3d_group *spec = v3d_spec_find_struct(clif->spec, + "Transform Feedback Output Data Spec"); + assert(spec); + + cl += *size; + + for (int i = 0; i < values.number_of_16_bit_output_data_specs_following; i++) { + if (!reloc_mode) + v3d_print_group(clif, spec, 0, cl); + cl += v3d_group_get_length(spec); + *size += v3d_group_get_length(spec); + } + if (!reloc_mode) + out(clif, "@format ctrllist\n"); + break; + } +#else /* V3D_VERSION < 40 */ + case V3DX(TRANSFORM_FEEDBACK_ENABLE_opcode): { + struct V3DX(TRANSFORM_FEEDBACK_ENABLE) values; + V3DX(TRANSFORM_FEEDBACK_ENABLE_unpack)(cl, &values); + struct v3d_group *spec = v3d_spec_find_struct(clif->spec, + "Transform Feedback Output Data Spec"); + struct v3d_group *addr = v3d_spec_find_struct(clif->spec, + "Transform Feedback Output Address"); + assert(spec); + assert(addr); + + cl += *size; + + for (int i = 0; i < values.number_of_16_bit_output_data_specs_following; i++) { + if (!reloc_mode) + v3d_print_group(clif, spec, 0, cl); + cl += v3d_group_get_length(spec); + *size += v3d_group_get_length(spec); + } + + for (int i = 0; i < values.number_of_32_bit_output_buffer_address_following; i++) { + if (!reloc_mode) + v3d_print_group(clif, addr, 0, cl); + cl += v3d_group_get_length(addr); + *size += v3d_group_get_length(addr); + } + break; + } +#endif /* V3D_VERSION < 40 */ + + case V3DX(START_ADDRESS_OF_GENERIC_TILE_LIST_opcode): { + struct V3DX(START_ADDRESS_OF_GENERIC_TILE_LIST) values; + V3DX(START_ADDRESS_OF_GENERIC_TILE_LIST_unpack)(cl, &values); + struct reloc_worklist_entry *reloc = + clif_dump_add_address_to_worklist(clif, + reloc_generic_tile_list, + values.start); + reloc->generic_tile_list.end = values.end; + break; + } + + case V3DX(HALT_opcode): + return false; + } + + return true; +} diff --git a/lib/mesa/src/broadcom/common/v3d_debug.c b/lib/mesa/src/broadcom/common/v3d_debug.c index 630bfe0fc..97404448e 100644 --- a/lib/mesa/src/broadcom/common/v3d_debug.c +++ b/lib/mesa/src/broadcom/common/v3d_debug.c @@ -41,6 +41,7 @@ uint32_t V3D_DEBUG = 0; static const struct debug_control debug_control[] = { { "cl", V3D_DEBUG_CL}, + { "clif", V3D_DEBUG_CLIF}, { "qpu", V3D_DEBUG_QPU}, { "vir", V3D_DEBUG_VIR}, { "nir", V3D_DEBUG_NIR}, @@ -52,6 +53,7 @@ static const struct debug_control debug_control[] = { { "fs", V3D_DEBUG_FS}, { "vs", V3D_DEBUG_VS}, { "cs", V3D_DEBUG_CS}, + { "always_flush", V3D_DEBUG_ALWAYS_FLUSH}, { NULL, 0 } }; diff --git a/lib/mesa/src/broadcom/common/v3d_debug.h b/lib/mesa/src/broadcom/common/v3d_debug.h index bdb951854..d9f5255e2 100644 --- a/lib/mesa/src/broadcom/common/v3d_debug.h +++ b/lib/mesa/src/broadcom/common/v3d_debug.h @@ -54,10 +54,15 @@ extern uint32_t V3D_DEBUG; #define V3D_DEBUG_PERF (1 << 10) #define V3D_DEBUG_NORAST (1 << 11) #define V3D_DEBUG_ALWAYS_FLUSH (1 << 12) +#define V3D_DEBUG_CLIF (1 << 13) #ifdef HAVE_ANDROID_PLATFORM #define LOG_TAG "BROADCOM-MESA" +#if ANDROID_API_LEVEL >= 26 +#include <log/log.h> +#else #include <cutils/log.h> +#endif /* use log/log.h start from android 8 major version */ #ifndef ALOGW #define ALOGW LOGW #endif diff --git a/lib/mesa/src/broadcom/common/v3d_macros.h b/lib/mesa/src/broadcom/common/v3d_macros.h new file mode 100644 index 000000000..fe8939820 --- /dev/null +++ b/lib/mesa/src/broadcom/common/v3d_macros.h @@ -0,0 +1,48 @@ +/* + * Copyright © 2015 Intel Corporation + * Copyright © 2015 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef V3DX_MACROS_H +#define V3DX_MACROS_H + +#ifndef V3D_VERSION +# error "The V3D_VERSION macro must be defined" +#endif + +#if (V3D_VERSION == 21) +# define V3DX(x) V3D21_##x +# define v3dX(x) v3d21_##x +#elif (V3D_VERSION == 33) +# define V3DX(x) V3D33_##x +# define v3dX(x) v3d33_##x +#elif (V3D_VERSION == 41) +# define V3DX(x) V3D41_##x +# define v3dX(x) v3d41_##x +#elif (V3D_VERSION == 42) +# define V3DX(x) V3D42_##x +# define v3dX(x) v3d42_##x +#else +# error "Need to add prefixing macros for this v3d version" +#endif + +#endif /* V3DX_MACROS_H */ diff --git a/lib/mesa/src/broadcom/compiler/meson.build b/lib/mesa/src/broadcom/compiler/meson.build new file mode 100644 index 000000000..86ef365aa --- /dev/null +++ b/lib/mesa/src/broadcom/compiler/meson.build @@ -0,0 +1,51 @@ +# Copyright © 2017 Broadcom +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libbroadcom_compiler_files = files( + 'nir_to_vir.c', + 'vir.c', + 'vir_dump.c', + 'vir_live_variables.c', + 'vir_lower_uniforms.c', + 'vir_opt_copy_propagate.c', + 'vir_opt_dead_code.c', + 'vir_opt_small_immediates.c', + 'vir_register_allocate.c', + 'vir_to_qpu.c', + 'qpu_schedule.c', + 'qpu_validate.c', + 'v3d33_tex.c', + 'v3d40_tex.c', + 'v3d33_vpm_setup.c', + 'v3d_compiler.h', + 'v3d_nir_lower_io.c', + 'v3d_nir_lower_txf_ms.c', +) + +libbroadcom_compiler = static_library( + ['broadcom_compiler', v3d_xml_pack], + libbroadcom_compiler_files, + include_directories : [inc_common, inc_broadcom], + c_args : [c_vis_args, no_override_init_args], + dependencies : [dep_libdrm, dep_valgrind, idep_nir_headers], + build_by_default : false, +) + +v3d_libs += libbroadcom_compiler diff --git a/lib/mesa/src/broadcom/compiler/nir_to_vir.c b/lib/mesa/src/broadcom/compiler/nir_to_vir.c index 3b032b704..bb41c1be9 100644 --- a/lib/mesa/src/broadcom/compiler/nir_to_vir.c +++ b/lib/mesa/src/broadcom/compiler/nir_to_vir.c @@ -29,17 +29,9 @@ #include "util/hash_table.h" #include "compiler/nir/nir.h" #include "compiler/nir/nir_builder.h" +#include "common/v3d_device_info.h" #include "v3d_compiler.h" -/* We don't do any address packing. */ -#define __gen_user_data void -#define __gen_address_type uint32_t -#define __gen_address_offset(reloc) (*reloc) -#define __gen_emit_reloc(cl, reloc) -#include "cle/v3d_packet_v33_pack.h" - -static struct qreg -ntq_get_src(struct v3d_compile *c, nir_src src, int i); static void ntq_emit_cf_list(struct v3d_compile *c, struct exec_list *list); @@ -64,18 +56,21 @@ resize_qreg_array(struct v3d_compile *c, (*regs)[i] = c->undef; } -static struct qreg -vir_SFU(struct v3d_compile *c, int waddr, struct qreg src) +void +vir_emit_thrsw(struct v3d_compile *c) { - vir_FMOV_dest(c, vir_reg(QFILE_MAGIC, waddr), src); - return vir_FMOV(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R4)); -} + if (c->threads == 1) + return; -static struct qreg -vir_LDTMU(struct v3d_compile *c) -{ - vir_NOP(c)->qpu.sig.ldtmu = true; - return vir_MOV(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R4)); + /* Always thread switch after each texture operation for now. + * + * We could do better by batching a bunch of texture fetches up and + * then doing one thread switch and collecting all their results + * afterward. + */ + c->last_thrsw = vir_NOP(c); + c->last_thrsw->qpu.sig.thrsw = true; + c->last_thrsw_at_top_level = (c->execute.file == QFILE_NULL); } static struct qreg @@ -117,6 +112,7 @@ indirect_uniform_load(struct v3d_compile *c, nir_intrinsic_instr *intr) vir_uniform(c, QUNIFORM_UBO_ADDR, 0), indirect_offset); + vir_emit_thrsw(c); return vir_LDTMU(c); } @@ -144,7 +140,7 @@ ntq_init_ssa_def(struct v3d_compile *c, nir_ssa_def *def) * (knowing that the previous instruction doesn't depend on flags) and rewrite * its destination to be the NIR reg's destination */ -static void +void ntq_store_dest(struct v3d_compile *c, nir_dest *dest, int chan, struct qreg result) { @@ -195,14 +191,11 @@ ntq_store_dest(struct v3d_compile *c, nir_dest *dest, int chan, if (c->execute.file != QFILE_NULL) { last_inst->dst.index = qregs[chan].index; - /* Set the flags to the current exec mask. To insert - * the flags push, we temporarily remove our SSA - * instruction. + /* Set the flags to the current exec mask. */ - list_del(&last_inst->link); + c->cursor = vir_before_inst(last_inst); vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ); - list_addtail(&last_inst->link, - &c->cur_block->instructions); + c->cursor = vir_after_inst(last_inst); vir_set_cond(last_inst, V3D_QPU_COND_IFA); last_inst->cond_is_exec_mask = true; @@ -210,7 +203,7 @@ ntq_store_dest(struct v3d_compile *c, nir_dest *dest, int chan, } } -static struct qreg +struct qreg ntq_get_src(struct v3d_compile *c, nir_src src, int i) { struct hash_entry *entry; @@ -233,7 +226,7 @@ static struct qreg ntq_get_alu_src(struct v3d_compile *c, nir_alu_instr *instr, unsigned src) { - assert(util_is_power_of_two(instr->dest.write_mask)); + assert(util_is_power_of_two_or_zero(instr->dest.write_mask)); unsigned chan = ffs(instr->dest.write_mask) - 1; struct qreg r = ntq_get_src(c, instr->src[src].src, instr->src[src].swizzle[chan]); @@ -244,21 +237,6 @@ ntq_get_alu_src(struct v3d_compile *c, nir_alu_instr *instr, return r; }; -static inline struct qreg -vir_SAT(struct v3d_compile *c, struct qreg val) -{ - return vir_FMAX(c, - vir_FMIN(c, val, vir_uniform_f(c, 1.0)), - vir_uniform_f(c, 0.0)); -} - -static struct qreg -ntq_umul(struct v3d_compile *c, struct qreg src0, struct qreg src1) -{ - vir_MULTOP(c, src0, src1); - return vir_UMUL24(c, src0, src1); -} - static struct qreg ntq_minify(struct v3d_compile *c, struct qreg size, struct qreg level) { @@ -331,165 +309,10 @@ ntq_emit_tex(struct v3d_compile *c, nir_tex_instr *instr) break; } - struct V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1 p0_unpacked = { - V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_header, - - .fetch_sample_mode = instr->op == nir_texop_txf, - }; - - switch (instr->sampler_dim) { - case GLSL_SAMPLER_DIM_1D: - if (instr->is_array) - p0_unpacked.lookup_type = TEXTURE_1D_ARRAY; - else - p0_unpacked.lookup_type = TEXTURE_1D; - break; - case GLSL_SAMPLER_DIM_2D: - case GLSL_SAMPLER_DIM_RECT: - if (instr->is_array) - p0_unpacked.lookup_type = TEXTURE_2D_ARRAY; - else - p0_unpacked.lookup_type = TEXTURE_2D; - break; - case GLSL_SAMPLER_DIM_3D: - p0_unpacked.lookup_type = TEXTURE_3D; - break; - case GLSL_SAMPLER_DIM_CUBE: - p0_unpacked.lookup_type = TEXTURE_CUBE_MAP; - break; - default: - unreachable("Bad sampler type"); - } - - struct qreg coords[5]; - int next_coord = 0; - for (unsigned i = 0; i < instr->num_srcs; i++) { - switch (instr->src[i].src_type) { - case nir_tex_src_coord: - for (int j = 0; j < instr->coord_components; j++) { - coords[next_coord++] = - ntq_get_src(c, instr->src[i].src, j); - } - if (instr->coord_components < 2) - coords[next_coord++] = vir_uniform_f(c, 0.5); - break; - case nir_tex_src_bias: - coords[next_coord++] = - ntq_get_src(c, instr->src[i].src, 0); - - p0_unpacked.bias_supplied = true; - break; - case nir_tex_src_lod: - /* XXX: Needs base level addition */ - coords[next_coord++] = - ntq_get_src(c, instr->src[i].src, 0); - - if (instr->op != nir_texop_txf && - instr->op != nir_texop_tg4) { - p0_unpacked.disable_autolod_use_bias_only = true; - } - break; - case nir_tex_src_comparator: - coords[next_coord++] = - ntq_get_src(c, instr->src[i].src, 0); - - p0_unpacked.shadow = true; - break; - - case nir_tex_src_offset: { - nir_const_value *offset = - nir_src_as_const_value(instr->src[i].src); - p0_unpacked.texel_offset_for_s_coordinate = - offset->i32[0]; - - if (instr->coord_components >= 2) - p0_unpacked.texel_offset_for_t_coordinate = - offset->i32[1]; - - if (instr->coord_components >= 3) - p0_unpacked.texel_offset_for_r_coordinate = - offset->i32[2]; - break; - } - - default: - unreachable("unknown texture source"); - } - } - - uint32_t p0_packed; - V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_pack(NULL, - (uint8_t *)&p0_packed, - &p0_unpacked); - - /* There is no native support for GL texture rectangle coordinates, so - * we have to rescale from ([0, width], [0, height]) to ([0, 1], [0, - * 1]). - */ - if (instr->sampler_dim == GLSL_SAMPLER_DIM_RECT) { - coords[0] = vir_FMUL(c, coords[0], - vir_uniform(c, QUNIFORM_TEXRECT_SCALE_X, - unit)); - coords[1] = vir_FMUL(c, coords[1], - vir_uniform(c, QUNIFORM_TEXRECT_SCALE_Y, - unit)); - } - - struct qreg texture_u[] = { - vir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P0_0 + unit, p0_packed), - vir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P1, unit), - }; - uint32_t next_texture_u = 0; - - for (int i = 0; i < next_coord; i++) { - struct qreg dst; - - if (i == next_coord - 1) - dst = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMUL); - else - dst = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMU); - - struct qinst *tmu = vir_MOV_dest(c, dst, coords[i]); - - if (i < 2) { - tmu->has_implicit_uniform = true; - tmu->src[vir_get_implicit_uniform_src(tmu)] = - texture_u[next_texture_u++]; - } - } - - bool return_16 = (c->key->tex[unit].return_size == 16 || - p0_unpacked.shadow); - - struct qreg return_values[4]; - for (int i = 0; i < c->key->tex[unit].return_channels; i++) - return_values[i] = vir_LDTMU(c); - /* Swizzling .zw of an RG texture should give undefined results, not - * crash the compiler. - */ - for (int i = c->key->tex[unit].return_channels; i < 4; i++) - return_values[i] = c->undef; - - for (int i = 0; i < nir_tex_instr_dest_size(instr); i++) { - struct qreg chan; - - if (return_16) { - STATIC_ASSERT(PIPE_SWIZZLE_X == 0); - chan = return_values[i / 2]; - - enum v3d_qpu_input_unpack unpack; - if (i & 1) - unpack = V3D_QPU_UNPACK_H; - else - unpack = V3D_QPU_UNPACK_L; - - chan = vir_FMOV(c, chan); - vir_set_unpack(c->defs[chan.index], 0, unpack); - } else { - chan = vir_MOV(c, return_values[i]); - } - ntq_store_dest(c, &instr->dest, i, chan); - } + if (c->devinfo->ver >= 40) + v3d40_vir_emit_tex(c, instr); + else + v3d33_vir_emit_tex(c, instr); } static struct qreg @@ -500,8 +323,7 @@ ntq_fsincos(struct v3d_compile *c, struct qreg src, bool is_cos) input = vir_FADD(c, input, vir_uniform_f(c, 0.5)); struct qreg periods = vir_FROUND(c, input); - struct qreg sin_output = vir_SFU(c, V3D_QPU_WADDR_SIN, - vir_FSUB(c, input, periods)); + struct qreg sin_output = vir_SIN(c, vir_FSUB(c, input, periods)); return vir_XOR(c, sin_output, vir_SHL(c, vir_FTOIN(c, periods), vir_uniform_ui(c, -1))); @@ -539,17 +361,27 @@ emit_fragcoord_input(struct v3d_compile *c, int attr) c->inputs[attr * 4 + 0] = vir_FXCD(c); c->inputs[attr * 4 + 1] = vir_FYCD(c); c->inputs[attr * 4 + 2] = c->payload_z; - c->inputs[attr * 4 + 3] = vir_SFU(c, V3D_QPU_WADDR_RECIP, - c->payload_w); + c->inputs[attr * 4 + 3] = vir_RECIP(c, c->payload_w); } static struct qreg emit_fragment_varying(struct v3d_compile *c, nir_variable *var, uint8_t swizzle) { - struct qreg vary = vir_reg(QFILE_VARY, ~0); + struct qreg r3 = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R3); struct qreg r5 = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R5); + struct qreg vary; + if (c->devinfo->ver >= 41) { + struct qinst *ldvary = vir_add_inst(V3D_QPU_A_NOP, c->undef, + c->undef, c->undef); + ldvary->qpu.sig.ldvary = true; + vary = vir_emit_def(c, ldvary); + } else { + vir_NOP(c)->qpu.sig.ldvary = true; + vary = r3; + } + /* For gl_PointCoord input or distance along a line, we'll be called * with no nir_variable, and we don't count toward VPM size so we * don't track an input slot. @@ -565,31 +397,36 @@ emit_fragment_varying(struct v3d_compile *c, nir_variable *var, switch (var->data.interpolation) { case INTERP_MODE_NONE: /* If a gl_FrontColor or gl_BackColor input has no interp - * qualifier, then flag it for glShadeModel() handling by the - * driver. + * qualifier, then if we're using glShadeModel(GL_FLAT) it + * needs to be flat shaded. */ switch (var->data.location) { case VARYING_SLOT_COL0: case VARYING_SLOT_COL1: case VARYING_SLOT_BFC0: case VARYING_SLOT_BFC1: - BITSET_SET(c->shade_model_flags, i); - break; + if (c->fs_key->shade_model_flat) { + BITSET_SET(c->flat_shade_flags, i); + vir_MOV_dest(c, c->undef, vary); + return vir_MOV(c, r5); + } else { + return vir_FADD(c, vir_FMUL(c, vary, + c->payload_w), r5); + } default: break; } /* FALLTHROUGH */ case INTERP_MODE_SMOOTH: if (var->data.centroid) { + BITSET_SET(c->centroid_flags, i); return vir_FADD(c, vir_FMUL(c, vary, c->payload_w_centroid), r5); } else { return vir_FADD(c, vir_FMUL(c, vary, c->payload_w), r5); } case INTERP_MODE_NOPERSPECTIVE: - /* C appears after the mov from the varying. - XXX: improve ldvary setup. - */ + BITSET_SET(c->noperspective_flags, i); return vir_FADD(c, vir_MOV(c, vary), r5); case INTERP_MODE_FLAT: BITSET_SET(c->flat_shade_flags, i); @@ -604,8 +441,9 @@ static void emit_fragment_input(struct v3d_compile *c, int attr, nir_variable *var) { for (int i = 0; i < glsl_get_vector_elements(var->type); i++) { - c->inputs[attr * 4 + i] = - emit_fragment_varying(c, var, i); + int chan = var->data.location_frac + i; + c->inputs[attr * 4 + chan] = + emit_fragment_varying(c, var, chan); } } @@ -662,7 +500,9 @@ ntq_emit_comparison(struct v3d_compile *c, struct qreg *dest, nir_alu_instr *sel_instr) { struct qreg src0 = ntq_get_alu_src(c, compare_instr, 0); - struct qreg src1 = ntq_get_alu_src(c, compare_instr, 1); + struct qreg src1; + if (nir_op_infos[compare_instr->op].num_inputs > 1) + src1 = ntq_get_alu_src(c, compare_instr, 1); bool cond_invert = false; switch (compare_instr->op) { @@ -806,6 +646,14 @@ ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr) case nir_op_imov: result = vir_MOV(c, src[0]); break; + + case nir_op_fneg: + result = vir_XOR(c, src[0], vir_uniform_ui(c, 1 << 31)); + break; + case nir_op_ineg: + result = vir_NEG(c, src[0]); + break; + case nir_op_fmul: result = vir_FMUL(c, src[0], src[1]); break; @@ -888,8 +736,12 @@ ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr) result = vir_NOT(c, src[0]); break; + case nir_op_ufind_msb: + result = vir_SUB(c, vir_uniform_ui(c, 31), vir_CLZ(c, src[0])); + break; + case nir_op_imul: - result = ntq_umul(c, src[0], src[1]); + result = vir_UMUL(c, src[0], src[1]); break; case nir_op_seq: @@ -921,16 +773,16 @@ ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr) break; case nir_op_frcp: - result = vir_SFU(c, V3D_QPU_WADDR_RECIP, src[0]); + result = vir_RECIP(c, src[0]); break; case nir_op_frsq: - result = vir_SFU(c, V3D_QPU_WADDR_RSQRT, src[0]); + result = vir_RSQRT(c, src[0]); break; case nir_op_fexp2: - result = vir_SFU(c, V3D_QPU_WADDR_EXP, src[0]); + result = vir_EXP(c, src[0]); break; case nir_op_flog2: - result = vir_SFU(c, V3D_QPU_WADDR_LOG, src[0]); + result = vir_LOG(c, src[0]); break; case nir_op_fceil: @@ -986,6 +838,27 @@ ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr) result = vir_FDY(c, src[0]); break; + case nir_op_uadd_carry: + vir_PF(c, vir_ADD(c, src[0], src[1]), V3D_QPU_PF_PUSHC); + result = vir_MOV(c, vir_SEL(c, V3D_QPU_COND_IFA, + vir_uniform_ui(c, ~0), + vir_uniform_ui(c, 0))); + break; + + case nir_op_pack_half_2x16_split: + result = vir_VFPACK(c, src[0], src[1]); + break; + + case nir_op_unpack_half_2x16_split_x: + result = vir_FMOV(c, src[0]); + vir_set_unpack(c->defs[result.index], 0, V3D_QPU_UNPACK_L); + break; + + case nir_op_unpack_half_2x16_split_y: + result = vir_FMOV(c, src[0]); + vir_set_unpack(c->defs[result.index], 0, V3D_QPU_UNPACK_H); + break; + default: fprintf(stderr, "unknown NIR ALU inst: "); nir_print_instr(&instr->instr, stderr); @@ -996,7 +869,7 @@ ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr) /* We have a scalar result, so the instruction should only have a * single channel written to. */ - assert(util_is_power_of_two(instr->dest.write_mask)); + assert(util_is_power_of_two_or_zero(instr->dest.write_mask)); ntq_store_dest(c, &instr->dest.dest, ffs(instr->dest.write_mask) - 1, result); } @@ -1036,6 +909,22 @@ emit_frag_end(struct v3d_compile *c) } */ + bool has_any_tlb_color_write = false; + for (int rt = 0; rt < c->fs_key->nr_cbufs; rt++) { + if (c->output_color_var[rt]) + has_any_tlb_color_write = true; + } + + if (c->fs_key->sample_alpha_to_coverage && c->output_color_var[0]) { + struct nir_variable *var = c->output_color_var[0]; + struct qreg *color = &c->outputs[var->data.driver_location * 4]; + + vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0), + vir_AND(c, + vir_MSF(c), + vir_FTOC(c, color[3]))); + } + if (c->output_position_index != -1) { struct qinst *inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), @@ -1046,7 +935,19 @@ emit_frag_end(struct v3d_compile *c) TLB_TYPE_DEPTH | TLB_DEPTH_TYPE_PER_PIXEL | 0xffffff00); - } else if (c->s->info.fs.uses_discard) { + } else if (c->s->info.fs.uses_discard || + c->fs_key->sample_alpha_to_coverage || + !has_any_tlb_color_write) { + /* Emit passthrough Z if it needed to be delayed until shader + * end due to potential discards. + * + * Since (single-threaded) fragment shaders always need a TLB + * write, emit passthrouh Z if we didn't have any color + * buffers and flag us as potentially discarding, so that we + * can use Z as the TLB write. + */ + c->s->info.fs.uses_discard = true; + struct qinst *inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), vir_reg(QFILE_NULL, 0)); @@ -1075,11 +976,18 @@ emit_frag_end(struct v3d_compile *c) conf |= TLB_SAMPLE_MODE_PER_PIXEL; conf |= (7 - rt) << TLB_RENDER_TARGET_SHIFT; + if (c->fs_key->swap_color_rb & (1 << rt)) + num_components = MAX2(num_components, 3); + assert(num_components != 0); switch (glsl_get_base_type(var->type)) { case GLSL_TYPE_UINT: case GLSL_TYPE_INT: - conf |= TLB_TYPE_I32_COLOR; + /* The F32 vs I32 distinction was dropped in 4.2. */ + if (c->devinfo->ver < 42) + conf |= TLB_TYPE_I32_COLOR; + else + conf |= TLB_TYPE_F32_COLOR; conf |= ((num_components - 1) << TLB_VEC_SIZE_MINUS_1_SHIFT); @@ -1099,7 +1007,7 @@ emit_frag_end(struct v3d_compile *c) struct qreg b = color[2]; struct qreg a = color[3]; - if (c->fs_key->f32_color_rb) { + if (c->fs_key->f32_color_rb & (1 << rt)) { conf |= TLB_TYPE_F32_COLOR; conf |= ((num_components - 1) << TLB_VEC_SIZE_MINUS_1_SHIFT); @@ -1117,15 +1025,20 @@ emit_frag_end(struct v3d_compile *c) b = color[0]; } + if (c->fs_key->sample_alpha_to_one) + a = vir_uniform_f(c, 1.0); + if (c->fs_key->f32_color_rb & (1 << rt)) { - inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), color[0]); + inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), r); inst->src[vir_get_implicit_uniform_src(inst)] = vir_uniform_ui(c, conf); - for (int i = 1; i < num_components; i++) { - inst = vir_MOV_dest(c, vir_reg(QFILE_TLB, 0), - color[i]); - } + if (num_components >= 2) + vir_MOV_dest(c, vir_reg(QFILE_TLB, 0), g); + if (num_components >= 3) + vir_MOV_dest(c, vir_reg(QFILE_TLB, 0), b); + if (num_components >= 4) + vir_MOV_dest(c, vir_reg(QFILE_TLB, 0), a); } else { inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), r, g); if (conf != ~0) { @@ -1134,7 +1047,8 @@ emit_frag_end(struct v3d_compile *c) vir_uniform_ui(c, conf); } - inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), b, a); + if (num_components >= 3) + inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), b, a); } break; } @@ -1143,7 +1057,21 @@ emit_frag_end(struct v3d_compile *c) } static void -emit_scaled_viewport_write(struct v3d_compile *c, struct qreg rcp_w) +vir_VPM_WRITE(struct v3d_compile *c, struct qreg val, uint32_t *vpm_index) +{ + if (c->devinfo->ver >= 40) { + vir_STVPMV(c, vir_uniform_ui(c, *vpm_index), val); + *vpm_index = *vpm_index + 1; + } else { + vir_MOV_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_VPM), val); + } + + c->num_vpm_writes++; +} + +static void +emit_scaled_viewport_write(struct v3d_compile *c, struct qreg rcp_w, + uint32_t *vpm_index) { for (int i = 0; i < 2; i++) { struct qreg coord = c->outputs[c->output_position_index + i]; @@ -1151,34 +1079,32 @@ emit_scaled_viewport_write(struct v3d_compile *c, struct qreg rcp_w) vir_uniform(c, QUNIFORM_VIEWPORT_X_SCALE + i, 0)); coord = vir_FMUL(c, coord, rcp_w); - vir_FTOIN_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_VPM), - coord); + vir_VPM_WRITE(c, vir_FTOIN(c, coord), vpm_index); } } static void -emit_zs_write(struct v3d_compile *c, struct qreg rcp_w) +emit_zs_write(struct v3d_compile *c, struct qreg rcp_w, uint32_t *vpm_index) { struct qreg zscale = vir_uniform(c, QUNIFORM_VIEWPORT_Z_SCALE, 0); struct qreg zoffset = vir_uniform(c, QUNIFORM_VIEWPORT_Z_OFFSET, 0); - vir_FADD_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_VPM), - vir_FMUL(c, vir_FMUL(c, - c->outputs[c->output_position_index + 2], - zscale), - rcp_w), - zoffset); + struct qreg z = c->outputs[c->output_position_index + 2]; + z = vir_FMUL(c, z, zscale); + z = vir_FMUL(c, z, rcp_w); + z = vir_FADD(c, z, zoffset); + vir_VPM_WRITE(c, z, vpm_index); } static void -emit_rcp_wc_write(struct v3d_compile *c, struct qreg rcp_w) +emit_rcp_wc_write(struct v3d_compile *c, struct qreg rcp_w, uint32_t *vpm_index) { - vir_VPM_WRITE(c, rcp_w); + vir_VPM_WRITE(c, rcp_w, vpm_index); } static void -emit_point_size_write(struct v3d_compile *c) +emit_point_size_write(struct v3d_compile *c, uint32_t *vpm_index) { struct qreg point_size; @@ -1192,55 +1118,67 @@ emit_point_size_write(struct v3d_compile *c) */ point_size = vir_FMAX(c, point_size, vir_uniform_f(c, .125)); - vir_VPM_WRITE(c, point_size); + vir_VPM_WRITE(c, point_size, vpm_index); } static void emit_vpm_write_setup(struct v3d_compile *c) { - uint32_t packed; - struct V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP unpacked = { - V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_header, - - .horiz = true, - .laned = false, - .segs = true, - .stride = 1, - .size = VPM_SETUP_SIZE_32_BIT, - .addr = 0, - }; - - V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_pack(NULL, - (uint8_t *)&packed, - &unpacked); - vir_VPMSETUP(c, vir_uniform_ui(c, packed)); + if (c->devinfo->ver >= 40) + return; + + v3d33_vir_vpm_write_setup(c); +} + +/** + * Sets up c->outputs[c->output_position_index] for the vertex shader + * epilogue, if an output vertex position wasn't specified in the user's + * shader. This may be the case for transform feedback with rasterizer + * discard enabled. + */ +static void +setup_default_position(struct v3d_compile *c) +{ + if (c->output_position_index != -1) + return; + + c->output_position_index = c->outputs_array_size; + for (int i = 0; i < 4; i++) { + add_output(c, + c->output_position_index + i, + VARYING_SLOT_POS, i); + } } static void emit_vert_end(struct v3d_compile *c) { - struct qreg rcp_w = vir_SFU(c, V3D_QPU_WADDR_RECIP, - c->outputs[c->output_position_index + 3]); + setup_default_position(c); + + uint32_t vpm_index = 0; + struct qreg rcp_w = vir_RECIP(c, + c->outputs[c->output_position_index + 3]); emit_vpm_write_setup(c); if (c->vs_key->is_coord) { for (int i = 0; i < 4; i++) - vir_VPM_WRITE(c, c->outputs[c->output_position_index + i]); - emit_scaled_viewport_write(c, rcp_w); + vir_VPM_WRITE(c, c->outputs[c->output_position_index + i], + &vpm_index); + emit_scaled_viewport_write(c, rcp_w, &vpm_index); if (c->vs_key->per_vertex_point_size) { - emit_point_size_write(c); + emit_point_size_write(c, &vpm_index); /* emit_rcp_wc_write(c, rcp_w); */ } /* XXX: Z-only rendering */ if (0) - emit_zs_write(c, rcp_w); + emit_zs_write(c, rcp_w, &vpm_index); } else { - emit_scaled_viewport_write(c, rcp_w); - emit_zs_write(c, rcp_w); - emit_rcp_wc_write(c, rcp_w); + emit_scaled_viewport_write(c, rcp_w, &vpm_index); + emit_zs_write(c, rcp_w, &vpm_index); + emit_rcp_wc_write(c, rcp_w, &vpm_index); if (c->vs_key->per_vertex_point_size) - emit_point_size_write(c); + emit_point_size_write(c, &vpm_index); } for (int i = 0; i < c->vs_key->num_fs_inputs; i++) { @@ -1251,7 +1189,8 @@ emit_vert_end(struct v3d_compile *c) struct v3d_varying_slot output = c->output_slots[j]; if (!memcmp(&input, &output, sizeof(input))) { - vir_VPM_WRITE(c, c->outputs[j]); + vir_VPM_WRITE(c, c->outputs[j], + &vpm_index); break; } } @@ -1259,8 +1198,14 @@ emit_vert_end(struct v3d_compile *c) * this FS input. */ if (j == c->num_outputs) - vir_VPM_WRITE(c, vir_uniform_f(c, 0.0)); + vir_VPM_WRITE(c, vir_uniform_f(c, 0.0), + &vpm_index); } + + /* GFXH-1684: VPM writes need to be complete by the end of the shader. + */ + if (c->devinfo->ver >= 40 && c->devinfo->ver <= 42) + vir_VPMWT(c); } void @@ -1284,6 +1229,8 @@ v3d_optimize_nir(struct nir_shader *s) NIR_PASS(progress, s, nir_opt_constant_folding); NIR_PASS(progress, s, nir_opt_undef); } while (progress); + + NIR_PASS(progress, s, nir_opt_move_load_ubo); } static int @@ -1303,6 +1250,12 @@ ntq_emit_vpm_read(struct v3d_compile *c, { struct qreg vpm = vir_reg(QFILE_VPM, vpm_index); + if (c->devinfo->ver >= 40 ) { + return vir_LDVPMV_IN(c, + vir_uniform_ui(c, + (*num_components_queued)++)); + } + if (*num_components_queued != 0) { (*num_components_queued)--; c->num_inputs++; @@ -1311,24 +1264,7 @@ ntq_emit_vpm_read(struct v3d_compile *c, uint32_t num_components = MIN2(*remaining, 32); - struct V3D33_VPM_GENERIC_BLOCK_READ_SETUP unpacked = { - V3D33_VPM_GENERIC_BLOCK_READ_SETUP_header, - - .horiz = true, - .laned = false, - /* If the field is 0, that means a read count of 32. */ - .num = num_components & 31, - .segs = true, - .stride = 1, - .size = VPM_SETUP_SIZE_32_BIT, - .addr = c->num_inputs, - }; - - uint32_t packed; - V3D33_VPM_GENERIC_BLOCK_READ_SETUP_pack(NULL, - (uint8_t *)&packed, - &unpacked); - vir_VPMSETUP(c, vir_uniform_ui(c, packed)); + v3d33_vir_vpm_read_setup(c, num_components); *num_components_queued = num_components - 1; *remaining -= num_components; @@ -1338,7 +1274,72 @@ ntq_emit_vpm_read(struct v3d_compile *c, } static void -ntq_setup_inputs(struct v3d_compile *c) +ntq_setup_vpm_inputs(struct v3d_compile *c) +{ + /* Figure out how many components of each vertex attribute the shader + * uses. Each variable should have been split to individual + * components and unused ones DCEed. The vertex fetcher will load + * from the start of the attribute to the number of components we + * declare we need in c->vattr_sizes[]. + */ + nir_foreach_variable(var, &c->s->inputs) { + /* No VS attribute array support. */ + assert(MAX2(glsl_get_length(var->type), 1) == 1); + + unsigned loc = var->data.driver_location; + int start_component = var->data.location_frac; + int num_components = glsl_get_components(var->type); + + c->vattr_sizes[loc] = MAX2(c->vattr_sizes[loc], + start_component + num_components); + } + + unsigned num_components = 0; + uint32_t vpm_components_queued = 0; + bool uses_iid = c->s->info.system_values_read & + (1ull << SYSTEM_VALUE_INSTANCE_ID); + bool uses_vid = c->s->info.system_values_read & + (1ull << SYSTEM_VALUE_VERTEX_ID); + num_components += uses_iid; + num_components += uses_vid; + + for (int i = 0; i < ARRAY_SIZE(c->vattr_sizes); i++) + num_components += c->vattr_sizes[i]; + + if (uses_iid) { + c->iid = ntq_emit_vpm_read(c, &vpm_components_queued, + &num_components, ~0); + } + + if (uses_vid) { + c->vid = ntq_emit_vpm_read(c, &vpm_components_queued, + &num_components, ~0); + } + + for (int loc = 0; loc < ARRAY_SIZE(c->vattr_sizes); loc++) { + resize_qreg_array(c, &c->inputs, &c->inputs_array_size, + (loc + 1) * 4); + + for (int i = 0; i < c->vattr_sizes[loc]; i++) { + c->inputs[loc * 4 + i] = + ntq_emit_vpm_read(c, + &vpm_components_queued, + &num_components, + loc * 4 + i); + + } + } + + if (c->devinfo->ver >= 40) { + assert(vpm_components_queued == num_components); + } else { + assert(vpm_components_queued == 0); + assert(num_components == 0); + } +} + +static void +ntq_setup_fs_inputs(struct v3d_compile *c) { unsigned num_entries = 0; unsigned num_components = 0; @@ -1360,27 +1361,6 @@ ntq_setup_inputs(struct v3d_compile *c) */ qsort(&vars, num_entries, sizeof(*vars), driver_location_compare); - uint32_t vpm_components_queued = 0; - if (c->s->info.stage == MESA_SHADER_VERTEX) { - bool uses_iid = c->s->info.system_values_read & - (1ull << SYSTEM_VALUE_INSTANCE_ID); - bool uses_vid = c->s->info.system_values_read & - (1ull << SYSTEM_VALUE_VERTEX_ID); - - num_components += uses_iid; - num_components += uses_vid; - - if (uses_iid) { - c->iid = ntq_emit_vpm_read(c, &vpm_components_queued, - &num_components, ~0); - } - - if (uses_vid) { - c->vid = ntq_emit_vpm_read(c, &vpm_components_queued, - &num_components, ~0); - } - } - for (unsigned i = 0; i < num_entries; i++) { nir_variable *var = vars[i]; unsigned array_len = MAX2(glsl_get_length(var->type), 1); @@ -1391,38 +1371,19 @@ ntq_setup_inputs(struct v3d_compile *c) resize_qreg_array(c, &c->inputs, &c->inputs_array_size, (loc + 1) * 4); - if (c->s->info.stage == MESA_SHADER_FRAGMENT) { - if (var->data.location == VARYING_SLOT_POS) { - emit_fragcoord_input(c, loc); - } else if (var->data.location == VARYING_SLOT_PNTC || - (var->data.location >= VARYING_SLOT_VAR0 && - (c->fs_key->point_sprite_mask & - (1 << (var->data.location - - VARYING_SLOT_VAR0))))) { - c->inputs[loc * 4 + 0] = c->point_x; - c->inputs[loc * 4 + 1] = c->point_y; - } else { - emit_fragment_input(c, loc, var); - } + if (var->data.location == VARYING_SLOT_POS) { + emit_fragcoord_input(c, loc); + } else if (var->data.location == VARYING_SLOT_PNTC || + (var->data.location >= VARYING_SLOT_VAR0 && + (c->fs_key->point_sprite_mask & + (1 << (var->data.location - + VARYING_SLOT_VAR0))))) { + c->inputs[loc * 4 + 0] = c->point_x; + c->inputs[loc * 4 + 1] = c->point_y; } else { - int var_components = glsl_get_components(var->type); - - for (int i = 0; i < var_components; i++) { - c->inputs[loc * 4 + i] = - ntq_emit_vpm_read(c, - &vpm_components_queued, - &num_components, - loc * 4 + i); - - } - c->vattr_sizes[loc] = var_components; + emit_fragment_input(c, loc, var); } } - - if (c->s->info.stage == MESA_SHADER_VERTEX) { - assert(vpm_components_queued == 0); - assert(num_components == 0); - } } static void @@ -1435,8 +1396,11 @@ ntq_setup_outputs(struct v3d_compile *c) assert(array_len == 1); (void)array_len; - for (int i = 0; i < 4; i++) - add_output(c, loc + i, var->data.location, i); + for (int i = 0; i < 4 - var->data.location_frac; i++) { + add_output(c, loc + var->data.location_frac + i, + var->data.location, + var->data.location_frac + i); + } if (c->s->info.stage == MESA_SHADER_FRAGMENT) { switch (var->data.location) { @@ -1566,6 +1530,8 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr) ntq_get_src(c, instr->src[1], 0), vir_uniform_ui(c, i * 4))); + vir_emit_thrsw(c); + ntq_store_dest(c, &instr->dest, i, vir_LDTMU(c)); } break; @@ -1669,7 +1635,7 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr) * the condition so that we can use zero as "executing * and discarding." */ - vir_PF(c, vir_AND(c, c->execute, vir_NOT(c, cond)), + vir_PF(c, vir_OR(c, c->execute, vir_NOT(c, cond)), V3D_QPU_PF_PUSHZ); vir_set_cond(vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0), vir_uniform_ui(c, 0)), @@ -1698,7 +1664,7 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr) static void ntq_activate_execute_for_block(struct v3d_compile *c) { - vir_PF(c, vir_SUB(c, c->execute, vir_uniform_ui(c, c->cur_block->index)), + vir_PF(c, vir_XOR(c, c->execute, vir_uniform_ui(c, c->cur_block->index)), V3D_QPU_PF_PUSHZ); vir_MOV_cond(c, V3D_QPU_COND_IFA, c->execute, vir_uniform_ui(c, 0)); @@ -1760,7 +1726,7 @@ ntq_emit_if(struct v3d_compile *c, nir_if *if_stmt) vir_uniform_ui(c, after_block->index)); /* If everything points at ENDIF, then jump there immediately. */ - vir_PF(c, vir_SUB(c, c->execute, + vir_PF(c, vir_XOR(c, c->execute, vir_uniform_ui(c, after_block->index)), V3D_QPU_PF_PUSHZ); vir_BRANCH(c, V3D_QPU_BRANCH_COND_ALLA); @@ -1874,7 +1840,7 @@ ntq_emit_loop(struct v3d_compile *c, nir_loop *loop) * * XXX: Use the .ORZ flags update, instead. */ - vir_PF(c, vir_SUB(c, + vir_PF(c, vir_XOR(c, c->execute, vir_uniform_ui(c, c->loop_cont_block->index)), V3D_QPU_PF_PUSHZ); @@ -1882,7 +1848,11 @@ ntq_emit_loop(struct v3d_compile *c, nir_loop *loop) vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ); - vir_BRANCH(c, V3D_QPU_BRANCH_COND_ANYA); + struct qinst *branch = vir_BRANCH(c, V3D_QPU_BRANCH_COND_ANYA); + /* Pixels that were not dispatched or have been discarded should not + * contribute to looping again. + */ + branch->qpu.branch.msfign = V3D_QPU_MSFIGN_P; vir_link_blocks(c->cur_block, c->loop_cont_block); vir_link_blocks(c->cur_block, c->loop_break_block); @@ -1954,7 +1924,11 @@ nir_to_vir(struct v3d_compile *c) } } - ntq_setup_inputs(c); + if (c->s->info.stage == MESA_SHADER_FRAGMENT) + ntq_setup_fs_inputs(c); + else + ntq_setup_vpm_inputs(c); + ntq_setup_outputs(c); ntq_setup_uniforms(c); ntq_setup_registers(c, &c->s->registers); @@ -1968,20 +1942,33 @@ nir_to_vir(struct v3d_compile *c) } const nir_shader_compiler_options v3d_nir_options = { + .lower_all_io_to_temps = true, .lower_extract_byte = true, .lower_extract_word = true, - .lower_bitfield_insert = true, - .lower_bitfield_extract = true, + .lower_bfm = true, + .lower_bitfield_insert_to_shifts = true, + .lower_bitfield_extract_to_shifts = true, + .lower_bitfield_reverse = true, + .lower_bit_count = true, .lower_pack_unorm_2x16 = true, .lower_pack_snorm_2x16 = true, .lower_pack_unorm_4x8 = true, .lower_pack_snorm_4x8 = true, + .lower_unpack_unorm_4x8 = true, + .lower_unpack_snorm_4x8 = true, + .lower_pack_half_2x16 = true, + .lower_unpack_half_2x16 = true, + .lower_fdiv = true, + .lower_find_lsb = true, .lower_ffma = true, .lower_flrp32 = true, .lower_fpow = true, .lower_fsat = true, .lower_fsqrt = true, - .lower_negate = true, + .lower_ifind_msb = true, + .lower_ldexp = true, + .lower_mul_high = true, + .lower_wpos_pntc = true, .native_integers = true, }; @@ -2003,6 +1990,85 @@ count_nir_instrs(nir_shader *nir) } #endif +/** + * When demoting a shader down to single-threaded, removes the THRSW + * instructions (one will still be inserted at v3d_vir_to_qpu() for the + * program end). + */ +static void +vir_remove_thrsw(struct v3d_compile *c) +{ + vir_for_each_block(block, c) { + vir_for_each_inst_safe(inst, block) { + if (inst->qpu.sig.thrsw) + vir_remove_instruction(c, inst); + } + } + + c->last_thrsw = NULL; +} + +void +vir_emit_last_thrsw(struct v3d_compile *c) +{ + /* On V3D before 4.1, we need a TMU op to be outstanding when thread + * switching, so disable threads if we didn't do any TMU ops (each of + * which would have emitted a THRSW). + */ + if (!c->last_thrsw_at_top_level && c->devinfo->ver < 41) { + c->threads = 1; + if (c->last_thrsw) + vir_remove_thrsw(c); + return; + } + + /* If we're threaded and the last THRSW was in conditional code, then + * we need to emit another one so that we can flag it as the last + * thrsw. + */ + if (c->last_thrsw && !c->last_thrsw_at_top_level) { + assert(c->devinfo->ver >= 41); + vir_emit_thrsw(c); + } + + /* If we're threaded, then we need to mark the last THRSW instruction + * so we can emit a pair of them at QPU emit time. + * + * For V3D 4.x, we can spawn the non-fragment shaders already in the + * post-last-THRSW state, so we can skip this. + */ + if (!c->last_thrsw && c->s->info.stage == MESA_SHADER_FRAGMENT) { + assert(c->devinfo->ver >= 41); + vir_emit_thrsw(c); + } + + if (c->last_thrsw) + c->last_thrsw->is_last_thrsw = true; +} + +/* There's a flag in the shader for "center W is needed for reasons other than + * non-centroid varyings", so we just walk the program after VIR optimization + * to see if it's used. It should be harmless to set even if we only use + * center W for varyings. + */ +static void +vir_check_payload_w(struct v3d_compile *c) +{ + if (c->s->info.stage != MESA_SHADER_FRAGMENT) + return; + + vir_for_each_inst_inorder(inst, c) { + for (int i = 0; i < vir_get_nsrc(inst); i++) { + if (inst->src[i].file == QFILE_REG && + inst->src[i].index == 0) { + c->uses_center_w = true; + return; + } + } + } + +} + void v3d_nir_to_vir(struct v3d_compile *c) { @@ -2016,6 +2082,9 @@ v3d_nir_to_vir(struct v3d_compile *c) nir_to_vir(c); + /* Emit the last THRSW before STVPM and TLB writes. */ + vir_emit_last_thrsw(c); + switch (c->s->info.stage) { case MESA_SHADER_FRAGMENT: emit_frag_end(c); @@ -2039,6 +2108,8 @@ v3d_nir_to_vir(struct v3d_compile *c) vir_optimize(c); vir_lower_uniforms(c); + vir_check_payload_w(c); + /* XXX: vir_schedule_instructions(c); */ if (V3D_DEBUG & (V3D_DEBUG_VIR | @@ -2050,5 +2121,33 @@ v3d_nir_to_vir(struct v3d_compile *c) fprintf(stderr, "\n"); } - v3d_vir_to_qpu(c); + /* Attempt to allocate registers for the temporaries. If we fail, + * reduce thread count and try again. + */ + int min_threads = (c->devinfo->ver >= 41) ? 2 : 1; + struct qpu_reg *temp_registers; + while (true) { + bool spilled; + temp_registers = v3d_register_allocate(c, &spilled); + if (spilled) + continue; + + if (temp_registers) + break; + + if (c->threads == min_threads) { + fprintf(stderr, "Failed to register allocate at %d threads:\n", + c->threads); + vir_dump(c); + c->failed = true; + return; + } + + c->threads /= 2; + + if (c->threads == 1) + vir_remove_thrsw(c); + } + + v3d_vir_to_qpu(c, temp_registers); } diff --git a/lib/mesa/src/broadcom/compiler/qpu_schedule.c b/lib/mesa/src/broadcom/compiler/qpu_schedule.c index dd221e027..544831959 100644 --- a/lib/mesa/src/broadcom/compiler/qpu_schedule.c +++ b/lib/mesa/src/broadcom/compiler/qpu_schedule.c @@ -78,11 +78,13 @@ struct schedule_node_child { enum direction { F, R }; struct schedule_state { + const struct v3d_device_info *devinfo; struct schedule_node *last_r[6]; struct schedule_node *last_rf[64]; struct schedule_node *last_sf; struct schedule_node *last_vpm_read; struct schedule_node *last_tmu_write; + struct schedule_node *last_tmu_config; struct schedule_node *last_tlb; struct schedule_node *last_vpm; struct schedule_node *last_unif; @@ -194,6 +196,16 @@ process_waddr_deps(struct schedule_state *state, struct schedule_node *n, add_write_dep(state, &state->last_rf[waddr], n); } else if (v3d_qpu_magic_waddr_is_tmu(waddr)) { add_write_dep(state, &state->last_tmu_write, n); + switch (waddr) { + case V3D_QPU_WADDR_TMUS: + case V3D_QPU_WADDR_TMUSCM: + case V3D_QPU_WADDR_TMUSF: + case V3D_QPU_WADDR_TMUSLOD: + add_write_dep(state, &state->last_tmu_config, n); + break; + default: + break; + } } else if (v3d_qpu_magic_waddr_is_sfu(waddr)) { /* Handled by v3d_qpu_writes_r4() check. */ } else { @@ -201,13 +213,15 @@ process_waddr_deps(struct schedule_state *state, struct schedule_node *n, case V3D_QPU_WADDR_R0: case V3D_QPU_WADDR_R1: case V3D_QPU_WADDR_R2: - case V3D_QPU_WADDR_R3: - case V3D_QPU_WADDR_R4: - case V3D_QPU_WADDR_R5: add_write_dep(state, &state->last_r[waddr - V3D_QPU_WADDR_R0], n); break; + case V3D_QPU_WADDR_R3: + case V3D_QPU_WADDR_R4: + case V3D_QPU_WADDR_R5: + /* Handled by v3d_qpu_writes_r*() checks below. */ + break; case V3D_QPU_WADDR_VPM: case V3D_QPU_WADDR_VPMU: @@ -263,6 +277,7 @@ process_uf_deps(struct schedule_state *state, struct schedule_node *n, static void calculate_deps(struct schedule_state *state, struct schedule_node *n) { + const struct v3d_device_info *devinfo = state->devinfo; struct qinst *qinst = n->inst; struct v3d_qpu_instr *inst = &qinst->qpu; @@ -306,6 +321,10 @@ calculate_deps(struct schedule_state *state, struct schedule_node *n) add_write_dep(state, &state->last_vpm, n); break; + case V3D_QPU_A_VPMWT: + add_read_dep(state, state->last_vpm, n); + break; + case V3D_QPU_A_MSF: add_read_dep(state, state->last_tlb, n); break; @@ -324,7 +343,7 @@ calculate_deps(struct schedule_state *state, struct schedule_node *n) add_read_dep(state, state->last_sf, n); break; - case V3D_QPU_A_FLBPOP: + case V3D_QPU_A_FLPOP: add_write_dep(state, &state->last_sf, n); break; @@ -354,12 +373,16 @@ calculate_deps(struct schedule_state *state, struct schedule_node *n) process_waddr_deps(state, n, inst->alu.mul.waddr, inst->alu.mul.magic_write); } + if (v3d_qpu_sig_writes_address(devinfo, &inst->sig)) { + process_waddr_deps(state, n, inst->sig_addr, + inst->sig_magic); + } - if (v3d_qpu_writes_r3(inst)) + if (v3d_qpu_writes_r3(devinfo, inst)) add_write_dep(state, &state->last_r[3], n); - if (v3d_qpu_writes_r4(inst)) + if (v3d_qpu_writes_r4(devinfo, inst)) add_write_dep(state, &state->last_r[4], n); - if (v3d_qpu_writes_r5(inst)) + if (v3d_qpu_writes_r5(devinfo, inst)) add_write_dep(state, &state->last_r[5], n); if (inst->sig.thrsw) { @@ -369,6 +392,7 @@ calculate_deps(struct schedule_state *state, struct schedule_node *n) for (int i = 0; i < ARRAY_SIZE(state->last_r); i++) add_write_dep(state, &state->last_r[i], n); add_write_dep(state, &state->last_sf, n); + add_write_dep(state, &state->last_rtop, n); /* Scoreboard-locking operations have to stay after the last * thread switch. @@ -376,14 +400,18 @@ calculate_deps(struct schedule_state *state, struct schedule_node *n) add_write_dep(state, &state->last_tlb, n); add_write_dep(state, &state->last_tmu_write, n); + add_write_dep(state, &state->last_tmu_config, n); } - if (inst->sig.ldtmu) { + if (v3d_qpu_waits_on_tmu(inst)) { /* TMU loads are coming from a FIFO, so ordering is important. */ add_write_dep(state, &state->last_tmu_write, n); } + if (inst->sig.wrtmuc) + add_write_dep(state, &state->last_tmu_config, n); + if (inst->sig.ldtlb | inst->sig.ldtlbu) add_read_dep(state, state->last_tlb, n); @@ -408,6 +436,7 @@ calculate_forward_deps(struct v3d_compile *c, struct list_head *schedule_list) struct schedule_state state; memset(&state, 0, sizeof(state)); + state.devinfo = c->devinfo; state.dir = F; list_for_each_entry(struct schedule_node, node, schedule_list, link) @@ -421,6 +450,7 @@ calculate_reverse_deps(struct v3d_compile *c, struct list_head *schedule_list) struct schedule_state state; memset(&state, 0, sizeof(state)); + state.devinfo = c->devinfo; state.dir = R; for (node = schedule_list->prev; schedule_list != node; node = node->prev) { @@ -430,10 +460,10 @@ calculate_reverse_deps(struct v3d_compile *c, struct list_head *schedule_list) struct choose_scoreboard { int tick; - int last_sfu_write_tick; + int last_magic_sfu_write_tick; int last_ldvary_tick; int last_uniforms_reset_tick; - uint32_t last_waddr_add, last_waddr_mul; + int last_thrsw_tick; bool tlb_locked; }; @@ -442,22 +472,8 @@ mux_reads_too_soon(struct choose_scoreboard *scoreboard, const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux) { switch (mux) { - case V3D_QPU_MUX_A: - if (scoreboard->last_waddr_add == inst->raddr_a || - scoreboard->last_waddr_mul == inst->raddr_a) { - return true; - } - break; - - case V3D_QPU_MUX_B: - if (scoreboard->last_waddr_add == inst->raddr_b || - scoreboard->last_waddr_mul == inst->raddr_b) { - return true; - } - break; - case V3D_QPU_MUX_R4: - if (scoreboard->tick - scoreboard->last_sfu_write_tick <= 2) + if (scoreboard->tick - scoreboard->last_magic_sfu_write_tick <= 2) return true; break; @@ -512,7 +528,8 @@ reads_too_soon_after_write(struct choose_scoreboard *scoreboard, } static bool -writes_too_soon_after_write(struct choose_scoreboard *scoreboard, +writes_too_soon_after_write(const struct v3d_device_info *devinfo, + struct choose_scoreboard *scoreboard, struct qinst *qinst) { const struct v3d_qpu_instr *inst = &qinst->qpu; @@ -521,8 +538,8 @@ writes_too_soon_after_write(struct choose_scoreboard *scoreboard, * This would normally be prevented by dependency tracking, but might * occur if a dead SFU computation makes it to scheduling. */ - if (scoreboard->tick - scoreboard->last_sfu_write_tick < 2 && - v3d_qpu_writes_r4(inst)) + if (scoreboard->tick - scoreboard->last_magic_sfu_write_tick < 2 && + v3d_qpu_writes_r4(devinfo, inst)) return true; return false; @@ -549,7 +566,7 @@ get_instruction_priority(const struct v3d_qpu_instr *inst) next_score++; /* Schedule texture read results collection late to hide latency. */ - if (inst->sig.ldtmu) + if (v3d_qpu_waits_on_tmu(inst)) return next_score; next_score++; @@ -558,13 +575,8 @@ get_instruction_priority(const struct v3d_qpu_instr *inst) next_score++; /* Schedule texture read setup early to hide their latency better. */ - if (inst->type == V3D_QPU_INSTR_TYPE_ALU && - ((inst->alu.add.magic_write && - v3d_qpu_magic_waddr_is_tmu(inst->alu.add.waddr)) || - (inst->alu.mul.magic_write && - v3d_qpu_magic_waddr_is_tmu(inst->alu.mul.waddr)))) { + if (v3d_qpu_writes_tmu(inst)) return next_score; - } next_score++; return baseline_score; @@ -583,6 +595,11 @@ qpu_magic_waddr_is_periph(enum v3d_qpu_waddr waddr) static bool qpu_accesses_peripheral(const struct v3d_qpu_instr *inst) { + if (v3d_qpu_uses_vpm(inst)) + return true; + if (v3d_qpu_uses_sfu(inst)) + return true; + if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { if (inst->alu.add.op != V3D_QPU_A_NOP && inst->alu.add.magic_write && @@ -590,7 +607,7 @@ qpu_accesses_peripheral(const struct v3d_qpu_instr *inst) return true; } - if (inst->alu.add.op == V3D_QPU_A_VPMSETUP) + if (inst->alu.add.op == V3D_QPU_A_TMUWT) return true; if (inst->alu.mul.op != V3D_QPU_M_NOP && @@ -603,7 +620,8 @@ qpu_accesses_peripheral(const struct v3d_qpu_instr *inst) return (inst->sig.ldvpm || inst->sig.ldtmu || inst->sig.ldtlb || - inst->sig.ldtlbu); + inst->sig.ldtlbu || + inst->sig.wrtmuc); } static bool @@ -617,7 +635,11 @@ qpu_merge_inst(const struct v3d_device_info *devinfo, return false; } - /* Can't do more than one peripheral access in an instruction. */ + /* Can't do more than one peripheral access in an instruction. + * + * XXX: V3D 4.1 allows TMU read along with a VPM read or write, and + * WRTMUC with a TMU magic register write (other than tmuc). + */ if (qpu_accesses_peripheral(a) && qpu_accesses_peripheral(b)) return false; @@ -653,7 +675,8 @@ qpu_merge_inst(const struct v3d_device_info *devinfo, if (v3d_qpu_uses_mux(b, V3D_QPU_MUX_B)) { if (v3d_qpu_uses_mux(a, V3D_QPU_MUX_B) && - a->raddr_b != b->raddr_b) { + (a->raddr_b != b->raddr_b || + a->sig.small_imm != b->sig.small_imm)) { return false; } merge.raddr_b = b->raddr_b; @@ -661,6 +684,9 @@ qpu_merge_inst(const struct v3d_device_info *devinfo, merge.sig.thrsw |= b->sig.thrsw; merge.sig.ldunif |= b->sig.ldunif; + merge.sig.ldunifrf |= b->sig.ldunifrf; + merge.sig.ldunifa |= b->sig.ldunifa; + merge.sig.ldunifarf |= b->sig.ldunifarf; merge.sig.ldtmu |= b->sig.ldtmu; merge.sig.ldvary |= b->sig.ldvary; merge.sig.ldvpm |= b->sig.ldvpm; @@ -671,6 +697,12 @@ qpu_merge_inst(const struct v3d_device_info *devinfo, merge.sig.rotate |= b->sig.rotate; merge.sig.wrtmuc |= b->sig.wrtmuc; + if (v3d_qpu_sig_writes_address(devinfo, &a->sig) && + v3d_qpu_sig_writes_address(devinfo, &b->sig)) + return false; + merge.sig_addr |= b->sig_addr; + merge.sig_magic |= b->sig_magic; + uint64_t packed; bool ok = v3d_qpu_instr_pack(devinfo, &merge, &packed); @@ -717,7 +749,7 @@ choose_instruction_to_schedule(const struct v3d_device_info *devinfo, if (reads_too_soon_after_write(scoreboard, n->inst)) continue; - if (writes_too_soon_after_write(scoreboard, n->inst)) + if (writes_too_soon_after_write(devinfo, scoreboard, n->inst)) continue; /* "A scoreboard wait must not occur in the first two @@ -733,7 +765,7 @@ choose_instruction_to_schedule(const struct v3d_device_info *devinfo, * otherwise get scheduled so ldunif and ldvary try to update * r5 in the same tick. */ - if (inst->sig.ldunif && + if ((inst->sig.ldunif || inst->sig.ldunifa) && scoreboard->tick == scoreboard->last_ldvary_tick + 1) { continue; } @@ -801,16 +833,13 @@ update_scoreboard_for_magic_waddr(struct choose_scoreboard *scoreboard, enum v3d_qpu_waddr waddr) { if (v3d_qpu_magic_waddr_is_sfu(waddr)) - scoreboard->last_sfu_write_tick = scoreboard->tick; + scoreboard->last_magic_sfu_write_tick = scoreboard->tick; } static void update_scoreboard_for_chosen(struct choose_scoreboard *scoreboard, const struct v3d_qpu_instr *inst) { - scoreboard->last_waddr_add = ~0; - scoreboard->last_waddr_mul = ~0; - if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH) return; @@ -820,8 +849,6 @@ update_scoreboard_for_chosen(struct choose_scoreboard *scoreboard, if (inst->alu.add.magic_write) { update_scoreboard_for_magic_waddr(scoreboard, inst->alu.add.waddr); - } else { - scoreboard->last_waddr_add = inst->alu.add.waddr; } } @@ -829,8 +856,6 @@ update_scoreboard_for_chosen(struct choose_scoreboard *scoreboard, if (inst->alu.mul.magic_write) { update_scoreboard_for_magic_waddr(scoreboard, inst->alu.mul.waddr); - } else { - scoreboard->last_waddr_mul = inst->alu.mul.waddr; } } @@ -890,7 +915,7 @@ static uint32_t magic_waddr_latency(enum v3d_qpu_waddr waddr, * * because we associate the first load_tmu0 with the *second* tmu0_s. */ - if (v3d_qpu_magic_waddr_is_tmu(waddr) && after->sig.ldtmu) + if (v3d_qpu_magic_waddr_is_tmu(waddr) && v3d_qpu_waits_on_tmu(after)) return 100; /* Assume that anything depending on us is consuming the SFU result. */ @@ -983,6 +1008,19 @@ mark_instruction_scheduled(struct list_head *schedule_list, } } +static void +insert_scheduled_instruction(struct v3d_compile *c, + struct qblock *block, + struct choose_scoreboard *scoreboard, + struct qinst *inst) +{ + list_addtail(&inst->link, &block->instructions); + + update_scoreboard_for_chosen(scoreboard, &inst->qpu); + c->qpu_inst_count++; + scoreboard->tick++; +} + static struct qinst * vir_nop() { @@ -992,61 +1030,190 @@ vir_nop() return qinst; } -#if 0 -static struct qinst * -nop_after(struct qinst *inst) +static void +emit_nop(struct v3d_compile *c, struct qblock *block, + struct choose_scoreboard *scoreboard) +{ + insert_scheduled_instruction(c, block, scoreboard, vir_nop()); +} + +static bool +qpu_instruction_valid_in_thrend_slot(struct v3d_compile *c, + const struct qinst *qinst, int slot) +{ + const struct v3d_qpu_instr *inst = &qinst->qpu; + + /* Only TLB Z writes are prohibited in the last slot, but we don't + * have those flagged so prohibit all TLB ops for now. + */ + if (slot == 2 && qpu_inst_is_tlb(inst)) + return false; + + if (slot > 0 && qinst->uniform != ~0) + return false; + + if (v3d_qpu_uses_vpm(inst)) + return false; + + if (inst->sig.ldvary) + return false; + + if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { + /* GFXH-1625: TMUWT not allowed in the final instruction. */ + if (slot == 2 && inst->alu.add.op == V3D_QPU_A_TMUWT) + return false; + + /* No writing physical registers at the end. */ + if (!inst->alu.add.magic_write || + !inst->alu.mul.magic_write) { + return false; + } + + if (c->devinfo->ver < 40 && inst->alu.add.op == V3D_QPU_A_SETMSF) + return false; + + /* RF0-2 might be overwritten during the delay slots by + * fragment shader setup. + */ + if (inst->raddr_a < 3 && + (inst->alu.add.a == V3D_QPU_MUX_A || + inst->alu.add.b == V3D_QPU_MUX_A || + inst->alu.mul.a == V3D_QPU_MUX_A || + inst->alu.mul.b == V3D_QPU_MUX_A)) { + return false; + } + + if (inst->raddr_b < 3 && + !inst->sig.small_imm && + (inst->alu.add.a == V3D_QPU_MUX_B || + inst->alu.add.b == V3D_QPU_MUX_B || + inst->alu.mul.a == V3D_QPU_MUX_B || + inst->alu.mul.b == V3D_QPU_MUX_B)) { + return false; + } + } + + return true; +} + +static bool +valid_thrsw_sequence(struct v3d_compile *c, struct choose_scoreboard *scoreboard, + struct qinst *qinst, int instructions_in_sequence, + bool is_thrend) { - struct qinst *q = vir_nop(); + /* No emitting our thrsw while the previous thrsw hasn't happened yet. */ + if (scoreboard->last_thrsw_tick + 3 > + scoreboard->tick - instructions_in_sequence) { + return false; + } + + for (int slot = 0; slot < instructions_in_sequence; slot++) { + /* No scheduling SFU when the result would land in the other + * thread. The simulator complains for safety, though it + * would only occur for dead code in our case. + */ + if (slot > 0 && + qinst->qpu.type == V3D_QPU_INSTR_TYPE_ALU && + (v3d_qpu_magic_waddr_is_sfu(qinst->qpu.alu.add.waddr) || + v3d_qpu_magic_waddr_is_sfu(qinst->qpu.alu.mul.waddr))) { + return false; + } + + if (slot > 0 && qinst->qpu.sig.ldvary) + return false; + + if (is_thrend && + !qpu_instruction_valid_in_thrend_slot(c, qinst, slot)) { + return false; + } - list_add(&q->link, &inst->link); + /* Note that the list is circular, so we can only do this up + * to instructions_in_sequence. + */ + qinst = (struct qinst *)qinst->link.next; + } - return q; + return true; } /** - * Emits a THRSW/LTHRSW signal in the stream, trying to move it up to pair - * with another instruction. + * Emits a THRSW signal in the stream, trying to move it up to pair with + * another instruction. */ -static void +static int emit_thrsw(struct v3d_compile *c, + struct qblock *block, struct choose_scoreboard *scoreboard, - const struct v3d_qpu_instr *inst) + struct qinst *inst, + bool is_thrend) { + int time = 0; + /* There should be nothing in a thrsw inst being scheduled other than * the signal bits. */ - assert(inst->type == V3D_QPU_INSTR_TYPE_ALU); - assert(inst->alu.add.op == V3D_QPU_A_NOP); - assert(inst->alu.mul.op == V3D_QPU_M_NOP); + assert(inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU); + assert(inst->qpu.alu.add.op == V3D_QPU_A_NOP); + assert(inst->qpu.alu.mul.op == V3D_QPU_M_NOP); + + /* Find how far back into previous instructions we can put the THRSW. */ + int slots_filled = 0; + struct qinst *merge_inst = NULL; + vir_for_each_inst_rev(prev_inst, block) { + struct v3d_qpu_sig sig = prev_inst->qpu.sig; + sig.thrsw = true; + uint32_t packed_sig; + + if (!v3d_qpu_sig_pack(c->devinfo, &sig, &packed_sig)) + break; - /* Try to find an earlier scheduled instruction that we can merge the - * thrsw into. - */ - int thrsw_ip = c->qpu_inst_count; - for (int i = 1; i <= MIN2(c->qpu_inst_count, 3); i++) { - uint64_t prev_instr = c->qpu_insts[c->qpu_inst_count - i]; - uint32_t prev_sig = QPU_GET_FIELD(prev_instr, QPU_SIG); + if (!valid_thrsw_sequence(c, scoreboard, + prev_inst, slots_filled + 1, + is_thrend)) { + break; + } - if (prev_sig == QPU_SIG_NONE) - thrsw_ip = c->qpu_inst_count - i; + merge_inst = prev_inst; + if (++slots_filled == 3) + break; } - if (thrsw_ip != c->qpu_inst_count) { - /* Merge the thrsw into the existing instruction. */ - c->qpu_insts[thrsw_ip] = - QPU_UPDATE_FIELD(c->qpu_insts[thrsw_ip], sig, QPU_SIG); + bool needs_free = false; + if (merge_inst) { + merge_inst->qpu.sig.thrsw = true; + needs_free = true; + scoreboard->last_thrsw_tick = scoreboard->tick - slots_filled; } else { - qpu_serialize_one_inst(c, inst); - update_scoreboard_for_chosen(scoreboard, inst); + scoreboard->last_thrsw_tick = scoreboard->tick; + insert_scheduled_instruction(c, block, scoreboard, inst); + time++; + slots_filled++; + merge_inst = inst; + } + + /* Insert any extra delay slot NOPs we need. */ + for (int i = 0; i < 3 - slots_filled; i++) { + emit_nop(c, block, scoreboard); + time++; } - /* Fill the delay slots. */ - while (c->qpu_inst_count < thrsw_ip + 3) { - update_scoreboard_for_chosen(scoreboard, v3d_qpu_nop()); - qpu_serialize_one_inst(c, v3d_qpu_nop()); + /* If we're emitting the last THRSW (other than program end), then + * signal that to the HW by emitting two THRSWs in a row. + */ + if (inst->is_last_thrsw) { + struct qinst *second_inst = + (struct qinst *)merge_inst->link.next; + second_inst->qpu.sig.thrsw = true; } + + /* If we put our THRSW into another instruction, free up the + * instruction that didn't end up scheduled into the list. + */ + if (needs_free) + free(inst); + + return time; } -#endif static uint32_t schedule_instructions(struct v3d_compile *c, @@ -1095,6 +1262,13 @@ schedule_instructions(struct v3d_compile *c, fprintf(stderr, "\n"); } + /* We can't mark_instruction_scheduled() the chosen inst until + * we're done identifying instructions to merge, so put the + * merged instructions on a list for a moment. + */ + struct list_head merged_list; + list_inithead(&merged_list); + /* Schedule this instruction onto the QPU list. Also try to * find an instruction to pair with it. */ @@ -1104,13 +1278,14 @@ schedule_instructions(struct v3d_compile *c, mark_instruction_scheduled(schedule_list, time, chosen, true); - merge = choose_instruction_to_schedule(devinfo, + while ((merge = + choose_instruction_to_schedule(devinfo, scoreboard, schedule_list, - chosen); - if (merge) { + chosen))) { time = MAX2(merge->unblocked_time, time); list_del(&merge->link); + list_addtail(&merge->link, &merged_list); (void)qpu_merge_inst(devinfo, inst, inst, &merge->inst->qpu); if (merge->inst->uniform != -1) { @@ -1156,8 +1331,8 @@ schedule_instructions(struct v3d_compile *c, * DAG edge as we do so. */ mark_instruction_scheduled(schedule_list, time, chosen, false); - - if (merge) { + list_for_each_entry(struct schedule_node, merge, &merged_list, + link) { mark_instruction_scheduled(schedule_list, time, merge, false); @@ -1167,40 +1342,24 @@ schedule_instructions(struct v3d_compile *c, free(merge->inst); } - if (0 && inst->sig.thrsw) { - /* XXX emit_thrsw(c, scoreboard, qinst); */ + if (inst->sig.thrsw) { + time += emit_thrsw(c, block, scoreboard, qinst, false); } else { - c->qpu_inst_count++; - list_addtail(&qinst->link, &block->instructions); - update_scoreboard_for_chosen(scoreboard, inst); - } - - scoreboard->tick++; - time++; - - if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH || - inst->sig.thrsw /* XXX */) { - block->branch_qpu_ip = c->qpu_inst_count - 1; - /* Fill the delay slots. - * - * We should fill these with actual instructions, - * instead, but that will probably need to be done - * after this, once we know what the leading - * instructions of the successors are (so we can - * handle A/B register file write latency) - */ - /* XXX: scoreboard */ - int slots = (inst->type == V3D_QPU_INSTR_TYPE_BRANCH ? - 3 : 2); - for (int i = 0; i < slots; i++) { - struct qinst *nop = vir_nop(); - list_addtail(&nop->link, &block->instructions); - - update_scoreboard_for_chosen(scoreboard, - &nop->qpu); - c->qpu_inst_count++; - scoreboard->tick++; - time++; + insert_scheduled_instruction(c, block, + scoreboard, qinst); + + if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH) { + block->branch_qpu_ip = c->qpu_inst_count - 1; + /* Fill the delay slots. + * + * We should fill these with actual instructions, + * instead, but that will probably need to be done + * after this, once we know what the leading + * instructions of the successors are (so we can + * handle A/B register file write latency) + */ + for (int i = 0; i < 3; i++) + emit_nop(c, block, scoreboard); } } } @@ -1308,6 +1467,8 @@ uint32_t v3d_qpu_schedule_instructions(struct v3d_compile *c) { const struct v3d_device_info *devinfo = c->devinfo; + struct qblock *end_block = list_last_entry(&c->blocks, + struct qblock, link); /* We reorder the uniforms as we schedule instructions, so save the * old data off and replace it. @@ -1322,11 +1483,10 @@ v3d_qpu_schedule_instructions(struct v3d_compile *c) struct choose_scoreboard scoreboard; memset(&scoreboard, 0, sizeof(scoreboard)); - scoreboard.last_waddr_add = ~0; - scoreboard.last_waddr_mul = ~0; scoreboard.last_ldvary_tick = -10; - scoreboard.last_sfu_write_tick = -10; + scoreboard.last_magic_sfu_write_tick = -10; scoreboard.last_uniforms_reset_tick = -10; + scoreboard.last_thrsw_tick = -10; if (debug) { fprintf(stderr, "Pre-schedule instructions\n"); @@ -1357,6 +1517,11 @@ v3d_qpu_schedule_instructions(struct v3d_compile *c) block->end_qpu_ip = c->qpu_inst_count - 1; } + /* Emit the program-end THRSW instruction. */; + struct qinst *thrsw = vir_nop(); + thrsw->qpu.sig.thrsw = true; + emit_thrsw(c, end_block, &scoreboard, thrsw, true); + qpu_set_branch_targets(c); assert(next_uniform == c->num_uniforms); diff --git a/lib/mesa/src/broadcom/compiler/qpu_validate.c b/lib/mesa/src/broadcom/compiler/qpu_validate.c index d99d76a8b..fb2ed123a 100644 --- a/lib/mesa/src/broadcom/compiler/qpu_validate.c +++ b/lib/mesa/src/broadcom/compiler/qpu_validate.c @@ -39,6 +39,18 @@ struct v3d_qpu_validate_state { const struct v3d_qpu_instr *last; int ip; int last_sfu_write; + int last_branch_ip; + int last_thrsw_ip; + + /* Set when we've found the last-THRSW signal, or if we were started + * in single-segment mode. + */ + bool last_thrsw_found; + + /* Set when we've found the THRSW after the last THRSW */ + bool thrend_found; + + int thrsw_count; }; static void @@ -63,6 +75,18 @@ fail_instr(struct v3d_qpu_validate_state *state, const char *msg) } static bool +in_branch_delay_slots(struct v3d_qpu_validate_state *state) +{ + return (state->ip - state->last_branch_ip) < 3; +} + +static bool +in_thrsw_delay_slots(struct v3d_qpu_validate_state *state) +{ + return (state->ip - state->last_thrsw_ip) < 3; +} + +static bool qpu_magic_waddr_matches(const struct v3d_qpu_instr *inst, bool (*predicate)(enum v3d_qpu_waddr waddr)) { @@ -85,6 +109,7 @@ qpu_magic_waddr_matches(const struct v3d_qpu_instr *inst, static void qpu_validate_inst(struct v3d_qpu_validate_state *state, struct qinst *qinst) { + const struct v3d_device_info *devinfo = state->c->devinfo; const struct v3d_qpu_instr *inst = &qinst->qpu; if (inst->type != V3D_QPU_INSTR_TYPE_ALU) @@ -94,10 +119,24 @@ qpu_validate_inst(struct v3d_qpu_validate_state *state, struct qinst *qinst) * r5 one instruction later, which is illegal to have * together. */ - if (state->last && state->last->sig.ldvary && inst->sig.ldunif) { + if (state->last && state->last->sig.ldvary && + (inst->sig.ldunif || inst->sig.ldunifa)) { fail_instr(state, "LDUNIF after a LDVARY"); } + /* GFXH-1633 */ + bool last_reads_ldunif = (state->last && (state->last->sig.ldunif || + state->last->sig.ldunifrf)); + bool last_reads_ldunifa = (state->last && (state->last->sig.ldunifa || + state->last->sig.ldunifarf)); + bool reads_ldunif = inst->sig.ldunif || inst->sig.ldunifrf; + bool reads_ldunifa = inst->sig.ldunifa || inst->sig.ldunifarf; + if ((last_reads_ldunif && reads_ldunifa) || + (last_reads_ldunifa && reads_ldunif)) { + fail_instr(state, + "LDUNIF and LDUNIFA can't be next to each other"); + } + int tmu_writes = 0; int sfu_writes = 0; int vpm_writes = 0; @@ -134,6 +173,19 @@ qpu_validate_inst(struct v3d_qpu_validate_state *state, struct qinst *qinst) } } + if (in_thrsw_delay_slots(state)) { + /* There's no way you want to start SFU during the THRSW delay + * slots, since the result would land in the other thread. + */ + if (sfu_writes) { + fail_instr(state, + "SFU write started during THRSW delay slots "); + } + + if (inst->sig.ldvary) + fail_instr(state, "LDVARY during THRSW delay slots"); + } + (void)qpu_magic_waddr_matches; /* XXX */ /* SFU r4 results come back two instructions later. No doing @@ -143,7 +195,7 @@ qpu_validate_inst(struct v3d_qpu_validate_state *state, struct qinst *qinst) if (v3d_qpu_uses_mux(inst, V3D_QPU_MUX_R4)) fail_instr(state, "R4 read too soon after SFU"); - if (v3d_qpu_writes_r4(inst)) + if (v3d_qpu_writes_r4(devinfo, inst)) fail_instr(state, "R4 write too soon after SFU"); if (sfu_writes) @@ -168,6 +220,60 @@ qpu_validate_inst(struct v3d_qpu_validate_state *state, struct qinst *qinst) if (sfu_writes) state->last_sfu_write = state->ip; + + if (inst->sig.thrsw) { + if (in_branch_delay_slots(state)) + fail_instr(state, "THRSW in a branch delay slot."); + + if (state->last_thrsw_found) + state->thrend_found = true; + + if (state->last_thrsw_ip == state->ip - 1) { + /* If it's the second THRSW in a row, then it's just a + * last-thrsw signal. + */ + if (state->last_thrsw_found) + fail_instr(state, "Two last-THRSW signals"); + state->last_thrsw_found = true; + } else { + if (in_thrsw_delay_slots(state)) { + fail_instr(state, + "THRSW too close to another THRSW."); + } + state->thrsw_count++; + state->last_thrsw_ip = state->ip; + } + } + + if (state->thrend_found && + state->last_thrsw_ip - state->ip <= 2 && + inst->type == V3D_QPU_INSTR_TYPE_ALU) { + if ((inst->alu.add.op != V3D_QPU_A_NOP && + !inst->alu.add.magic_write)) { + fail_instr(state, "RF write after THREND"); + } + + if ((inst->alu.mul.op != V3D_QPU_M_NOP && + !inst->alu.mul.magic_write)) { + fail_instr(state, "RF write after THREND"); + } + + if (v3d_qpu_sig_writes_address(devinfo, &inst->sig)) + fail_instr(state, "RF write after THREND"); + + /* GFXH-1625: No TMUWT in the last instruction */ + if (state->last_thrsw_ip - state->ip == 2 && + inst->alu.add.op == V3D_QPU_A_TMUWT) + fail_instr(state, "TMUWT in last instruction"); + } + + if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH) { + if (in_branch_delay_slots(state)) + fail_instr(state, "branch in a branch delay slot."); + if (in_thrsw_delay_slots(state)) + fail_instr(state, "branch in a THRSW delay slot."); + state->last_branch_ip = state->ip; + } } static void @@ -199,10 +305,22 @@ qpu_validate(struct v3d_compile *c) struct v3d_qpu_validate_state state = { .c = c, .last_sfu_write = -10, + .last_thrsw_ip = -10, + .last_branch_ip = -10, .ip = 0, + + .last_thrsw_found = !c->last_thrsw, }; vir_for_each_block(block, c) { qpu_validate_block(&state, block); } + + if (state.thrsw_count > 1 && !state.last_thrsw_found) { + fail_instr(&state, + "thread switch found without last-THRSW in program"); + } + + if (!state.thrend_found) + fail_instr(&state, "No program-end THRSW found"); } diff --git a/lib/mesa/src/broadcom/compiler/v3d33_tex.c b/lib/mesa/src/broadcom/compiler/v3d33_tex.c new file mode 100644 index 000000000..9af9285e0 --- /dev/null +++ b/lib/mesa/src/broadcom/compiler/v3d33_tex.c @@ -0,0 +1,248 @@ +/* + * Copyright © 2016-2018 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "v3d_compiler.h" + +/* We don't do any address packing. */ +#define __gen_user_data void +#define __gen_address_type uint32_t +#define __gen_address_offset(reloc) (*reloc) +#define __gen_emit_reloc(cl, reloc) +#include "cle/v3d_packet_v33_pack.h" + +void +v3d33_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr) +{ + unsigned unit = instr->texture_index; + + struct V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1 p0_unpacked = { + V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_header, + + .fetch_sample_mode = instr->op == nir_texop_txf, + }; + + struct V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1 p1_unpacked = { + }; + + switch (instr->sampler_dim) { + case GLSL_SAMPLER_DIM_1D: + if (instr->is_array) + p0_unpacked.lookup_type = TEXTURE_1D_ARRAY; + else + p0_unpacked.lookup_type = TEXTURE_1D; + break; + case GLSL_SAMPLER_DIM_2D: + case GLSL_SAMPLER_DIM_RECT: + if (instr->is_array) + p0_unpacked.lookup_type = TEXTURE_2D_ARRAY; + else + p0_unpacked.lookup_type = TEXTURE_2D; + break; + case GLSL_SAMPLER_DIM_3D: + p0_unpacked.lookup_type = TEXTURE_3D; + break; + case GLSL_SAMPLER_DIM_CUBE: + p0_unpacked.lookup_type = TEXTURE_CUBE_MAP; + break; + default: + unreachable("Bad sampler type"); + } + + struct qreg coords[5]; + int next_coord = 0; + for (unsigned i = 0; i < instr->num_srcs; i++) { + switch (instr->src[i].src_type) { + case nir_tex_src_coord: + for (int j = 0; j < instr->coord_components; j++) { + coords[next_coord++] = + ntq_get_src(c, instr->src[i].src, j); + } + if (instr->coord_components < 2) + coords[next_coord++] = vir_uniform_f(c, 0.5); + break; + case nir_tex_src_bias: + coords[next_coord++] = + ntq_get_src(c, instr->src[i].src, 0); + + p0_unpacked.bias_supplied = true; + break; + case nir_tex_src_lod: + coords[next_coord++] = + vir_FADD(c, + ntq_get_src(c, instr->src[i].src, 0), + vir_uniform(c, QUNIFORM_TEXTURE_FIRST_LEVEL, + unit)); + + if (instr->op != nir_texop_txf && + instr->op != nir_texop_tg4) { + p0_unpacked.disable_autolod_use_bias_only = true; + } + break; + case nir_tex_src_comparator: + coords[next_coord++] = + ntq_get_src(c, instr->src[i].src, 0); + + p0_unpacked.shadow = true; + break; + + case nir_tex_src_offset: { + nir_const_value *offset = + nir_src_as_const_value(instr->src[i].src); + p0_unpacked.texel_offset_for_s_coordinate = + offset->i32[0]; + + if (instr->coord_components >= 2) + p0_unpacked.texel_offset_for_t_coordinate = + offset->i32[1]; + + if (instr->coord_components >= 3) + p0_unpacked.texel_offset_for_r_coordinate = + offset->i32[2]; + break; + } + + default: + unreachable("unknown texture source"); + } + } + + bool return_16 = (c->key->tex[unit].return_size == 16 || + p0_unpacked.shadow); + + /* Limit the number of channels returned to both how many the NIR + * instruction writes and how many the instruction could produce. + */ + uint32_t instr_return_channels = nir_tex_instr_dest_size(instr); + if (return_16) + instr_return_channels = (instr_return_channels + 1) / 2; + + p1_unpacked.return_words_of_texture_data = + (1 << MIN2(instr_return_channels, + c->key->tex[unit].return_channels)) - 1; + + uint32_t p0_packed; + V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_pack(NULL, + (uint8_t *)&p0_packed, + &p0_unpacked); + + uint32_t p1_packed; + V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1_pack(NULL, + (uint8_t *)&p1_packed, + &p1_unpacked); + /* Load unit number into the address field, which will be be used by + * the driver to decide which texture to put in the actual address + * field. + */ + p1_packed |= unit << 5; + + /* There is no native support for GL texture rectangle coordinates, so + * we have to rescale from ([0, width], [0, height]) to ([0, 1], [0, + * 1]). + */ + if (instr->sampler_dim == GLSL_SAMPLER_DIM_RECT) { + coords[0] = vir_FMUL(c, coords[0], + vir_uniform(c, QUNIFORM_TEXRECT_SCALE_X, + unit)); + coords[1] = vir_FMUL(c, coords[1], + vir_uniform(c, QUNIFORM_TEXRECT_SCALE_Y, + unit)); + } + + struct qreg texture_u[] = { + vir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P0_0 + unit, p0_packed), + vir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P1, p1_packed), + }; + uint32_t next_texture_u = 0; + + for (int i = 0; i < next_coord; i++) { + struct qreg dst; + + if (i == next_coord - 1) + dst = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMUL); + else + dst = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMU); + + struct qinst *tmu = vir_MOV_dest(c, dst, coords[i]); + + if (i < 2) { + tmu->has_implicit_uniform = true; + tmu->src[vir_get_implicit_uniform_src(tmu)] = + texture_u[next_texture_u++]; + } + } + + vir_emit_thrsw(c); + + struct qreg return_values[4]; + for (int i = 0; i < 4; i++) { + /* Swizzling .zw of an RG texture should give undefined + * results, not crash the compiler. + */ + if (p1_unpacked.return_words_of_texture_data & (1 << i)) + return_values[i] = vir_LDTMU(c); + else + return_values[i] = c->undef; + } + + for (int i = 0; i < nir_tex_instr_dest_size(instr); i++) { + struct qreg chan; + + if (return_16) { + STATIC_ASSERT(PIPE_SWIZZLE_X == 0); + chan = return_values[i / 2]; + + if (nir_alu_type_get_base_type(instr->dest_type) == + nir_type_float) { + enum v3d_qpu_input_unpack unpack; + if (i & 1) + unpack = V3D_QPU_UNPACK_H; + else + unpack = V3D_QPU_UNPACK_L; + + chan = vir_FMOV(c, chan); + vir_set_unpack(c->defs[chan.index], 0, unpack); + } else { + /* If we're unpacking the low field, shift it + * up to the top first. + */ + if ((i & 1) == 0) { + chan = vir_SHL(c, chan, + vir_uniform_ui(c, 16)); + } + + /* Do proper sign extension to a 32-bit int. */ + if (nir_alu_type_get_base_type(instr->dest_type) == + nir_type_int) { + chan = vir_ASR(c, chan, + vir_uniform_ui(c, 16)); + } else { + chan = vir_SHR(c, chan, + vir_uniform_ui(c, 16)); + } + } + } else { + chan = vir_MOV(c, return_values[i]); + } + ntq_store_dest(c, &instr->dest, i, chan); + } +} diff --git a/lib/mesa/src/broadcom/compiler/v3d33_vpm_setup.c b/lib/mesa/src/broadcom/compiler/v3d33_vpm_setup.c new file mode 100644 index 000000000..8bce67dfa --- /dev/null +++ b/lib/mesa/src/broadcom/compiler/v3d33_vpm_setup.c @@ -0,0 +1,75 @@ +/* + * Copyright © 2016-2018 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "v3d_compiler.h" + +/* We don't do any address packing. */ +#define __gen_user_data void +#define __gen_address_type uint32_t +#define __gen_address_offset(reloc) (*reloc) +#define __gen_emit_reloc(cl, reloc) +#include "broadcom/cle/v3d_packet_v33_pack.h" + +void +v3d33_vir_vpm_read_setup(struct v3d_compile *c, int num_components) +{ + struct V3D33_VPM_GENERIC_BLOCK_READ_SETUP unpacked = { + V3D33_VPM_GENERIC_BLOCK_READ_SETUP_header, + + .horiz = true, + .laned = false, + /* If the field is 0, that means a read count of 32. */ + .num = num_components & 31, + .segs = true, + .stride = 1, + .size = VPM_SETUP_SIZE_32_BIT, + .addr = c->num_inputs, + }; + + uint32_t packed; + V3D33_VPM_GENERIC_BLOCK_READ_SETUP_pack(NULL, + (uint8_t *)&packed, + &unpacked); + vir_VPMSETUP(c, vir_uniform_ui(c, packed)); +} + +void +v3d33_vir_vpm_write_setup(struct v3d_compile *c) +{ + uint32_t packed; + struct V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP unpacked = { + V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_header, + + .horiz = true, + .laned = false, + .segs = true, + .stride = 1, + .size = VPM_SETUP_SIZE_32_BIT, + .addr = 0, + }; + + V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_pack(NULL, + (uint8_t *)&packed, + &unpacked); + vir_VPMSETUP(c, vir_uniform_ui(c, packed)); +} diff --git a/lib/mesa/src/broadcom/compiler/v3d40_tex.c b/lib/mesa/src/broadcom/compiler/v3d40_tex.c new file mode 100644 index 000000000..9f1fd9a0d --- /dev/null +++ b/lib/mesa/src/broadcom/compiler/v3d40_tex.c @@ -0,0 +1,263 @@ +/* + * Copyright © 2016-2018 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "v3d_compiler.h" + +/* We don't do any address packing. */ +#define __gen_user_data void +#define __gen_address_type uint32_t +#define __gen_address_offset(reloc) (*reloc) +#define __gen_emit_reloc(cl, reloc) +#include "cle/v3d_packet_v41_pack.h" + +static void +vir_TMU_WRITE(struct v3d_compile *c, enum v3d_qpu_waddr waddr, struct qreg val, + int *tmu_writes) +{ + vir_MOV_dest(c, vir_reg(QFILE_MAGIC, waddr), val); + + (*tmu_writes)++; +} + +static void +vir_WRTMUC(struct v3d_compile *c, enum quniform_contents contents, uint32_t data) +{ + struct qinst *inst = vir_NOP(c); + inst->qpu.sig.wrtmuc = true; + inst->has_implicit_uniform = true; + inst->src[0] = vir_uniform(c, contents, data); +} + +void +v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr) +{ + unsigned unit = instr->texture_index; + int tmu_writes = 0; + static const struct V3D41_TMU_CONFIG_PARAMETER_2 p2_unpacked_default = { + .op = V3D_TMU_OP_REGULAR, + }; + + struct V3D41_TMU_CONFIG_PARAMETER_0 p0_unpacked = { + }; + + struct V3D41_TMU_CONFIG_PARAMETER_1 p1_unpacked = { + .output_type_32_bit = (c->key->tex[unit].return_size == 32 && + !instr->is_shadow), + + .unnormalized_coordinates = (instr->sampler_dim == + GLSL_SAMPLER_DIM_RECT), + }; + + struct V3D41_TMU_CONFIG_PARAMETER_2 p2_unpacked = { + .op = V3D_TMU_OP_REGULAR, + + .gather_mode = instr->op == nir_texop_tg4, + .gather_component = instr->component, + + .coefficient_mode = instr->op == nir_texop_txd, + }; + + int non_array_components = instr->coord_components - instr->is_array; + struct qreg s; + + for (unsigned i = 0; i < instr->num_srcs; i++) { + switch (instr->src[i].src_type) { + case nir_tex_src_coord: + /* S triggers the lookup, so save it for the end. */ + s = ntq_get_src(c, instr->src[i].src, 0); + + if (non_array_components > 1) { + vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUT, + ntq_get_src(c, instr->src[i].src, + 1), &tmu_writes); + } + if (non_array_components > 2) { + vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUR, + ntq_get_src(c, instr->src[i].src, + 2), &tmu_writes); + } + + if (instr->is_array) { + vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUI, + ntq_get_src(c, instr->src[i].src, + instr->coord_components - 1), + &tmu_writes); + } + break; + + case nir_tex_src_bias: + vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUB, + ntq_get_src(c, instr->src[i].src, 0), + &tmu_writes); + break; + + case nir_tex_src_lod: + vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUB, + ntq_get_src(c, instr->src[i].src, 0), + &tmu_writes); + + if (instr->op != nir_texop_txf && + instr->op != nir_texop_tg4) { + p2_unpacked.disable_autolod = true; + } + break; + + case nir_tex_src_comparator: + vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUDREF, + ntq_get_src(c, instr->src[i].src, 0), + &tmu_writes); + break; + + case nir_tex_src_offset: { + nir_const_value *offset = + nir_src_as_const_value(instr->src[i].src); + + p2_unpacked.offset_s = offset->i32[0]; + if (instr->coord_components >= 2) + p2_unpacked.offset_t = offset->i32[1]; + if (instr->coord_components >= 3) + p2_unpacked.offset_r = offset->i32[2]; + break; + } + + default: + unreachable("unknown texture source"); + } + } + + /* Limit the number of channels returned to both how many the NIR + * instruction writes and how many the instruction could produce. + */ + uint32_t instr_return_channels = nir_tex_instr_dest_size(instr); + if (!p1_unpacked.output_type_32_bit) + instr_return_channels = (instr_return_channels + 1) / 2; + + p0_unpacked.return_words_of_texture_data = + (1 << MIN2(instr_return_channels, + c->key->tex[unit].return_channels)) - 1; + + /* Word enables can't ask for more channels than the output type could + * provide (2 for f16, 4 for 32-bit). + */ + assert(!p1_unpacked.output_type_32_bit || + p0_unpacked.return_words_of_texture_data < (1 << 4)); + assert(p1_unpacked.output_type_32_bit || + p0_unpacked.return_words_of_texture_data < (1 << 2)); + + uint32_t p0_packed; + V3D41_TMU_CONFIG_PARAMETER_0_pack(NULL, + (uint8_t *)&p0_packed, + &p0_unpacked); + + uint32_t p1_packed; + V3D41_TMU_CONFIG_PARAMETER_1_pack(NULL, + (uint8_t *)&p1_packed, + &p1_unpacked); + + uint32_t p2_packed; + V3D41_TMU_CONFIG_PARAMETER_2_pack(NULL, + (uint8_t *)&p2_packed, + &p2_unpacked); + + /* Load unit number into the high bits of the texture or sampler + * address field, which will be be used by the driver to decide which + * texture to put in the actual address field. + */ + p0_packed |= unit << 24; + p1_packed |= unit << 24; + + vir_WRTMUC(c, QUNIFORM_TMU_CONFIG_P0, p0_packed); + vir_WRTMUC(c, QUNIFORM_TMU_CONFIG_P1, p1_packed); + if (memcmp(&p2_unpacked, &p2_unpacked_default, sizeof(p2_unpacked)) != 0) + vir_WRTMUC(c, QUNIFORM_CONSTANT, p2_packed); + + if (instr->op == nir_texop_txf) { + assert(instr->sampler_dim != GLSL_SAMPLER_DIM_CUBE); + vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUSF, s, &tmu_writes); + } else if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE) { + vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUSCM, s, &tmu_writes); + } else { + vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUS, s, &tmu_writes); + } + + vir_emit_thrsw(c); + + /* The input FIFO has 16 slots across all threads, so make sure we + * don't overfill our allocation. + */ + while (tmu_writes > 16 / c->threads) + c->threads /= 2; + + struct qreg return_values[4]; + for (int i = 0; i < 4; i++) { + /* Swizzling .zw of an RG texture should give undefined + * results, not crash the compiler. + */ + if (p0_unpacked.return_words_of_texture_data & (1 << i)) + return_values[i] = vir_LDTMU(c); + else + return_values[i] = c->undef; + } + + for (int i = 0; i < nir_tex_instr_dest_size(instr); i++) { + struct qreg chan; + + if (!p1_unpacked.output_type_32_bit) { + STATIC_ASSERT(PIPE_SWIZZLE_X == 0); + chan = return_values[i / 2]; + + if (nir_alu_type_get_base_type(instr->dest_type) == + nir_type_float) { + enum v3d_qpu_input_unpack unpack; + if (i & 1) + unpack = V3D_QPU_UNPACK_H; + else + unpack = V3D_QPU_UNPACK_L; + + chan = vir_FMOV(c, chan); + vir_set_unpack(c->defs[chan.index], 0, unpack); + } else { + /* If we're unpacking the low field, shift it + * up to the top first. + */ + if ((i & 1) == 0) { + chan = vir_SHL(c, chan, + vir_uniform_ui(c, 16)); + } + + /* Do proper sign extension to a 32-bit int. */ + if (nir_alu_type_get_base_type(instr->dest_type) == + nir_type_int) { + chan = vir_ASR(c, chan, + vir_uniform_ui(c, 16)); + } else { + chan = vir_SHR(c, chan, + vir_uniform_ui(c, 16)); + } + } + } else { + chan = vir_MOV(c, return_values[i]); + } + ntq_store_dest(c, &instr->dest, i, chan); + } +} diff --git a/lib/mesa/src/broadcom/compiler/v3d_compiler.h b/lib/mesa/src/broadcom/compiler/v3d_compiler.h index 021c88f7b..070e6a3aa 100644 --- a/lib/mesa/src/broadcom/compiler/v3d_compiler.h +++ b/lib/mesa/src/broadcom/compiler/v3d_compiler.h @@ -33,6 +33,7 @@ #include "util/macros.h" #include "common/v3d_debug.h" +#include "common/v3d_device_info.h" #include "compiler/nir/nir.h" #include "util/list.h" #include "util/u_math.h" @@ -72,7 +73,6 @@ enum qfile { * or physical registers later. */ QFILE_TEMP, - QFILE_VARY, QFILE_UNIF, QFILE_TLB, QFILE_TLBU, @@ -115,6 +115,7 @@ static inline struct qreg vir_reg(enum qfile file, uint32_t index) */ struct qpu_reg { bool magic; + bool smimm; int index; }; @@ -134,6 +135,7 @@ struct qinst { struct qreg src[3]; bool cond_is_exec_mask; bool has_implicit_uniform; + bool is_last_thrsw; /* After vir_to_qpu.c: If instr reads a uniform, which uniform from * the uncompiled stream it is. @@ -171,7 +173,7 @@ enum quniform_contents { QUNIFORM_USER_CLIP_PLANE, /** - * A reference to a texture config parameter 0 uniform. + * A reference to a V3D 3.x texture config parameter 0 uniform. * * This is a uniform implicitly loaded with a QPU_W_TMU* write, which * defines texture type, miplevels, and such. It will be found as a @@ -212,15 +214,22 @@ enum quniform_contents { QUNIFORM_TEXTURE_CONFIG_P0_32, /** - * A reference to a texture config parameter 1 uniform. + * A reference to a V3D 3.x texture config parameter 1 uniform. * * This is a uniform implicitly loaded with a QPU_W_TMU* write, which - * defines texture width, height, filters, and wrap modes. It will be - * found as a parameter to the second QOP_TEX_[STRB] instruction in a - * sequence. + * has the pointer to the indirect texture state. Our data[] field + * will have a packed p1 value, but the address field will be just + * which texture unit's texture should be referenced. */ QUNIFORM_TEXTURE_CONFIG_P1, + /* A a V3D 4.x texture config parameter. The high 8 bits will be + * which texture or sampler is being sampled, and the driver must + * replace the address field with the appropriate address. + */ + QUNIFORM_TMU_CONFIG_P0, + QUNIFORM_TMU_CONFIG_P1, + QUNIFORM_TEXTURE_FIRST_LEVEL, QUNIFORM_TEXTURE_WIDTH, @@ -229,8 +238,6 @@ enum quniform_contents { QUNIFORM_TEXTURE_ARRAY_SIZE, QUNIFORM_TEXTURE_LEVELS, - QUNIFORM_TEXTURE_MSAA_ADDR, - QUNIFORM_UBO_ADDR, QUNIFORM_TEXRECT_SCALE_X, @@ -238,10 +245,14 @@ enum quniform_contents { QUNIFORM_TEXTURE_BORDER_COLOR, - QUNIFORM_STENCIL, - QUNIFORM_ALPHA_REF, QUNIFORM_SAMPLE_MASK, + + /** + * Returns the the offset of the scratch buffer for register spilling. + */ + QUNIFORM_SPILL_OFFSET, + QUNIFORM_SPILL_SIZE_PER_THREAD, }; struct v3d_varying_slot { @@ -290,17 +301,11 @@ struct v3d_key { uint8_t swizzle[4]; uint8_t return_size; uint8_t return_channels; - union { - struct { - unsigned compare_mode:1; - unsigned compare_func:3; - unsigned wrap_s:3; - unsigned wrap_t:3; - }; - struct { - uint16_t msaa_width, msaa_height; - }; - }; + unsigned compare_mode:1; + unsigned compare_func:3; + bool clamp_s:1; + bool clamp_t:1; + bool clamp_r:1; } tex[V3D_MAX_TEXTURE_SAMPLERS]; uint8_t ucp_enables; }; @@ -318,10 +323,16 @@ struct v3d_fs_key { bool sample_alpha_to_coverage; bool sample_alpha_to_one; bool clamp_color; + bool shade_model_flat; uint8_t nr_cbufs; uint8_t swap_color_rb; /* Mask of which render targets need to be written as 32-bit floats */ uint8_t f32_color_rb; + /* Masks of which render targets need to be written as ints/uints. + * Used by gallium to work around lost information in TGSI. + */ + uint8_t int_color_rb; + uint8_t uint_color_rb; uint8_t alpha_test_func; uint8_t logicop_func; uint32_t point_sprite_mask; @@ -376,6 +387,48 @@ struct qblock { /** @} */ }; +/** Which util/list.h add mode we should use when inserting an instruction. */ +enum vir_cursor_mode { + vir_cursor_add, + vir_cursor_addtail, +}; + +/** + * Tracking structure for where new instructions should be inserted. Create + * with one of the vir_after_inst()-style helper functions. + * + * This does not protect against removal of the block or instruction, so we + * have an assert in instruction removal to try to catch it. + */ +struct vir_cursor { + enum vir_cursor_mode mode; + struct list_head *link; +}; + +static inline struct vir_cursor +vir_before_inst(struct qinst *inst) +{ + return (struct vir_cursor){ vir_cursor_addtail, &inst->link }; +} + +static inline struct vir_cursor +vir_after_inst(struct qinst *inst) +{ + return (struct vir_cursor){ vir_cursor_add, &inst->link }; +} + +static inline struct vir_cursor +vir_before_block(struct qblock *block) +{ + return (struct vir_cursor){ vir_cursor_add, &block->instructions }; +} + +static inline struct vir_cursor +vir_after_block(struct qblock *block) +{ + return (struct vir_cursor){ vir_cursor_addtail, &block->instructions }; +} + /** * Compiler state saved across compiler invocations, for any expensive global * setup. @@ -383,7 +436,8 @@ struct qblock { struct v3d_compiler { const struct v3d_device_info *devinfo; struct ra_regs *regs; - unsigned int reg_class[3]; + unsigned int reg_class_phys[3]; + unsigned int reg_class_phys_or_acc[3]; }; struct v3d_compile { @@ -418,16 +472,16 @@ struct v3d_compile { uint32_t uniforms_array_size; /* Booleans for whether the corresponding QFILE_VARY[i] is - * flat-shaded. This doesn't count gl_FragColor flat-shading, which is - * controlled by shader->color_inputs and rasterizer->flatshade in the - * gallium driver. + * flat-shaded. This includes gl_FragColor flat-shading, which is + * customized based on the shademodel_flat shader key. */ - BITSET_WORD flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; + uint32_t flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; - /* Booleans for whether the corresponding QFILE_VARY[i] uses the - * default glShadeModel() behavior. - */ - BITSET_WORD shade_model_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; + uint32_t noperspective_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; + + uint32_t centroid_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; + + bool uses_center_w; struct v3d_ubo_range *ubo_ranges; bool *ubo_range_used; @@ -461,6 +515,20 @@ struct v3d_compile { uint8_t vattr_sizes[V3D_MAX_VS_INPUTS]; uint32_t num_vpm_writes; + /* Size in bytes of registers that have been spilled. This is how much + * space needs to be available in the spill BO per thread per QPU. + */ + uint32_t spill_size; + /* Shader-db stats for register spilling. */ + uint32_t spills, fills; + /** + * Register spilling's per-thread base address, shared between each + * spill/fill's addressing calculations. + */ + struct qreg spill_base; + /* Bit vector of which temps may be spilled */ + BITSET_WORD *spillable; + /** * Array of the VARYING_SLOT_* of all FS QFILE_VARY reads. * @@ -483,6 +551,7 @@ struct v3d_compile { /* Live ranges of temps. */ int *temp_start, *temp_end; + bool live_intervals_valid; uint32_t *uniform_data; enum quniform_contents *uniform_contents; @@ -497,6 +566,7 @@ struct v3d_compile { struct qreg undef; uint32_t num_temps; + struct vir_cursor cursor; struct list_head blocks; int next_block_index; struct qblock *cur_block; @@ -527,12 +597,16 @@ struct v3d_compile { uint32_t program_id; uint32_t variant_id; - /* Set to compile program in threaded FS mode, where SIG_THREAD_SWITCH - * is used to hide texturing latency at the cost of limiting ourselves - * to the bottom half of physical reg space. + /* Set to compile program in in 1x, 2x, or 4x threaded mode, where + * SIG_THREAD_SWITCH is used to hide texturing latency at the cost of + * limiting ourselves to the part of the physical reg space. + * + * On V3D 3.x, 2x or 4x divide the physical reg space by 2x or 4x. On + * V3D 4.x, all shaders are 2x threaded, and 4x only divides the + * physical reg space in half. */ - bool fs_threaded; - + uint8_t threads; + struct qinst *last_thrsw; bool last_thrsw_at_top_level; bool failed; @@ -550,9 +624,15 @@ struct v3d_prog_data { struct v3d_ubo_range *ubo_ranges; uint32_t num_ubo_ranges; uint32_t ubo_size; + uint32_t spill_size; uint8_t num_inputs; + uint8_t threads; + /* For threads > 1, whether the program should be dispatched in the + * after-final-THRSW state. + */ + bool single_seg; }; struct v3d_vs_prog_data { @@ -568,6 +648,9 @@ struct v3d_vs_prog_data { /* Total number of components written, for the shader state record. */ uint32_t vpm_output_size; + + /* Value to be programmed in VCM_CACHE_SIZE. */ + uint8_t vcm_cache_size; }; struct v3d_fs_prog_data { @@ -575,17 +658,20 @@ struct v3d_fs_prog_data { struct v3d_varying_slot input_slots[V3D_MAX_FS_INPUTS]; - /* Bitmask for whether the corresponding input is flat-shaded, - * independent of rasterizer (gl_FragColor) flat-shading. - */ - BITSET_WORD flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; - /* Bitmask for whether the corresponding input uses the default - * glShadeModel() behavior. + /* Array of flat shade flags. + * + * Each entry is only 24 bits (high 8 bits 0), to match the hardware + * packet layout. */ - BITSET_WORD shade_model_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; + uint32_t flat_shade_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1]; + + uint32_t noperspective_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1]; + + uint32_t centroid_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1]; bool writes_z; bool discard; + bool uses_center_w; }; /* Special nir_load_input intrinsic index for loading the current TLB @@ -644,6 +730,7 @@ void vir_set_unpack(struct qinst *inst, int src, enum v3d_qpu_input_unpack unpack); struct qreg vir_get_temp(struct v3d_compile *c); +void vir_emit_last_thrsw(struct v3d_compile *c); void vir_calculate_live_intervals(struct v3d_compile *c); bool vir_has_implicit_uniform(struct qinst *inst); int vir_get_implicit_uniform_src(struct qinst *inst); @@ -658,10 +745,14 @@ bool vir_is_add(struct qinst *inst); bool vir_is_mul(struct qinst *inst); bool vir_is_float_input(struct qinst *inst); bool vir_depends_on_flags(struct qinst *inst); -bool vir_writes_r3(struct qinst *inst); -bool vir_writes_r4(struct qinst *inst); +bool vir_writes_r3(const struct v3d_device_info *devinfo, struct qinst *inst); +bool vir_writes_r4(const struct v3d_device_info *devinfo, struct qinst *inst); struct qreg vir_follow_movs(struct v3d_compile *c, struct qreg reg); uint8_t vir_channels_written(struct qinst *inst); +struct qreg ntq_get_src(struct v3d_compile *c, nir_src src, int i); +void ntq_store_dest(struct v3d_compile *c, nir_dest *dest, int chan, + struct qreg result); +void vir_emit_thrsw(struct v3d_compile *c); void vir_dump(struct v3d_compile *c); void vir_dump_inst(struct v3d_compile *c, struct qinst *inst); @@ -681,10 +772,15 @@ void v3d_nir_lower_io(nir_shader *s, struct v3d_compile *c); void v3d_nir_lower_txf_ms(nir_shader *s, struct v3d_compile *c); void vir_lower_uniforms(struct v3d_compile *c); -void v3d_vir_to_qpu(struct v3d_compile *c); +void v3d33_vir_vpm_read_setup(struct v3d_compile *c, int num_components); +void v3d33_vir_vpm_write_setup(struct v3d_compile *c); +void v3d33_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr); +void v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr); + +void v3d_vir_to_qpu(struct v3d_compile *c, struct qpu_reg *temp_registers); uint32_t v3d_qpu_schedule_instructions(struct v3d_compile *c); void qpu_validate(struct v3d_compile *c); -struct qpu_reg *v3d_register_allocate(struct v3d_compile *c); +struct qpu_reg *v3d_register_allocate(struct v3d_compile *c, bool *spilled); bool vir_init_reg_sets(struct v3d_compiler *compiler); void vir_PF(struct v3d_compile *c, struct qreg src, enum v3d_qpu_pf pf); @@ -751,6 +847,14 @@ vir_##name##_dest(struct v3d_compile *c, struct qreg dest, \ return vir_emit_nondef(c, vir_inst(op, dest, a, b)); \ } +#define VIR_NODST_0(name, vir_inst, op) \ +static inline struct qinst * \ +vir_##name(struct v3d_compile *c) \ +{ \ + return vir_emit_nondef(c, vir_inst(op, c->undef, \ + c->undef, c->undef)); \ +} + #define VIR_NODST_1(name, vir_inst, op) \ static inline struct qinst * \ vir_##name(struct v3d_compile *c, struct qreg a) \ @@ -767,6 +871,33 @@ vir_##name(struct v3d_compile *c, struct qreg a, struct qreg b) \ a, b)); \ } +#define VIR_SFU(name) \ +static inline struct qreg \ +vir_##name(struct v3d_compile *c, struct qreg a) \ +{ \ + if (c->devinfo->ver >= 41) { \ + return vir_emit_def(c, vir_add_inst(V3D_QPU_A_##name, \ + c->undef, \ + a, c->undef)); \ + } else { \ + vir_FMOV_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_##name), a); \ + return vir_FMOV(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R4)); \ + } \ +} \ +static inline struct qinst * \ +vir_##name##_dest(struct v3d_compile *c, struct qreg dest, \ + struct qreg a) \ +{ \ + if (c->devinfo->ver >= 41) { \ + return vir_emit_nondef(c, vir_add_inst(V3D_QPU_A_##name, \ + dest, \ + a, c->undef)); \ + } else { \ + vir_FMOV_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_##name), a); \ + return vir_FMOV_dest(c, dest, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R4)); \ + } \ +} + #define VIR_A_ALU2(name) VIR_ALU2(name, vir_add_inst, V3D_QPU_A_##name) #define VIR_M_ALU2(name) VIR_ALU2(name, vir_mul_inst, V3D_QPU_M_##name) #define VIR_A_ALU1(name) VIR_ALU1(name, vir_add_inst, V3D_QPU_A_##name) @@ -777,6 +908,7 @@ vir_##name(struct v3d_compile *c, struct qreg a, struct qreg b) \ #define VIR_M_NODST_2(name) VIR_NODST_2(name, vir_mul_inst, V3D_QPU_M_##name) #define VIR_A_NODST_1(name) VIR_NODST_1(name, vir_add_inst, V3D_QPU_A_##name) #define VIR_M_NODST_1(name) VIR_NODST_1(name, vir_mul_inst, V3D_QPU_M_##name) +#define VIR_A_NODST_0(name) VIR_NODST_0(name, vir_add_inst, V3D_QPU_A_##name) VIR_A_ALU2(FADD) VIR_A_ALU2(VFPACK) @@ -799,15 +931,19 @@ VIR_A_ALU2(OR) VIR_A_ALU2(XOR) VIR_A_ALU2(VADD) VIR_A_ALU2(VSUB) +VIR_A_NODST_2(STVPMV) VIR_A_ALU1(NOT) VIR_A_ALU1(NEG) VIR_A_ALU1(FLAPUSH) VIR_A_ALU1(FLBPUSH) -VIR_A_ALU1(FLBPOP) +VIR_A_ALU1(FLPOP) VIR_A_ALU1(SETMSF) VIR_A_ALU1(SETREVF) -VIR_A_ALU1(TIDX) -VIR_A_ALU1(EIDX) +VIR_A_ALU0(TIDX) +VIR_A_ALU0(EIDX) +VIR_A_ALU1(LDVPMV_IN) +VIR_A_ALU1(LDVPMV_OUT) +VIR_A_ALU0(TMUWT) VIR_A_ALU0(FXCD) VIR_A_ALU0(XCD) @@ -816,6 +952,7 @@ VIR_A_ALU0(YCD) VIR_A_ALU0(MSF) VIR_A_ALU0(REVF) VIR_A_NODST_1(VPMSETUP) +VIR_A_NODST_0(VPMWT) VIR_A_ALU2(FCMP) VIR_A_ALU2(VFMAX) @@ -843,6 +980,13 @@ VIR_M_NODST_2(MULTOP) VIR_M_ALU1(MOV) VIR_M_ALU1(FMOV) +VIR_SFU(RECIP) +VIR_SFU(RSQRT) +VIR_SFU(EXP) +VIR_SFU(LOG) +VIR_SFU(SIN) +VIR_SFU(RSQRT2) + static inline struct qinst * vir_MOV_cond(struct v3d_compile *c, enum v3d_qpu_cond cond, struct qreg dest, struct qreg src) @@ -862,18 +1006,35 @@ vir_SEL(struct v3d_compile *c, enum v3d_qpu_cond cond, return t; } -static inline void -vir_VPM_WRITE(struct v3d_compile *c, struct qreg val) -{ - vir_MOV_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_VPM), val); -} - static inline struct qinst * vir_NOP(struct v3d_compile *c) { return vir_emit_nondef(c, vir_add_inst(V3D_QPU_A_NOP, c->undef, c->undef, c->undef)); } + +static inline struct qreg +vir_LDTMU(struct v3d_compile *c) +{ + if (c->devinfo->ver >= 41) { + struct qinst *ldtmu = vir_add_inst(V3D_QPU_A_NOP, c->undef, + c->undef, c->undef); + ldtmu->qpu.sig.ldtmu = true; + + return vir_emit_def(c, ldtmu); + } else { + vir_NOP(c)->qpu.sig.ldtmu = true; + return vir_MOV(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R4)); + } +} + +static inline struct qreg +vir_UMUL(struct v3d_compile *c, struct qreg src0, struct qreg src1) +{ + vir_MULTOP(c, src0, src1); + return vir_UMUL24(c, src0, src1); +} + /* static inline struct qreg vir_LOAD_IMM(struct v3d_compile *c, uint32_t val) diff --git a/lib/mesa/src/broadcom/compiler/v3d_nir_lower_io.c b/lib/mesa/src/broadcom/compiler/v3d_nir_lower_io.c index 9cdcc0219..10bc25811 100644 --- a/lib/mesa/src/broadcom/compiler/v3d_nir_lower_io.c +++ b/lib/mesa/src/broadcom/compiler/v3d_nir_lower_io.c @@ -52,44 +52,6 @@ replace_intrinsic_with_vec(nir_builder *b, nir_intrinsic_instr *intr, } static void -v3d_nir_lower_output(struct v3d_compile *c, nir_builder *b, - nir_intrinsic_instr *intr) -{ - nir_variable *output_var = NULL; - nir_foreach_variable(var, &c->s->outputs) { - if (var->data.driver_location == nir_intrinsic_base(intr)) { - output_var = var; - break; - } - } - assert(output_var); - - if (c->vs_key) { - int slot = output_var->data.location; - bool used = false; - - switch (slot) { - case VARYING_SLOT_PSIZ: - case VARYING_SLOT_POS: - used = true; - break; - - default: - for (int i = 0; i < c->vs_key->num_fs_inputs; i++) { - if (v3d_slot_get_slot(c->vs_key->fs_inputs[i]) == slot) { - used = true; - break; - } - } - break; - } - - if (!used) - nir_instr_remove(&intr->instr); - } -} - -static void v3d_nir_lower_uniform(struct v3d_compile *c, nir_builder *b, nir_intrinsic_instr *intr) { @@ -135,10 +97,6 @@ v3d_nir_lower_io_instr(struct v3d_compile *c, nir_builder *b, case nir_intrinsic_load_input: break; - case nir_intrinsic_store_output: - v3d_nir_lower_output(c, b, intr); - break; - case nir_intrinsic_load_uniform: v3d_nir_lower_uniform(c, b, intr); break; diff --git a/lib/mesa/src/broadcom/compiler/v3d_nir_lower_txf_ms.c b/lib/mesa/src/broadcom/compiler/v3d_nir_lower_txf_ms.c new file mode 100644 index 000000000..ffaee0d76 --- /dev/null +++ b/lib/mesa/src/broadcom/compiler/v3d_nir_lower_txf_ms.c @@ -0,0 +1,93 @@ +/* + * Copyright © 2015 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "v3d_compiler.h" +#include "compiler/nir/nir_builder.h" + +/** @file v3d_nir_lower_txf_ms.c + * + * V3D's MSAA surfaces are laid out in UIF textures where each pixel is a 2x2 + * quad in the texture. This pass lowers the txf_ms with a ms_index source to + * a plain txf with the sample_index pulling out the correct texel from the + * 2x2 quad. + */ + +#define V3D_MAX_SAMPLES 4 + +static void +vc4_nir_lower_txf_ms_instr(struct v3d_compile *c, nir_builder *b, + nir_tex_instr *instr) +{ + if (instr->op != nir_texop_txf_ms) + return; + + b->cursor = nir_before_instr(&instr->instr); + + int coord_index = nir_tex_instr_src_index(instr, nir_tex_src_coord); + int sample_index = nir_tex_instr_src_index(instr, nir_tex_src_ms_index); + nir_ssa_def *coord = instr->src[coord_index].src.ssa; + nir_ssa_def *sample = instr->src[sample_index].src.ssa; + + nir_ssa_def *one = nir_imm_int(b, 1); + coord = nir_ishl(b, coord, nir_imm_int(b, 1)); + coord = nir_vec2(b, + nir_iadd(b, + nir_channel(b, coord, 0), + nir_iand(b, sample, one)), + nir_iadd(b, + nir_channel(b, coord, 1), + nir_iand(b, nir_ushr(b, sample, one), one))); + + nir_instr_rewrite_src(&instr->instr, + &instr->src[nir_tex_src_coord].src, + nir_src_for_ssa(coord)); + nir_tex_instr_remove_src(instr, sample_index); + instr->op = nir_texop_txf; + instr->sampler_dim = GLSL_SAMPLER_DIM_2D; +} + +void +v3d_nir_lower_txf_ms(nir_shader *s, struct v3d_compile *c) +{ + nir_foreach_function(function, s) { + if (!function->impl) + continue; + + nir_builder b; + nir_builder_init(&b, function->impl); + + nir_foreach_block(block, function->impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type != nir_instr_type_tex) + continue; + + vc4_nir_lower_txf_ms_instr(c, &b, + nir_instr_as_tex(instr)); + } + } + + nir_metadata_preserve(function->impl, + nir_metadata_block_index | + nir_metadata_dominance); + } +} diff --git a/lib/mesa/src/broadcom/compiler/vir.c b/lib/mesa/src/broadcom/compiler/vir.c index 99b31841b..3f5a28d1b 100644 --- a/lib/mesa/src/broadcom/compiler/vir.c +++ b/lib/mesa/src/broadcom/compiler/vir.c @@ -21,6 +21,7 @@ * IN THE SOFTWARE. */ +#include "broadcom/common/v3d_device_info.h" #include "v3d_compiler.h" int @@ -73,6 +74,8 @@ vir_has_implicit_uniform(struct qinst *inst) int vir_get_implicit_uniform_src(struct qinst *inst) { + if (!vir_has_implicit_uniform(inst)) + return -1; return vir_get_nsrc(inst) - 1; } @@ -91,6 +94,11 @@ vir_has_side_effects(struct v3d_compile *c, struct qinst *inst) case V3D_QPU_A_SETREVF: case V3D_QPU_A_SETMSF: case V3D_QPU_A_VPMSETUP: + case V3D_QPU_A_STVPMV: + case V3D_QPU_A_STVPMD: + case V3D_QPU_A_STVPMP: + case V3D_QPU_A_VPMWT: + case V3D_QPU_A_TMUWT: return true; default: break; @@ -104,8 +112,12 @@ vir_has_side_effects(struct v3d_compile *c, struct qinst *inst) } } - if (inst->qpu.sig.ldtmu) + if (inst->qpu.sig.ldtmu || + inst->qpu.sig.ldvary || + inst->qpu.sig.wrtmuc || + inst->qpu.sig.thrsw) { return true; + } return false; } @@ -183,6 +195,11 @@ vir_is_tex(struct qinst *inst) if (inst->dst.file == QFILE_MAGIC) return v3d_qpu_magic_waddr_is_tmu(inst->dst.index); + if (inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU && + inst->qpu.alu.add.op == V3D_QPU_A_TMUWT) { + return true; + } + return false; } @@ -198,11 +215,10 @@ vir_depends_on_flags(struct qinst *inst) } bool -vir_writes_r3(struct qinst *inst) +vir_writes_r3(const struct v3d_device_info *devinfo, struct qinst *inst) { for (int i = 0; i < vir_get_nsrc(inst); i++) { switch (inst->src[i].file) { - case QFILE_VARY: case QFILE_VPM: return true; default: @@ -210,11 +226,18 @@ vir_writes_r3(struct qinst *inst) } } + if (devinfo->ver < 41 && (inst->qpu.sig.ldvary || + inst->qpu.sig.ldtlb || + inst->qpu.sig.ldtlbu || + inst->qpu.sig.ldvpm)) { + return true; + } + return false; } bool -vir_writes_r4(struct qinst *inst) +vir_writes_r4(const struct v3d_device_info *devinfo, struct qinst *inst) { switch (inst->dst.file) { case QFILE_MAGIC: @@ -231,7 +254,7 @@ vir_writes_r4(struct qinst *inst) break; } - if (inst->qpu.sig.ldtmu) + if (devinfo->ver < 41 && inst->qpu.sig.ldtmu) return true; return false; @@ -339,10 +362,17 @@ vir_get_temp(struct v3d_compile *c) if (c->num_temps > c->defs_array_size) { uint32_t old_size = c->defs_array_size; c->defs_array_size = MAX2(old_size * 2, 16); + c->defs = reralloc(c, c->defs, struct qinst *, c->defs_array_size); memset(&c->defs[old_size], 0, sizeof(c->defs[0]) * (c->defs_array_size - old_size)); + + c->spillable = reralloc(c, c->spillable, + BITSET_WORD, + BITSET_WORDS(c->defs_array_size)); + for (int i = old_size; i < c->defs_array_size; i++) + BITSET_SET(c->spillable, i); } return reg; @@ -403,11 +433,17 @@ vir_branch_inst(enum v3d_qpu_branch_cond cond, struct qreg src) static void vir_emit(struct v3d_compile *c, struct qinst *inst) { - list_addtail(&inst->link, &c->cur_block->instructions); + switch (c->cursor.mode) { + case vir_cursor_add: + list_add(&inst->link, c->cursor.link); + break; + case vir_cursor_addtail: + list_addtail(&inst->link, c->cursor.link); + break; + } - if (inst->dst.file == QFILE_MAGIC && - inst->dst.index == V3D_QPU_WADDR_VPM) - c->num_vpm_writes++; + c->cursor = vir_after_inst(inst); + c->live_intervals_valid = false; } /* Updates inst to write to a new temporary, emits it, and notes the def. */ @@ -416,6 +452,16 @@ vir_emit_def(struct v3d_compile *c, struct qinst *inst) { assert(inst->dst.file == QFILE_NULL); + /* If we're emitting an instruction that's a def, it had better be + * writing a register. + */ + if (inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU) { + assert(inst->qpu.alu.add.op == V3D_QPU_A_NOP || + v3d_qpu_add_op_has_dst(inst->qpu.alu.add.op)); + assert(inst->qpu.alu.mul.op == V3D_QPU_M_NOP || + v3d_qpu_mul_op_has_dst(inst->qpu.alu.mul.op)); + } + inst->dst = vir_get_temp(c); if (inst->dst.file == QFILE_TEMP) @@ -457,6 +503,7 @@ void vir_set_emit_block(struct v3d_compile *c, struct qblock *block) { c->cur_block = block; + c->cursor = vir_after_block(block); list_addtail(&block->link, &c->blocks); } @@ -520,6 +567,7 @@ vir_compile_init(const struct v3d_compiler *compiler, c->key = key; c->program_id = program_id; c->variant_id = variant_id; + c->threads = 4; s = nir_shader_clone(c, s); c->s = s; @@ -537,11 +585,18 @@ vir_compile_init(const struct v3d_compiler *compiler, return c; } +static int +type_size_vec4(const struct glsl_type *type) +{ + return glsl_count_attribute_slots(type, false); +} + static void v3d_lower_nir(struct v3d_compile *c) { struct nir_lower_tex_options tex_options = { - .lower_rect = false, /* XXX */ + .lower_txd = true, + .lower_rect = false, /* XXX: Use this on V3D 3.x */ .lower_txp = ~0, /* Apply swizzles to all samplers. */ .swizzle_result = ~0, @@ -553,6 +608,13 @@ v3d_lower_nir(struct v3d_compile *c) for (int i = 0; i < ARRAY_SIZE(c->key->tex); i++) { for (int j = 0; j < 4; j++) tex_options.swizzles[i][j] = c->key->tex[i].swizzle[j]; + + if (c->key->tex[i].clamp_s) + tex_options.saturate_s |= 1 << i; + if (c->key->tex[i].clamp_t) + tex_options.saturate_t |= 1 << i; + if (c->key->tex[i].clamp_r) + tex_options.saturate_r |= 1 << i; } NIR_PASS_V(c->s, nir_lower_tex, &tex_options); @@ -562,6 +624,7 @@ static void v3d_lower_nir_late(struct v3d_compile *c) { NIR_PASS_V(c->s, v3d_nir_lower_io, c); + NIR_PASS_V(c->s, v3d_nir_lower_txf_ms, c); NIR_PASS_V(c->s, nir_lower_idiv); } @@ -620,6 +683,10 @@ static void v3d_set_prog_data(struct v3d_compile *c, struct v3d_prog_data *prog_data) { + prog_data->threads = c->threads; + prog_data->single_seg = !c->last_thrsw; + prog_data->spill_size = c->spill_size; + v3d_set_prog_data_uniforms(c, prog_data); v3d_set_prog_data_ubo(c, prog_data); } @@ -652,6 +719,26 @@ uint64_t *v3d_compile_vs(const struct v3d_compiler *compiler, c->vs_key = key; + /* Split our I/O vars and dead code eliminate the unused + * components. + */ + NIR_PASS_V(c->s, nir_lower_io_to_scalar_early, + nir_var_shader_in | nir_var_shader_out); + uint64_t used_outputs[4] = {0}; + for (int i = 0; i < c->vs_key->num_fs_inputs; i++) { + int slot = v3d_slot_get_slot(c->vs_key->fs_inputs[i]); + int comp = v3d_slot_get_component(c->vs_key->fs_inputs[i]); + used_outputs[comp] |= 1ull << slot; + } + NIR_PASS_V(c->s, nir_remove_unused_io_vars, + &c->s->outputs, used_outputs, NULL); /* demotes to globals */ + NIR_PASS_V(c->s, nir_lower_global_vars_to_local); + v3d_optimize_nir(c->s); + NIR_PASS_V(c->s, nir_remove_dead_variables, nir_var_shader_in); + NIR_PASS_V(c->s, nir_lower_io, nir_var_shader_in | nir_var_shader_out, + type_size_vec4, + (nir_lower_io_options)0); + v3d_lower_nir(c); if (key->clamp_color) @@ -685,15 +772,39 @@ uint64_t *v3d_compile_vs(const struct v3d_compiler *compiler, prog_data->vpm_input_size += c->vattr_sizes[i]; } - /* Input/output segment size are in 8x32-bit multiples. */ - prog_data->vpm_input_size = align(prog_data->vpm_input_size, 8) / 8; - prog_data->vpm_output_size = align(c->num_vpm_writes, 8) / 8; - prog_data->uses_vid = (s->info.system_values_read & (1ull << SYSTEM_VALUE_VERTEX_ID)); prog_data->uses_iid = (s->info.system_values_read & (1ull << SYSTEM_VALUE_INSTANCE_ID)); + if (prog_data->uses_vid) + prog_data->vpm_input_size++; + if (prog_data->uses_iid) + prog_data->vpm_input_size++; + + /* Input/output segment size are in sectors (8 rows of 32 bits per + * channel). + */ + prog_data->vpm_input_size = align(prog_data->vpm_input_size, 8) / 8; + prog_data->vpm_output_size = align(c->num_vpm_writes, 8) / 8; + + /* Compute VCM cache size. We set up our program to take up less than + * half of the VPM, so that any set of bin and render programs won't + * run out of space. We need space for at least one input segment, + * and then allocate the rest to output segments (one for the current + * program, the rest to VCM). The valid range of the VCM cache size + * field is 1-4 16-vertex batches, but GFXH-1744 limits us to 2-4 + * batches. + */ + assert(c->devinfo->vpm_size); + int sector_size = 16 * sizeof(uint32_t) * 8; + int vpm_size_in_sectors = c->devinfo->vpm_size / sector_size; + int half_vpm = vpm_size_in_sectors / 2; + int vpm_output_sectors = half_vpm - prog_data->vpm_input_size; + int vpm_output_batches = vpm_output_sectors / prog_data->vpm_output_size; + assert(vpm_output_batches >= 2); + prog_data->vcm_cache_size = CLAMP(vpm_output_batches - 1, 2, 4); + return v3d_return_qpu_insts(c, final_assembly_size); } @@ -705,10 +816,48 @@ v3d_set_fs_prog_data_inputs(struct v3d_compile *c, memcpy(prog_data->input_slots, c->input_slots, c->num_inputs * sizeof(*c->input_slots)); - memcpy(prog_data->flat_shade_flags, c->flat_shade_flags, - sizeof(c->flat_shade_flags)); - memcpy(prog_data->shade_model_flags, c->shade_model_flags, - sizeof(c->shade_model_flags)); + STATIC_ASSERT(ARRAY_SIZE(prog_data->flat_shade_flags) > + (V3D_MAX_FS_INPUTS - 1) / 24); + for (int i = 0; i < V3D_MAX_FS_INPUTS; i++) { + if (BITSET_TEST(c->flat_shade_flags, i)) + prog_data->flat_shade_flags[i / 24] |= 1 << (i % 24); + + if (BITSET_TEST(c->noperspective_flags, i)) + prog_data->noperspective_flags[i / 24] |= 1 << (i % 24); + + if (BITSET_TEST(c->centroid_flags, i)) + prog_data->centroid_flags[i / 24] |= 1 << (i % 24); + } +} + +static void +v3d_fixup_fs_output_types(struct v3d_compile *c) +{ + nir_foreach_variable(var, &c->s->outputs) { + uint32_t mask = 0; + + switch (var->data.location) { + case FRAG_RESULT_COLOR: + mask = ~0; + break; + case FRAG_RESULT_DATA0: + case FRAG_RESULT_DATA1: + case FRAG_RESULT_DATA2: + case FRAG_RESULT_DATA3: + mask = 1 << (var->data.location - FRAG_RESULT_DATA0); + break; + } + + if (c->fs_key->int_color_rb & mask) { + var->type = + glsl_vector_type(GLSL_TYPE_INT, + glsl_get_components(var->type)); + } else if (c->fs_key->uint_color_rb & mask) { + var->type = + glsl_vector_type(GLSL_TYPE_UINT, + glsl_get_components(var->type)); + } + } } uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler, @@ -723,6 +872,9 @@ uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler, c->fs_key = key; + if (key->int_color_rb || key->uint_color_rb) + v3d_fixup_fs_output_types(c); + v3d_lower_nir(c); if (key->light_twoside) @@ -754,7 +906,9 @@ uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler, v3d_set_fs_prog_data_inputs(c, prog_data); prog_data->writes_z = (c->s->info.outputs_written & (1 << FRAG_RESULT_DEPTH)); - prog_data->discard = c->s->info.fs.uses_discard; + prog_data->discard = (c->s->info.fs.uses_discard || + c->fs_key->sample_alpha_to_coverage); + prog_data->uses_center_w = c->uses_center_w; return v3d_return_qpu_insts(c, final_assembly_size); } @@ -765,8 +919,12 @@ vir_remove_instruction(struct v3d_compile *c, struct qinst *qinst) if (qinst->dst.file == QFILE_TEMP) c->defs[qinst->dst.index] = NULL; + assert(&qinst->link != c->cursor.link); + list_del(&qinst->link); free(qinst); + + c->live_intervals_valid = false; } struct qreg @@ -792,6 +950,10 @@ vir_follow_movs(struct v3d_compile *c, struct qreg reg) void vir_compile_destroy(struct v3d_compile *c) { + /* Defuse the assert that we aren't removing the cursor's instruction. + */ + c->cursor.link = NULL; + vir_for_each_block(block, c) { while (!list_empty(&block->instructions)) { struct qinst *qinst = @@ -836,20 +998,40 @@ vir_uniform(struct v3d_compile *c, return vir_reg(QFILE_UNIF, uniform); } +static bool +vir_can_set_flags(struct v3d_compile *c, struct qinst *inst) +{ + if (c->devinfo->ver >= 40 && (v3d_qpu_reads_vpm(&inst->qpu) || + v3d_qpu_uses_sfu(&inst->qpu))) { + return false; + } + + return true; +} + void vir_PF(struct v3d_compile *c, struct qreg src, enum v3d_qpu_pf pf) { struct qinst *last_inst = NULL; - if (!list_empty(&c->cur_block->instructions)) + if (!list_empty(&c->cur_block->instructions)) { last_inst = (struct qinst *)c->cur_block->instructions.prev; + /* Can't stuff the PF into the last last inst if our cursor + * isn't pointing after it. + */ + struct vir_cursor after_inst = vir_after_inst(last_inst); + if (c->cursor.mode != after_inst.mode || + c->cursor.link != after_inst.link) + last_inst = NULL; + } + if (src.file != QFILE_TEMP || !c->defs[src.index] || - last_inst != c->defs[src.index]) { + last_inst != c->defs[src.index] || + !vir_can_set_flags(c, last_inst)) { /* XXX: Make the MOV be the appropriate type */ last_inst = vir_MOV_dest(c, vir_reg(QFILE_NULL, 0), src); - last_inst = (struct qinst *)c->cur_block->instructions.prev; } vir_set_pf(last_inst, pf); @@ -880,6 +1062,7 @@ vir_optimize(struct v3d_compile *c) OPTPASS(vir_opt_copy_propagate); OPTPASS(vir_opt_dead_code); + OPTPASS(vir_opt_small_immediates); if (!progress) break; diff --git a/lib/mesa/src/broadcom/compiler/vir_dump.c b/lib/mesa/src/broadcom/compiler/vir_dump.c index ad5c061a1..c43578302 100644 --- a/lib/mesa/src/broadcom/compiler/vir_dump.c +++ b/lib/mesa/src/broadcom/compiler/vir_dump.c @@ -21,14 +21,15 @@ * IN THE SOFTWARE. */ +#include "broadcom/common/v3d_device_info.h" #include "v3d_compiler.h" static void -vir_print_reg(struct v3d_compile *c, struct qreg reg) +vir_print_reg(struct v3d_compile *c, const struct qinst *inst, + struct qreg reg) { static const char *files[] = { [QFILE_TEMP] = "t", - [QFILE_VARY] = "v", [QFILE_UNIF] = "u", [QFILE_TLB] = "tlb", [QFILE_TLBU] = "tlbu", @@ -58,12 +59,20 @@ vir_print_reg(struct v3d_compile *c, struct qreg reg) fprintf(stderr, "%s", v3d_qpu_magic_waddr_name(reg.index)); break; - case QFILE_SMALL_IMM: - if ((int)reg.index >= -16 && (int)reg.index <= 15) - fprintf(stderr, "%d", reg.index); + case QFILE_SMALL_IMM: { + uint32_t unpacked; + bool ok = v3d_qpu_small_imm_unpack(c->devinfo, + inst->qpu.raddr_b, + &unpacked); + assert(ok); (void) ok; + + if ((int)inst->qpu.raddr_b >= -16 && + (int)inst->qpu.raddr_b <= 15) + fprintf(stderr, "%d", unpacked); else - fprintf(stderr, "%f", uif(reg.index)); + fprintf(stderr, "%f", uif(unpacked)); break; + } case QFILE_VPM: fprintf(stderr, "vpm%d.%d", @@ -71,6 +80,7 @@ vir_print_reg(struct v3d_compile *c, struct qreg reg) break; case QFILE_TLB: + case QFILE_TLBU: fprintf(stderr, "%s", files[reg.file]); break; @@ -146,20 +156,60 @@ vir_print_reg(struct v3d_compile *c, struct qreg reg) } static void +vir_dump_sig_addr(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *instr) +{ + if (devinfo->ver < 41) + return; + + if (!instr->sig_magic) + fprintf(stderr, ".rf%d", instr->sig_addr); + else { + const char *name = v3d_qpu_magic_waddr_name(instr->sig_addr); + if (name) + fprintf(stderr, ".%s", name); + else + fprintf(stderr, ".UNKNOWN%d", instr->sig_addr); + } +} + +static void vir_dump_sig(struct v3d_compile *c, struct qinst *inst) { struct v3d_qpu_sig *sig = &inst->qpu.sig; if (sig->thrsw) fprintf(stderr, "; thrsw"); - if (sig->ldvary) + if (sig->ldvary) { fprintf(stderr, "; ldvary"); + vir_dump_sig_addr(c->devinfo, &inst->qpu); + } if (sig->ldvpm) fprintf(stderr, "; ldvpm"); - if (sig->ldtmu) + if (sig->ldtmu) { fprintf(stderr, "; ldtmu"); + vir_dump_sig_addr(c->devinfo, &inst->qpu); + } + if (sig->ldtlb) { + fprintf(stderr, "; ldtlb"); + vir_dump_sig_addr(c->devinfo, &inst->qpu); + } + if (sig->ldtlbu) { + fprintf(stderr, "; ldtlbu"); + vir_dump_sig_addr(c->devinfo, &inst->qpu); + } if (sig->ldunif) fprintf(stderr, "; ldunif"); + if (sig->ldunifrf) { + fprintf(stderr, "; ldunifrf"); + vir_dump_sig_addr(c->devinfo, &inst->qpu); + } + if (sig->ldunifa) + fprintf(stderr, "; ldunifa"); + if (sig->ldunifarf) { + fprintf(stderr, "; ldunifarf"); + vir_dump_sig_addr(c->devinfo, &inst->qpu); + } if (sig->wrtmuc) fprintf(stderr, "; wrtmuc"); } @@ -179,7 +229,7 @@ vir_dump_alu(struct v3d_compile *c, struct qinst *inst) fprintf(stderr, "%s", v3d_qpu_uf_name(instr->flags.auf)); fprintf(stderr, " "); - vir_print_reg(c, inst->dst); + vir_print_reg(c, inst, inst->dst); fprintf(stderr, "%s", v3d_qpu_pack_name(instr->alu.add.output_pack)); unpack[0] = instr->alu.add.a_unpack; @@ -191,7 +241,7 @@ vir_dump_alu(struct v3d_compile *c, struct qinst *inst) fprintf(stderr, "%s", v3d_qpu_uf_name(instr->flags.muf)); fprintf(stderr, " "); - vir_print_reg(c, inst->dst); + vir_print_reg(c, inst, inst->dst); fprintf(stderr, "%s", v3d_qpu_pack_name(instr->alu.mul.output_pack)); unpack[0] = instr->alu.mul.a_unpack; @@ -200,7 +250,7 @@ vir_dump_alu(struct v3d_compile *c, struct qinst *inst) for (int i = 0; i < sideband_nsrc; i++) { fprintf(stderr, ", "); - vir_print_reg(c, inst->src[i]); + vir_print_reg(c, inst, inst->src[i]); if (i < nsrc) fprintf(stderr, "%s", v3d_qpu_unpack_name(unpack[i])); } @@ -266,7 +316,7 @@ vir_dump_inst(struct v3d_compile *c, struct qinst *inst) if (vir_has_implicit_uniform(inst)) { fprintf(stderr, " "); - vir_print_reg(c, inst->src[vir_get_implicit_uniform_src(inst)]); + vir_print_reg(c, inst, inst->src[vir_get_implicit_uniform_src(inst)]); } break; @@ -281,7 +331,7 @@ vir_dump(struct v3d_compile *c) vir_for_each_block(block, c) { fprintf(stderr, "BLOCK %d:\n", block->index); vir_for_each_inst(inst, block) { - if (c->temp_start) { + if (c->live_intervals_valid) { bool first = true; for (int i = 0; i < c->num_temps; i++) { @@ -302,7 +352,7 @@ vir_dump(struct v3d_compile *c) fprintf(stderr, " "); } - if (c->temp_end) { + if (c->live_intervals_valid) { bool first = true; for (int i = 0; i < c->num_temps; i++) { diff --git a/lib/mesa/src/broadcom/compiler/vir_live_variables.c b/lib/mesa/src/broadcom/compiler/vir_live_variables.c index 217b716fd..2879e23b4 100644 --- a/lib/mesa/src/broadcom/compiler/vir_live_variables.c +++ b/lib/mesa/src/broadcom/compiler/vir_live_variables.c @@ -180,8 +180,6 @@ vir_setup_def(struct v3d_compile *c, struct qblock *block, int ip, static void sf_state_clear(struct hash_table *partial_update_ht) { - struct hash_entry *entry; - hash_table_foreach(partial_update_ht, entry) { struct partial_update_state *state = entry->data; @@ -311,10 +309,20 @@ vir_calculate_live_intervals(struct v3d_compile *c) { int bitset_words = BITSET_WORDS(c->num_temps); - /* If we called this function more than once, then we should be - * freeing the previous arrays. + /* We may be called more than once if we've rearranged the program to + * try to get register allocation to succeed. */ - assert(!c->temp_start); + if (c->temp_start) { + ralloc_free(c->temp_start); + ralloc_free(c->temp_end); + + vir_for_each_block(block, c) { + ralloc_free(block->def); + ralloc_free(block->use); + ralloc_free(block->live_in); + ralloc_free(block->live_out); + } + } c->temp_start = rzalloc_array(c, int, c->num_temps); c->temp_end = rzalloc_array(c, int, c->num_temps); @@ -337,4 +345,6 @@ vir_calculate_live_intervals(struct v3d_compile *c) ; vir_compute_start_end(c, c->num_temps); + + c->live_intervals_valid = true; } diff --git a/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c b/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c index 7f3bb8460..570e601a6 100644 --- a/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c +++ b/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c @@ -76,9 +76,7 @@ is_lowerable_uniform(struct qinst *inst, int i) { if (inst->src[i].file != QFILE_UNIF) return false; - if (vir_has_implicit_uniform(inst)) - return i != vir_get_implicit_uniform_src(inst); - return true; + return i != vir_get_implicit_uniform_src(inst); } /* Returns the number of different uniform values referenced by the @@ -136,7 +134,6 @@ vir_lower_uniforms(struct v3d_compile *c) */ uint32_t max_count = 0; uint32_t max_index = 0; - struct hash_entry *entry; hash_table_foreach(ht, entry) { uint32_t count = (uintptr_t)entry->data; uint32_t index = (uintptr_t)entry->key - 1; @@ -152,7 +149,7 @@ vir_lower_uniforms(struct v3d_compile *c) * reference a temp instead. */ vir_for_each_block(block, c) { - struct qinst *mov = NULL; + struct qreg temp = c->undef; vir_for_each_inst(inst, block) { uint32_t nsrc = vir_get_nsrc(inst); @@ -162,29 +159,27 @@ vir_lower_uniforms(struct v3d_compile *c) if (count <= 1) continue; - /* If the block doesn't have a load of the - * uniform yet, add it. We could potentially - * do better and CSE MOVs from multiple blocks - * into dominating blocks, except that may - * cause troubles for register allocation. - */ - if (!mov) { - mov = vir_mul_inst(V3D_QPU_M_MOV, - vir_get_temp(c), - unif, c->undef); - list_add(&mov->link, - &block->instructions); - c->defs[mov->dst.index] = mov; - } - bool removed = false; for (int i = 0; i < nsrc; i++) { if (is_lowerable_uniform(inst, i) && inst->src[i].index == max_index) { - inst->src[i].file = - mov->dst.file; - inst->src[i].index = - mov->dst.index; + /* If the block doesn't have a + * load of the uniform yet, + * add it now. We could + * potentially do better and + * CSE MOVs from multiple + * blocks into dominating + * blocks, except that may + * cause troubles for register + * allocation. + */ + if (temp.file == QFILE_NULL) { + c->cursor = + vir_before_inst(inst); + temp = vir_MOV(c, unif); + } + + inst->src[i] = temp; remove_uniform(ht, unif); removed = true; } diff --git a/lib/mesa/src/broadcom/compiler/vir_opt_dead_code.c b/lib/mesa/src/broadcom/compiler/vir_opt_dead_code.c index 9e0ef20b6..362fc9e52 100644 --- a/lib/mesa/src/broadcom/compiler/vir_opt_dead_code.c +++ b/lib/mesa/src/broadcom/compiler/vir_opt_dead_code.c @@ -49,6 +49,8 @@ dce(struct v3d_compile *c, struct qinst *inst) } assert(inst->qpu.flags.apf == V3D_QPU_PF_NONE); assert(inst->qpu.flags.mpf == V3D_QPU_PF_NONE); + assert(inst->qpu.flags.auf == V3D_QPU_UF_NONE); + assert(inst->qpu.flags.muf == V3D_QPU_UF_NONE); vir_remove_instruction(c, inst); } @@ -78,17 +80,21 @@ has_nonremovable_reads(struct v3d_compile *c, struct qinst *inst) if (total_size == 1) return true; } - - /* Dead code removal of varyings is tricky, so just assert - * that it all happened at the NIR level. - */ - if (inst->src[i].file == QFILE_VARY) - return true; } return false; } +static bool +can_write_to_null(struct v3d_compile *c, struct qinst *inst) +{ + /* The SFU instructions must write to a physical register. */ + if (c->devinfo->ver >= 41 && v3d_qpu_uses_sfu(&inst->qpu)) + return false; + + return true; +} + bool vir_opt_dead_code(struct v3d_compile *c) { @@ -114,7 +120,9 @@ vir_opt_dead_code(struct v3d_compile *c) continue; if (inst->qpu.flags.apf != V3D_QPU_PF_NONE || - inst->qpu.flags.mpf != V3D_QPU_PF_NONE|| + inst->qpu.flags.mpf != V3D_QPU_PF_NONE || + inst->qpu.flags.auf != V3D_QPU_UF_NONE || + inst->qpu.flags.muf != V3D_QPU_UF_NONE || has_nonremovable_reads(c, inst)) { /* If we can't remove the instruction, but we * don't need its destination value, just @@ -124,7 +132,8 @@ vir_opt_dead_code(struct v3d_compile *c) * it's nicer to read the VIR code without * unused destination regs. */ - if (inst->dst.file == QFILE_TEMP) { + if (inst->dst.file == QFILE_TEMP && + can_write_to_null(c, inst)) { if (debug) { fprintf(stderr, "Removing dst from: "); diff --git a/lib/mesa/src/broadcom/compiler/vir_opt_small_immediates.c b/lib/mesa/src/broadcom/compiler/vir_opt_small_immediates.c new file mode 100644 index 000000000..5491f9c24 --- /dev/null +++ b/lib/mesa/src/broadcom/compiler/vir_opt_small_immediates.c @@ -0,0 +1,112 @@ +/* + * Copyright © 2014 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * @file v3d_opt_small_immediates.c + * + * Turns references to small constant uniform values into small immediates + * fields. + */ + +#include "v3d_compiler.h" + +static bool debug; + +bool +vir_opt_small_immediates(struct v3d_compile *c) +{ + bool progress = false; + + vir_for_each_inst_inorder(inst, c) { + if (inst->qpu.type != V3D_QPU_INSTR_TYPE_ALU) + continue; + + /* The small immediate value sits in the raddr B field, so we + * can't have 2 small immediates in one instruction (unless + * they're the same value, but that should be optimized away + * elsewhere). + */ + bool uses_small_imm = false; + for (int i = 0; i < vir_get_nsrc(inst); i++) { + if (inst->src[i].file == QFILE_SMALL_IMM) + uses_small_imm = true; + } + if (uses_small_imm) + continue; + + for (int i = 0; i < vir_get_nsrc(inst); i++) { + struct qreg src = vir_follow_movs(c, inst->src[i]); + + if (src.file != QFILE_UNIF || + c->uniform_contents[src.index] != + QUNIFORM_CONSTANT) { + continue; + } + + if (vir_has_implicit_uniform(inst) && + i == vir_get_implicit_uniform_src(inst)) { + /* No turning the implicit uniform read into + * an immediate. + */ + continue; + } + + /* Check if the uniform is suitable as a small + * immediate. + */ + uint32_t imm = c->uniform_data[src.index]; + uint32_t packed; + if (!v3d_qpu_small_imm_pack(c->devinfo, imm, &packed)) + continue; + + /* Check that we don't have any other signals already + * that would be incompatible with small_imm. + */ + struct v3d_qpu_sig new_sig = inst->qpu.sig; + uint32_t sig_packed; + new_sig.small_imm = true; + if (!v3d_qpu_sig_pack(c->devinfo, &new_sig, &sig_packed)) + continue; + + if (debug) { + fprintf(stderr, "opt_small_immediate() from: "); + vir_dump_inst(c, inst); + fprintf(stderr, "\n"); + } + inst->qpu.sig.small_imm = true; + inst->qpu.raddr_b = packed; + + inst->src[i].file = QFILE_SMALL_IMM; + inst->src[i].index = imm; + if (debug) { + fprintf(stderr, "to: "); + vir_dump_inst(c, inst); + fprintf(stderr, "\n"); + } + progress = true; + break; + } + } + + return progress; +} diff --git a/lib/mesa/src/broadcom/compiler/vir_register_allocate.c b/lib/mesa/src/broadcom/compiler/vir_register_allocate.c index 9ebf2cd69..accc07a3a 100644 --- a/lib/mesa/src/broadcom/compiler/vir_register_allocate.c +++ b/lib/mesa/src/broadcom/compiler/vir_register_allocate.c @@ -23,6 +23,7 @@ #include "util/ralloc.h" #include "util/register_allocate.h" +#include "common/v3d_device_info.h" #include "v3d_compiler.h" #define QPU_R(i) { .magic = false, .index = i } @@ -32,30 +33,292 @@ #define PHYS_INDEX (ACC_INDEX + ACC_COUNT) #define PHYS_COUNT 64 +static bool +is_last_ldtmu(struct qinst *inst, struct qblock *block) +{ + list_for_each_entry_from(struct qinst, scan_inst, inst, + &block->instructions, link) { + if (inst->qpu.sig.ldtmu) + return false; + if (v3d_qpu_writes_tmu(&inst->qpu)) + return true; + } + + return true; +} + +static int +v3d_choose_spill_node(struct v3d_compile *c, struct ra_graph *g, + uint32_t *temp_to_node) +{ + float block_scale = 1.0; + float spill_costs[c->num_temps]; + bool in_tmu_operation = false; + bool started_last_seg = false; + + for (unsigned i = 0; i < c->num_temps; i++) + spill_costs[i] = 0.0; + + /* XXX: Scale the cost up when inside of a loop. */ + vir_for_each_block(block, c) { + vir_for_each_inst(inst, block) { + /* We can't insert a new TMU operation while currently + * in a TMU operation, and we can't insert new thread + * switches after starting output writes. + */ + bool no_spilling = + (in_tmu_operation || + (c->threads > 1 && started_last_seg)); + + for (int i = 0; i < vir_get_nsrc(inst); i++) { + if (inst->src[i].file != QFILE_TEMP) + continue; + + int temp = inst->src[i].index; + if (no_spilling) { + BITSET_CLEAR(c->spillable, + temp); + } else { + spill_costs[temp] += block_scale; + } + } + + if (inst->dst.file == QFILE_TEMP) { + int temp = inst->dst.index; + + if (no_spilling) { + BITSET_CLEAR(c->spillable, + temp); + } else { + spill_costs[temp] += block_scale; + } + } + + /* Refuse to spill a ldvary's dst, because that means + * that ldvary's r5 would end up being used across a + * thrsw. + */ + if (inst->qpu.sig.ldvary) { + assert(inst->dst.file == QFILE_TEMP); + BITSET_CLEAR(c->spillable, inst->dst.index); + } + + if (inst->is_last_thrsw) + started_last_seg = true; + + if (v3d_qpu_writes_vpm(&inst->qpu) || + v3d_qpu_uses_tlb(&inst->qpu)) + started_last_seg = true; + + /* Track when we're in between a TMU setup and the + * final LDTMU or TMUWT from that TMU setup. We can't + * spill/fill any temps during that time, because that + * involves inserting a new TMU setup/LDTMU sequence. + */ + if (inst->qpu.sig.ldtmu && + is_last_ldtmu(inst, block)) + in_tmu_operation = false; + + if (inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU && + inst->qpu.alu.add.op == V3D_QPU_A_TMUWT) + in_tmu_operation = false; + + if (v3d_qpu_writes_tmu(&inst->qpu)) + in_tmu_operation = true; + } + } + + for (unsigned i = 0; i < c->num_temps; i++) { + int node = temp_to_node[i]; + + if (BITSET_TEST(c->spillable, i)) + ra_set_node_spill_cost(g, node, spill_costs[i]); + } + + return ra_get_best_spill_node(g); +} + +/* The spill offset for this thread takes a bit of setup, so do it once at + * program start. + */ +static void +v3d_setup_spill_base(struct v3d_compile *c) +{ + c->cursor = vir_before_block(vir_entry_block(c)); + + int start_num_temps = c->num_temps; + + /* Each thread wants to be in a separate region of the scratch space + * so that the QPUs aren't fighting over cache lines. We have the + * driver keep a single global spill BO rather than + * per-spilling-program BOs, so we need a uniform from the driver for + * what the per-thread scale is. + */ + struct qreg thread_offset = + vir_UMUL(c, + vir_TIDX(c), + vir_uniform(c, QUNIFORM_SPILL_SIZE_PER_THREAD, 0)); + + /* Each channel in a reg is 4 bytes, so scale them up by that. */ + struct qreg element_offset = vir_SHL(c, vir_EIDX(c), + vir_uniform_ui(c, 2)); + + c->spill_base = vir_ADD(c, + vir_ADD(c, thread_offset, element_offset), + vir_uniform(c, QUNIFORM_SPILL_OFFSET, 0)); + + /* Make sure that we don't spill the spilling setup instructions. */ + for (int i = start_num_temps; i < c->num_temps; i++) + BITSET_CLEAR(c->spillable, i); +} + +static void +v3d_emit_spill_tmua(struct v3d_compile *c, uint32_t spill_offset) +{ + vir_ADD_dest(c, vir_reg(QFILE_MAGIC, + V3D_QPU_WADDR_TMUA), + c->spill_base, + vir_uniform_ui(c, spill_offset)); +} + +static void +v3d_spill_reg(struct v3d_compile *c, int spill_temp) +{ + uint32_t spill_offset = c->spill_size; + c->spill_size += 16 * sizeof(uint32_t); + + if (spill_offset == 0) + v3d_setup_spill_base(c); + + struct qinst *last_thrsw = c->last_thrsw; + assert(!last_thrsw || last_thrsw->is_last_thrsw); + + int start_num_temps = c->num_temps; + + vir_for_each_inst_inorder(inst, c) { + for (int i = 0; i < vir_get_nsrc(inst); i++) { + if (inst->src[i].file != QFILE_TEMP || + inst->src[i].index != spill_temp) { + continue; + } + + c->cursor = vir_before_inst(inst); + + v3d_emit_spill_tmua(c, spill_offset); + vir_emit_thrsw(c); + inst->src[i] = vir_LDTMU(c); + c->fills++; + } + + if (inst->dst.file == QFILE_TEMP && + inst->dst.index == spill_temp) { + c->cursor = vir_after_inst(inst); + + inst->dst.index = c->num_temps++; + vir_MOV_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMUD), + inst->dst); + v3d_emit_spill_tmua(c, spill_offset); + vir_emit_thrsw(c); + vir_TMUWT(c); + c->spills++; + } + + /* If we didn't have a last-thrsw inserted by nir_to_vir and + * we've been inserting thrsws, then insert a new last_thrsw + * right before we start the vpm/tlb sequence for the last + * thread segment. + */ + if (!last_thrsw && c->last_thrsw && + (v3d_qpu_writes_vpm(&inst->qpu) || + v3d_qpu_uses_tlb(&inst->qpu))) { + c->cursor = vir_before_inst(inst); + vir_emit_thrsw(c); + + last_thrsw = c->last_thrsw; + last_thrsw->is_last_thrsw = true; + } + } + + /* Make sure c->last_thrsw is the actual last thrsw, not just one we + * inserted in our most recent unspill. + */ + if (last_thrsw) + c->last_thrsw = last_thrsw; + + /* Don't allow spilling of our spilling instructions. There's no way + * they can help get things colored. + */ + for (int i = start_num_temps; i < c->num_temps; i++) + BITSET_CLEAR(c->spillable, i); +} + +struct v3d_ra_select_callback_data { + uint32_t next_acc; + uint32_t next_phys; +}; + +static unsigned int +v3d_ra_select_callback(struct ra_graph *g, BITSET_WORD *regs, void *data) +{ + struct v3d_ra_select_callback_data *v3d_ra = data; + + /* Choose an accumulator if possible (I think it's lower power than + * phys regs), but round-robin through them to give post-RA + * instruction selection more options. + */ + for (int i = 0; i < ACC_COUNT; i++) { + int acc_off = (v3d_ra->next_acc + i) % ACC_COUNT; + int acc = ACC_INDEX + acc_off; + + if (BITSET_TEST(regs, acc)) { + v3d_ra->next_acc = acc_off + 1; + return acc; + } + } + + for (int i = 0; i < PHYS_COUNT; i++) { + int phys_off = (v3d_ra->next_phys + i) % PHYS_COUNT; + int phys = PHYS_INDEX + phys_off; + + if (BITSET_TEST(regs, phys)) { + v3d_ra->next_phys = phys_off + 1; + return phys; + } + } + + unreachable("RA must pass us at least one possible reg."); +} + bool vir_init_reg_sets(struct v3d_compiler *compiler) { + /* Allocate up to 3 regfile classes, for the ways the physical + * register file can be divided up for fragment shader threading. + */ + int max_thread_index = (compiler->devinfo->ver >= 40 ? 2 : 3); + compiler->regs = ra_alloc_reg_set(compiler, PHYS_INDEX + PHYS_COUNT, true); if (!compiler->regs) return false; - /* Allocate 3 regfile classes, for the ways the physical register file - * can be divided up for fragment shader threading. - */ - for (int threads = 0; threads < 3; threads++) { - compiler->reg_class[threads] = + for (int threads = 0; threads < max_thread_index; threads++) { + compiler->reg_class_phys_or_acc[threads] = + ra_alloc_reg_class(compiler->regs); + compiler->reg_class_phys[threads] = ra_alloc_reg_class(compiler->regs); for (int i = PHYS_INDEX; i < PHYS_INDEX + (PHYS_COUNT >> threads); i++) { ra_class_add_reg(compiler->regs, - compiler->reg_class[threads], i); + compiler->reg_class_phys_or_acc[threads], i); + ra_class_add_reg(compiler->regs, + compiler->reg_class_phys[threads], i); } for (int i = ACC_INDEX + 0; i < ACC_INDEX + ACC_COUNT; i++) { ra_class_add_reg(compiler->regs, - compiler->reg_class[threads], i); + compiler->reg_class_phys_or_acc[threads], i); } } @@ -89,7 +352,7 @@ node_to_temp_priority(const void *in_a, const void *in_b) * The return value should be freed by the caller. */ struct qpu_reg * -v3d_register_allocate(struct v3d_compile *c) +v3d_register_allocate(struct v3d_compile *c, bool *spilled) { struct node_to_temp_map map[c->num_temps]; uint32_t temp_to_node[c->num_temps]; @@ -97,10 +360,33 @@ v3d_register_allocate(struct v3d_compile *c) struct qpu_reg *temp_registers = calloc(c->num_temps, sizeof(*temp_registers)); int acc_nodes[ACC_COUNT]; + struct v3d_ra_select_callback_data callback_data = { + .next_acc = 0, + /* Start at RF3, to try to keep the TLB writes from using + * RF0-2. + */ + .next_phys = 3, + }; + + *spilled = false; + + vir_calculate_live_intervals(c); + + /* Convert 1, 2, 4 threads to 0, 1, 2 index. + * + * V3D 4.x has double the physical register space, so 64 physical regs + * are available at both 1x and 2x threading, and 4x has 32. + */ + int thread_index = ffs(c->threads) - 1; + if (c->devinfo->ver >= 40) { + if (thread_index >= 1) + thread_index--; + } struct ra_graph *g = ra_alloc_interference_graph(c->compiler->regs, c->num_temps + ARRAY_SIZE(acc_nodes)); + ra_set_select_reg_callback(g, v3d_ra_select_callback, &callback_data); /* Make some fixed nodes for the accumulators, which we will need to * interfere with when ops have implied r3/r4 writes or for the thread @@ -113,9 +399,6 @@ v3d_register_allocate(struct v3d_compile *c) ra_set_node_reg(g, acc_nodes[i], ACC_INDEX + i); } - /* Compute the live ranges so we can figure out interference. */ - vir_calculate_live_intervals(c); - for (uint32_t i = 0; i < c->num_temps; i++) { map[i].temp = i; map[i].priority = c->temp_end[i] - c->temp_start[i]; @@ -139,7 +422,7 @@ v3d_register_allocate(struct v3d_compile *c) * result to a temp), nothing else can be stored in r3/r4 across * it. */ - if (vir_writes_r3(inst)) { + if (vir_writes_r3(c->devinfo, inst)) { for (int i = 0; i < c->num_temps; i++) { if (c->temp_start[i] < ip && c->temp_end[i] > ip) { @@ -149,7 +432,7 @@ v3d_register_allocate(struct v3d_compile *c) } } } - if (vir_writes_r4(inst)) { + if (vir_writes_r4(c->devinfo, inst)) { for (int i = 0; i < c->num_temps; i++) { if (c->temp_start[i] < ip && c->temp_end[i] > ip) { @@ -160,6 +443,40 @@ v3d_register_allocate(struct v3d_compile *c) } } + if (inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU) { + switch (inst->qpu.alu.add.op) { + case V3D_QPU_A_LDVPMV_IN: + case V3D_QPU_A_LDVPMV_OUT: + case V3D_QPU_A_LDVPMD_IN: + case V3D_QPU_A_LDVPMD_OUT: + case V3D_QPU_A_LDVPMP: + case V3D_QPU_A_LDVPMG_IN: + case V3D_QPU_A_LDVPMG_OUT: + /* LDVPMs only store to temps (the MA flag + * decides whether the LDVPM is in or out) + */ + assert(inst->dst.file == QFILE_TEMP); + class_bits[inst->dst.index] &= CLASS_BIT_PHYS; + break; + + case V3D_QPU_A_RECIP: + case V3D_QPU_A_RSQRT: + case V3D_QPU_A_EXP: + case V3D_QPU_A_LOG: + case V3D_QPU_A_SIN: + case V3D_QPU_A_RSQRT2: + /* The SFU instructions write directly to the + * phys regfile. + */ + assert(inst->dst.file == QFILE_TEMP); + class_bits[inst->dst.index] &= CLASS_BIT_PHYS; + break; + + default: + break; + } + } + if (inst->src[0].file == QFILE_REG) { switch (inst->src[0].index) { case 0: @@ -179,30 +496,31 @@ v3d_register_allocate(struct v3d_compile *c) } } -#if 0 - switch (inst->op) { - case QOP_THRSW: + if (inst->qpu.sig.thrsw) { /* All accumulators are invalidated across a thread * switch. */ for (int i = 0; i < c->num_temps; i++) { if (c->temp_start[i] < ip && c->temp_end[i] > ip) - class_bits[i] &= ~(CLASS_BIT_R0_R3 | - CLASS_BIT_R4); + class_bits[i] &= CLASS_BIT_PHYS; } - break; - - default: - break; } -#endif ip++; } for (uint32_t i = 0; i < c->num_temps; i++) { - ra_set_node_class(g, temp_to_node[i], - c->compiler->reg_class[c->fs_threaded]); + if (class_bits[i] == CLASS_BIT_PHYS) { + ra_set_node_class(g, temp_to_node[i], + c->compiler->reg_class_phys[thread_index]); + } else { + assert(class_bits[i] == (CLASS_BIT_PHYS | + CLASS_BIT_R0_R2 | + CLASS_BIT_R3 | + CLASS_BIT_R4)); + ra_set_node_class(g, temp_to_node[i], + c->compiler->reg_class_phys_or_acc[thread_index]); + } } for (uint32_t i = 0; i < c->num_temps; i++) { @@ -216,14 +534,36 @@ v3d_register_allocate(struct v3d_compile *c) } } + /* Debug code to force a bit of register spilling, for running across + * conformance tests to make sure that spilling works. + */ + int force_register_spills = 0; + if (c->spill_size < 16 * sizeof(uint32_t) * force_register_spills) { + int node = v3d_choose_spill_node(c, g, temp_to_node); + if (node != -1) { + v3d_spill_reg(c, map[node].temp); + ralloc_free(g); + *spilled = true; + return NULL; + } + } + bool ok = ra_allocate(g); if (!ok) { - if (!c->fs_threaded) { - fprintf(stderr, "Failed to register allocate:\n"); - vir_dump(c); + /* Try to spill, if we can't reduce threading first. */ + if (thread_index == 0) { + int node = v3d_choose_spill_node(c, g, temp_to_node); + + if (node != -1) { + v3d_spill_reg(c, map[node].temp); + ralloc_free(g); + + /* Ask the outer loop to call back in. */ + *spilled = true; + return NULL; + } } - c->failed = true; free(temp_registers); return NULL; } @@ -250,5 +590,17 @@ v3d_register_allocate(struct v3d_compile *c) ralloc_free(g); + if (V3D_DEBUG & V3D_DEBUG_SHADERDB) { + fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d spills\n", + vir_get_stage_name(c), + c->program_id, c->variant_id, + c->spills); + + fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d fills\n", + vir_get_stage_name(c), + c->program_id, c->variant_id, + c->fills); + } + return temp_registers; } diff --git a/lib/mesa/src/broadcom/compiler/vir_to_qpu.c b/lib/mesa/src/broadcom/compiler/vir_to_qpu.c index eeb7b0bc2..4baadce29 100644 --- a/lib/mesa/src/broadcom/compiler/vir_to_qpu.c +++ b/lib/mesa/src/broadcom/compiler/vir_to_qpu.c @@ -109,6 +109,12 @@ new_ldunif_instr(struct qinst *inst, int i) static void set_src(struct v3d_qpu_instr *instr, enum v3d_qpu_mux *mux, struct qpu_reg src) { + if (src.smimm) { + assert(instr->sig.small_imm); + *mux = V3D_QPU_MUX_B; + return; + } + if (src.magic) { assert(src.index >= V3D_QPU_WADDR_R0 && src.index <= V3D_QPU_WADDR_R5); @@ -138,6 +144,60 @@ set_src(struct v3d_qpu_instr *instr, enum v3d_qpu_mux *mux, struct qpu_reg src) } } +static bool +is_no_op_mov(struct qinst *qinst) +{ + static const struct v3d_qpu_sig no_sig = {0}; + + /* Make sure it's just a lone MOV. */ + if (qinst->qpu.type != V3D_QPU_INSTR_TYPE_ALU || + qinst->qpu.alu.mul.op != V3D_QPU_M_MOV || + qinst->qpu.alu.add.op != V3D_QPU_A_NOP || + memcmp(&qinst->qpu.sig, &no_sig, sizeof(no_sig)) != 0) { + return false; + } + + /* Check if it's a MOV from a register to itself. */ + enum v3d_qpu_waddr waddr = qinst->qpu.alu.mul.waddr; + if (qinst->qpu.alu.mul.magic_write) { + if (waddr < V3D_QPU_WADDR_R0 || waddr > V3D_QPU_WADDR_R4) + return false; + + if (qinst->qpu.alu.mul.a != + V3D_QPU_MUX_R0 + (waddr - V3D_QPU_WADDR_R0)) { + return false; + } + } else { + int raddr; + + switch (qinst->qpu.alu.mul.a) { + case V3D_QPU_MUX_A: + raddr = qinst->qpu.raddr_a; + break; + case V3D_QPU_MUX_B: + raddr = qinst->qpu.raddr_b; + break; + default: + return false; + } + if (raddr != waddr) + return false; + } + + /* No packing or flags updates, or we need to execute the + * instruction. + */ + if (qinst->qpu.alu.mul.a_unpack != V3D_QPU_UNPACK_NONE || + qinst->qpu.alu.mul.output_pack != V3D_QPU_PACK_NONE || + qinst->qpu.flags.mc != V3D_QPU_COND_NONE || + qinst->qpu.flags.mpf != V3D_QPU_PF_NONE || + qinst->qpu.flags.muf != V3D_QPU_UF_NONE) { + return false; + } + + return true; +} + static void v3d_generate_code_block(struct v3d_compile *c, struct qblock *block, @@ -145,7 +205,7 @@ v3d_generate_code_block(struct v3d_compile *c, { int last_vpm_read_index = -1; - vir_for_each_inst(qinst, block) { + vir_for_each_inst_safe(qinst, block) { #if 0 fprintf(stderr, "translating qinst to qpu: "); vir_dump_inst(c, qinst); @@ -189,22 +249,8 @@ v3d_generate_code_block(struct v3d_compile *c, src[i] = qpu_acc(5); break; - case QFILE_VARY: - temp = new_qpu_nop_before(qinst); - temp->qpu.sig.ldvary = true; - - src[i] = qpu_acc(3); - break; case QFILE_SMALL_IMM: - abort(); /* XXX */ -#if 0 - src[i].mux = QPU_MUX_SMALL_IMM; - src[i].addr = qpu_encode_small_immediate(qinst->src[i].index); - /* This should only have returned a valid - * small immediate field, not ~0 for failure. - */ - assert(src[i].addr <= 47); -#endif + src[i].smimm = true; break; case QFILE_VPM: @@ -255,7 +301,6 @@ v3d_generate_code_block(struct v3d_compile *c, dst = qpu_magic(V3D_QPU_WADDR_TLBU); break; - case QFILE_VARY: case QFILE_UNIF: case QFILE_SMALL_IMM: case QFILE_LOAD_IMM: @@ -264,7 +309,14 @@ v3d_generate_code_block(struct v3d_compile *c, } if (qinst->qpu.type == V3D_QPU_INSTR_TYPE_ALU) { - if (qinst->qpu.alu.add.op != V3D_QPU_A_NOP) { + if (v3d_qpu_sig_writes_address(c->devinfo, + &qinst->qpu.sig)) { + assert(qinst->qpu.alu.add.op == V3D_QPU_A_NOP); + assert(qinst->qpu.alu.mul.op == V3D_QPU_M_NOP); + + qinst->qpu.sig_addr = dst.index; + qinst->qpu.sig_magic = dst.magic; + } else if (qinst->qpu.alu.add.op != V3D_QPU_A_NOP) { assert(qinst->qpu.alu.mul.op == V3D_QPU_M_NOP); if (nsrc >= 1) { set_src(&qinst->qpu, @@ -289,6 +341,11 @@ v3d_generate_code_block(struct v3d_compile *c, qinst->qpu.alu.mul.waddr = dst.index; qinst->qpu.alu.mul.magic_write = dst.magic; + + if (is_no_op_mov(qinst)) { + vir_remove_instruction(c, qinst); + continue; + } } } else { assert(qinst->qpu.type == V3D_QPU_INSTR_TYPE_BRANCH); @@ -307,17 +364,14 @@ v3d_dump_qpu(struct v3d_compile *c) for (int i = 0; i < c->qpu_inst_count; i++) { const char *str = v3d_qpu_disasm(c->devinfo, c->qpu_insts[i]); fprintf(stderr, "0x%016"PRIx64" %s\n", c->qpu_insts[i], str); + ralloc_free((void *)str); } fprintf(stderr, "\n"); } void -v3d_vir_to_qpu(struct v3d_compile *c) +v3d_vir_to_qpu(struct v3d_compile *c, struct qpu_reg *temp_registers) { - struct qpu_reg *temp_registers = v3d_register_allocate(c); - struct qblock *end_block = list_last_entry(&c->blocks, - struct qblock, link); - /* Reset the uniform count to how many will be actually loaded by the * generated QPU code. */ @@ -326,10 +380,6 @@ v3d_vir_to_qpu(struct v3d_compile *c) vir_for_each_block(block, c) v3d_generate_code_block(c, block, temp_registers); - struct qinst *thrsw = vir_nop(); - list_addtail(&thrsw->link, &end_block->instructions); - thrsw->qpu.sig.thrsw = true; - uint32_t cycles = v3d_qpu_schedule_instructions(c); c->qpu_insts = rzalloc_array(c, uint64_t, c->qpu_inst_count); @@ -337,11 +387,27 @@ v3d_vir_to_qpu(struct v3d_compile *c) vir_for_each_inst_inorder(inst, c) { bool ok = v3d_qpu_instr_pack(c->devinfo, &inst->qpu, &c->qpu_insts[i++]); - assert(ok); (void) ok; + if (!ok) { + fprintf(stderr, "Failed to pack instruction:\n"); + vir_dump_inst(c, inst); + fprintf(stderr, "\n"); + c->failed = true; + return; + } } assert(i == c->qpu_inst_count); if (V3D_DEBUG & V3D_DEBUG_SHADERDB) { + fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d instructions\n", + vir_get_stage_name(c), + c->program_id, c->variant_id, + c->qpu_inst_count); + } + + /* The QPU cycle estimates are pretty broken (see waddr_latency()), so + * don't report them for now. + */ + if (false) { fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d estimated cycles\n", vir_get_stage_name(c), c->program_id, c->variant_id, diff --git a/lib/mesa/src/broadcom/meson.build b/lib/mesa/src/broadcom/meson.build new file mode 100644 index 000000000..d3ea362f2 --- /dev/null +++ b/lib/mesa/src/broadcom/meson.build @@ -0,0 +1,58 @@ +# Copyright © 2017 Broadcom +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +inc_broadcom = include_directories('.', 'cle') + +subdir('cle') + +v3d_versions = ['33', '41', '42'] +v3d_libs = [] + +if with_gallium_v3d + subdir('compiler') + subdir('qpu') +endif + +per_version_libs = [] +foreach ver : v3d_versions + per_version_libs += static_library( + 'libbroadcom-v' + ver, + [ + files('clif/v3dx_dump.c'), + v3d_xml_pack + ], + include_directories : [inc_common, inc_broadcom, inc_src], + c_args : [c_vis_args, no_override_init_args, '-DV3D_VERSION=' + ver], + dependencies: [dep_valgrind, dep_thread], + ) +endforeach + +libbroadcom_v3d = static_library( + 'libbroadcom_v3d', + [ + files('common/v3d_debug.c', 'clif/clif_dump.c'), + v3d_xml_pack, + ], + include_directories : [inc_common, inc_broadcom, inc_src], + c_args : [c_vis_args, no_override_init_args], + link_whole : v3d_libs + per_version_libs, + build_by_default : false, + dependencies: [dep_valgrind, dep_thread], +) diff --git a/lib/mesa/src/broadcom/qpu/meson.build b/lib/mesa/src/broadcom/qpu/meson.build new file mode 100644 index 000000000..8a4001606 --- /dev/null +++ b/lib/mesa/src/broadcom/qpu/meson.build @@ -0,0 +1,45 @@ +# Copyright © 2017 Broadcom +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libbroadcom_qpu_files = files( + 'qpu_disasm.c', + 'qpu_instr.c', + 'qpu_pack.c', +) + +libbroadcom_qpu = static_library( + ['broadcom_qpu', v3d_xml_pack], + libbroadcom_qpu_files, + include_directories : [inc_common, inc_broadcom], + c_args : [c_vis_args, no_override_init_args], + dependencies : [dep_libdrm, dep_valgrind], + build_by_default : false, +) + +v3d_libs += libbroadcom_qpu + +test( + 'qpu_disasm', + executable( + 'qpu_disasm', 'tests/qpu_disasm.c', + link_with: [libbroadcom_qpu, libmesa_util], + include_directories: inc_common + ) +) diff --git a/lib/mesa/src/broadcom/qpu/qpu_disasm.c b/lib/mesa/src/broadcom/qpu/qpu_disasm.c index 5ee834852..32e7ba12a 100644 --- a/lib/mesa/src/broadcom/qpu/qpu_disasm.c +++ b/lib/mesa/src/broadcom/qpu/qpu_disasm.c @@ -62,7 +62,21 @@ v3d_qpu_disasm_raddr(struct disasm_state *disasm, if (mux == V3D_QPU_MUX_A) { append(disasm, "rf%d", instr->raddr_a); } else if (mux == V3D_QPU_MUX_B) { - append(disasm, "rf%d", instr->raddr_b); + if (instr->sig.small_imm) { + uint32_t val; + MAYBE_UNUSED bool ok = + v3d_qpu_small_imm_unpack(disasm->devinfo, + instr->raddr_b, + &val); + + if ((int)val >= -16 && (int)val <= 15) + append(disasm, "%d", val); + else + append(disasm, "0x%08x", val); + assert(ok); + } else { + append(disasm, "rf%d", instr->raddr_b); + } } else { append(disasm, "r%d", mux); } @@ -91,7 +105,8 @@ v3d_qpu_disasm_add(struct disasm_state *disasm, int num_src = v3d_qpu_add_op_num_src(instr->alu.add.op); append(disasm, "%s", v3d_qpu_add_op_name(instr->alu.add.op)); - append(disasm, "%s", v3d_qpu_cond_name(instr->flags.ac)); + if (!v3d_qpu_sig_writes_address(disasm->devinfo, &instr->sig)) + append(disasm, "%s", v3d_qpu_cond_name(instr->flags.ac)); append(disasm, "%s", v3d_qpu_pf_name(instr->flags.apf)); append(disasm, "%s", v3d_qpu_uf_name(instr->flags.auf)); @@ -130,7 +145,8 @@ v3d_qpu_disasm_mul(struct disasm_state *disasm, append(disasm, "; "); append(disasm, "%s", v3d_qpu_mul_op_name(instr->alu.mul.op)); - append(disasm, "%s", v3d_qpu_cond_name(instr->flags.mc)); + if (!v3d_qpu_sig_writes_address(disasm->devinfo, &instr->sig)) + append(disasm, "%s", v3d_qpu_cond_name(instr->flags.mc)); append(disasm, "%s", v3d_qpu_pf_name(instr->flags.mpf)); append(disasm, "%s", v3d_qpu_uf_name(instr->flags.muf)); @@ -162,6 +178,24 @@ v3d_qpu_disasm_mul(struct disasm_state *disasm, } static void +v3d_qpu_disasm_sig_addr(struct disasm_state *disasm, + const struct v3d_qpu_instr *instr) +{ + if (disasm->devinfo->ver < 41) + return; + + if (!instr->sig_magic) + append(disasm, ".rf%d", instr->sig_addr); + else { + const char *name = v3d_qpu_magic_waddr_name(instr->sig_addr); + if (name) + append(disasm, ".%s", name); + else + append(disasm, ".UNKNOWN%d", instr->sig_addr); + } +} + +static void v3d_qpu_disasm_sig(struct disasm_state *disasm, const struct v3d_qpu_instr *instr) { @@ -172,6 +206,9 @@ v3d_qpu_disasm_sig(struct disasm_state *disasm, !sig->ldvpm && !sig->ldtmu && !sig->ldunif && + !sig->ldunifrf && + !sig->ldunifa && + !sig->ldunifarf && !sig->wrtmuc) { return; } @@ -180,14 +217,36 @@ v3d_qpu_disasm_sig(struct disasm_state *disasm, if (sig->thrsw) append(disasm, "; thrsw"); - if (sig->ldvary) + if (sig->ldvary) { append(disasm, "; ldvary"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } if (sig->ldvpm) append(disasm, "; ldvpm"); - if (sig->ldtmu) + if (sig->ldtmu) { append(disasm, "; ldtmu"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } + if (sig->ldtlb) { + append(disasm, "; ldtlb"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } + if (sig->ldtlbu) { + append(disasm, "; ldtlbu"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } if (sig->ldunif) append(disasm, "; ldunif"); + if (sig->ldunifrf) { + append(disasm, "; ldunifrf"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } + if (sig->ldunifa) + append(disasm, "; ldunifa"); + if (sig->ldunifarf) { + append(disasm, "; ldunifarf"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } if (sig->wrtmuc) append(disasm, "; wrtmuc"); } diff --git a/lib/mesa/src/broadcom/qpu/qpu_instr.c b/lib/mesa/src/broadcom/qpu/qpu_instr.c index 7499170de..147017a65 100644 --- a/lib/mesa/src/broadcom/qpu/qpu_instr.c +++ b/lib/mesa/src/broadcom/qpu/qpu_instr.c @@ -23,92 +23,9 @@ #include <stdlib.h> #include "util/macros.h" +#include "broadcom/common/v3d_device_info.h" #include "qpu_instr.h" -#ifndef QPU_MASK -#define QPU_MASK(high, low) ((((uint64_t)1<<((high)-(low)+1))-1)<<(low)) -/* Using the GNU statement expression extension */ -#define QPU_SET_FIELD(value, field) \ - ({ \ - uint64_t fieldval = (uint64_t)(value) << field ## _SHIFT; \ - assert((fieldval & ~ field ## _MASK) == 0); \ - fieldval & field ## _MASK; \ - }) - -#define QPU_GET_FIELD(word, field) ((uint32_t)(((word) & field ## _MASK) >> field ## _SHIFT)) - -#define QPU_UPDATE_FIELD(inst, value, field) \ - (((inst) & ~(field ## _MASK)) | QPU_SET_FIELD(value, field)) -#endif /* QPU_MASK */ - -#define VC5_QPU_OP_MUL_SHIFT 58 -#define VC5_QPU_OP_MUL_MASK QPU_MASK(63, 58) - -#define VC5_QPU_SIG_SHIFT 53 -#define VC5_QPU_SIG_MASK QPU_MASK(57, 53) -# define VC5_QPU_SIG_THRSW_BIT 0x1 -# define VC5_QPU_SIG_LDUNIF_BIT 0x2 -# define VC5_QPU_SIG_LDTMU_BIT 0x4 -# define VC5_QPU_SIG_LDVARY_BIT 0x8 - -#define VC5_QPU_COND_SHIFT 46 -#define VC5_QPU_COND_MASK QPU_MASK(52, 46) - -#define VC5_QPU_COND_IFA 0 -#define VC5_QPU_COND_IFB 1 -#define VC5_QPU_COND_IFNA 2 -#define VC5_QPU_COND_IFNB 3 - -#define VC5_QPU_MM QPU_MASK(45, 45) -#define VC5_QPU_MA QPU_MASK(44, 44) - -#define V3D_QPU_WADDR_M_SHIFT 38 -#define V3D_QPU_WADDR_M_MASK QPU_MASK(43, 38) - -#define VC5_QPU_BRANCH_ADDR_LOW_SHIFT 35 -#define VC5_QPU_BRANCH_ADDR_LOW_MASK QPU_MASK(55, 35) - -#define V3D_QPU_WADDR_A_SHIFT 32 -#define V3D_QPU_WADDR_A_MASK QPU_MASK(37, 32) - -#define VC5_QPU_BRANCH_COND_SHIFT 32 -#define VC5_QPU_BRANCH_COND_MASK QPU_MASK(34, 32) - -#define VC5_QPU_BRANCH_ADDR_HIGH_SHIFT 24 -#define VC5_QPU_BRANCH_ADDR_HIGH_MASK QPU_MASK(31, 24) - -#define VC5_QPU_OP_ADD_SHIFT 24 -#define VC5_QPU_OP_ADD_MASK QPU_MASK(31, 24) - -#define VC5_QPU_MUL_B_SHIFT 21 -#define VC5_QPU_MUL_B_MASK QPU_MASK(23, 21) - -#define VC5_QPU_BRANCH_MSFIGN_SHIFT 21 -#define VC5_QPU_BRANCH_MSFIGN_MASK QPU_MASK(22, 21) - -#define VC5_QPU_MUL_A_SHIFT 18 -#define VC5_QPU_MUL_A_MASK QPU_MASK(20, 18) - -#define VC5_QPU_ADD_B_SHIFT 15 -#define VC5_QPU_ADD_B_MASK QPU_MASK(17, 15) - -#define VC5_QPU_BRANCH_BDU_SHIFT 15 -#define VC5_QPU_BRANCH_BDU_MASK QPU_MASK(17, 15) - -#define VC5_QPU_BRANCH_UB QPU_MASK(14, 14) - -#define VC5_QPU_ADD_A_SHIFT 12 -#define VC5_QPU_ADD_A_MASK QPU_MASK(14, 12) - -#define VC5_QPU_BRANCH_BDI_SHIFT 12 -#define VC5_QPU_BRANCH_BDI_MASK QPU_MASK(13, 12) - -#define VC5_QPU_RADDR_A_SHIFT 6 -#define VC5_QPU_RADDR_A_MASK QPU_MASK(11, 6) - -#define VC5_QPU_RADDR_B_SHIFT 0 -#define VC5_QPU_RADDR_B_MASK QPU_MASK(5, 0) - const char * v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr) { @@ -131,12 +48,29 @@ v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr) [V3D_QPU_WADDR_VPMU] = "vpmu", [V3D_QPU_WADDR_SYNC] = "sync", [V3D_QPU_WADDR_SYNCU] = "syncu", + [V3D_QPU_WADDR_SYNCB] = "syncb", [V3D_QPU_WADDR_RECIP] = "recip", [V3D_QPU_WADDR_RSQRT] = "rsqrt", [V3D_QPU_WADDR_EXP] = "exp", [V3D_QPU_WADDR_LOG] = "log", [V3D_QPU_WADDR_SIN] = "sin", [V3D_QPU_WADDR_RSQRT2] = "rsqrt2", + [V3D_QPU_WADDR_TMUC] = "tmuc", + [V3D_QPU_WADDR_TMUS] = "tmus", + [V3D_QPU_WADDR_TMUT] = "tmut", + [V3D_QPU_WADDR_TMUR] = "tmur", + [V3D_QPU_WADDR_TMUI] = "tmui", + [V3D_QPU_WADDR_TMUB] = "tmub", + [V3D_QPU_WADDR_TMUDREF] = "tmudref", + [V3D_QPU_WADDR_TMUOFF] = "tmuoff", + [V3D_QPU_WADDR_TMUSCM] = "tmuscm", + [V3D_QPU_WADDR_TMUSF] = "tmusf", + [V3D_QPU_WADDR_TMUSLOD] = "tmuslod", + [V3D_QPU_WADDR_TMUHS] = "tmuhs", + [V3D_QPU_WADDR_TMUHSCM] = "tmuscm", + [V3D_QPU_WADDR_TMUHSF] = "tmuhsf", + [V3D_QPU_WADDR_TMUHSLOD] = "tmuhslod", + [V3D_QPU_WADDR_R5REP] = "r5rep", }; return waddr_magic[waddr]; @@ -172,7 +106,8 @@ v3d_qpu_add_op_name(enum v3d_qpu_add_op op) [V3D_QPU_A_NEG] = "neg", [V3D_QPU_A_FLAPUSH] = "flapush", [V3D_QPU_A_FLBPUSH] = "flbpush", - [V3D_QPU_A_FLBPOP] = "flbpop", + [V3D_QPU_A_FLPOP] = "flpop", + [V3D_QPU_A_RECIP] = "recip", [V3D_QPU_A_SETMSF] = "setmsf", [V3D_QPU_A_SETREVF] = "setrevf", [V3D_QPU_A_NOP] = "nop", @@ -192,14 +127,22 @@ v3d_qpu_add_op_name(enum v3d_qpu_add_op op) [V3D_QPU_A_VDWWT] = "vdwwt", [V3D_QPU_A_IID] = "iid", [V3D_QPU_A_SAMPID] = "sampid", - [V3D_QPU_A_PATCHID] = "patchid", + [V3D_QPU_A_BARRIERID] = "barrierid", [V3D_QPU_A_TMUWT] = "tmuwt", [V3D_QPU_A_VPMSETUP] = "vpmsetup", [V3D_QPU_A_VPMWT] = "vpmwt", - [V3D_QPU_A_LDVPMV] = "ldvpmv", - [V3D_QPU_A_LDVPMD] = "ldvpmd", + [V3D_QPU_A_LDVPMV_IN] = "ldvpmv_in", + [V3D_QPU_A_LDVPMV_OUT] = "ldvpmv_out", + [V3D_QPU_A_LDVPMD_IN] = "ldvpmd_in", + [V3D_QPU_A_LDVPMD_OUT] = "ldvpmd_out", [V3D_QPU_A_LDVPMP] = "ldvpmp", - [V3D_QPU_A_LDVPMG] = "ldvpmg", + [V3D_QPU_A_RSQRT] = "rsqrt", + [V3D_QPU_A_EXP] = "exp", + [V3D_QPU_A_LOG] = "log", + [V3D_QPU_A_SIN] = "sin", + [V3D_QPU_A_RSQRT2] = "rsqrt2", + [V3D_QPU_A_LDVPMG_IN] = "ldvpmg_in", + [V3D_QPU_A_LDVPMG_OUT] = "ldvpmg_out", [V3D_QPU_A_FCMP] = "fcmp", [V3D_QPU_A_VFMAX] = "vfmax", [V3D_QPU_A_FROUND] = "fround", @@ -431,7 +374,8 @@ static const uint8_t add_op_args[] = { [V3D_QPU_A_NEG] = D | A, [V3D_QPU_A_FLAPUSH] = D | A, [V3D_QPU_A_FLBPUSH] = D | A, - [V3D_QPU_A_FLBPOP] = D | A, + [V3D_QPU_A_FLPOP] = D | A, + [V3D_QPU_A_RECIP] = D | A, [V3D_QPU_A_SETMSF] = D | A, [V3D_QPU_A_SETREVF] = D | A, [V3D_QPU_A_NOP] = 0, @@ -453,16 +397,24 @@ static const uint8_t add_op_args[] = { [V3D_QPU_A_VDWWT] = D, [V3D_QPU_A_IID] = D, [V3D_QPU_A_SAMPID] = D, - [V3D_QPU_A_PATCHID] = D, + [V3D_QPU_A_BARRIERID] = D, [V3D_QPU_A_TMUWT] = D, [V3D_QPU_A_VPMWT] = D, [V3D_QPU_A_VPMSETUP] = D | A, - [V3D_QPU_A_LDVPMV] = D | A, - [V3D_QPU_A_LDVPMD] = D | A, + [V3D_QPU_A_LDVPMV_IN] = D | A, + [V3D_QPU_A_LDVPMV_OUT] = D | A, + [V3D_QPU_A_LDVPMD_IN] = D | A, + [V3D_QPU_A_LDVPMD_OUT] = D | A, [V3D_QPU_A_LDVPMP] = D | A, - [V3D_QPU_A_LDVPMG] = D | A | B, + [V3D_QPU_A_RSQRT] = D | A, + [V3D_QPU_A_EXP] = D | A, + [V3D_QPU_A_LOG] = D | A, + [V3D_QPU_A_SIN] = D | A, + [V3D_QPU_A_RSQRT2] = D | A, + [V3D_QPU_A_LDVPMG_IN] = D | A | B, + [V3D_QPU_A_LDVPMG_OUT] = D | A | B, /* FIXME: MOVABSNEG */ @@ -566,16 +518,19 @@ v3d_qpu_magic_waddr_is_sfu(enum v3d_qpu_waddr waddr) bool v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr) { - switch (waddr) { - case V3D_QPU_WADDR_TMU: - case V3D_QPU_WADDR_TMUL: - case V3D_QPU_WADDR_TMUD: - case V3D_QPU_WADDR_TMUA: - case V3D_QPU_WADDR_TMUAU: - return true; - default: - return false; - } + /* XXX: WADDR_TMU changed to UNIFA on 4.x */ + return ((waddr >= V3D_QPU_WADDR_TMU && + waddr <= V3D_QPU_WADDR_TMUAU) || + (waddr >= V3D_QPU_WADDR_TMUC && + waddr <= V3D_QPU_WADDR_TMUHSLOD)); +} + +bool +v3d_qpu_waits_on_tmu(const struct v3d_qpu_instr *inst) +{ + return (inst->sig.ldtmu || + (inst->type == V3D_QPU_INSTR_TYPE_ALU && + inst->alu.add.op == V3D_QPU_A_TMUWT)); } bool @@ -596,40 +551,222 @@ bool v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr) { return (waddr == V3D_QPU_WADDR_SYNC || + waddr == V3D_QPU_WADDR_SYNCB || waddr == V3D_QPU_WADDR_SYNCU); } +static bool +v3d_qpu_add_op_reads_vpm(enum v3d_qpu_add_op op) +{ + switch (op) { + case V3D_QPU_A_VPMSETUP: + case V3D_QPU_A_VPMWT: + case V3D_QPU_A_LDVPMV_IN: + case V3D_QPU_A_LDVPMV_OUT: + case V3D_QPU_A_LDVPMD_IN: + case V3D_QPU_A_LDVPMD_OUT: + case V3D_QPU_A_LDVPMP: + case V3D_QPU_A_LDVPMG_IN: + case V3D_QPU_A_LDVPMG_OUT: + return true; + default: + return false; + } +} + +static bool +v3d_qpu_add_op_writes_vpm(enum v3d_qpu_add_op op) +{ + switch (op) { + case V3D_QPU_A_VPMSETUP: + case V3D_QPU_A_VPMWT: + case V3D_QPU_A_STVPMV: + case V3D_QPU_A_STVPMD: + case V3D_QPU_A_STVPMP: + return true; + default: + return false; + } +} + bool -v3d_qpu_writes_r3(const struct v3d_qpu_instr *inst) +v3d_qpu_uses_tlb(const struct v3d_qpu_instr *inst) { + if (inst->sig.ldtlb || + inst->sig.ldtlbu) + return true; + + if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { + if (inst->alu.add.magic_write && + v3d_qpu_magic_waddr_is_tlb(inst->alu.add.waddr)) { + return true; + } + + if (inst->alu.mul.magic_write && + v3d_qpu_magic_waddr_is_tlb(inst->alu.mul.waddr)) { + return true; + } + } + + return false; +} + +bool +v3d_qpu_uses_sfu(const struct v3d_qpu_instr *inst) +{ + if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { + switch (inst->alu.add.op) { + case V3D_QPU_A_RECIP: + case V3D_QPU_A_RSQRT: + case V3D_QPU_A_EXP: + case V3D_QPU_A_LOG: + case V3D_QPU_A_SIN: + case V3D_QPU_A_RSQRT2: + return true; + default: + break; + } + + if (inst->alu.add.magic_write && + v3d_qpu_magic_waddr_is_sfu(inst->alu.add.waddr)) { + return true; + } + + if (inst->alu.mul.magic_write && + v3d_qpu_magic_waddr_is_sfu(inst->alu.mul.waddr)) { + return true; + } + } + + return false; +} + +bool +v3d_qpu_writes_tmu(const struct v3d_qpu_instr *inst) +{ + return (inst->type == V3D_QPU_INSTR_TYPE_ALU && + ((inst->alu.add.magic_write && + v3d_qpu_magic_waddr_is_tmu(inst->alu.add.waddr)) || + (inst->alu.mul.magic_write && + v3d_qpu_magic_waddr_is_tmu(inst->alu.mul.waddr)))); +} + +bool +v3d_qpu_reads_vpm(const struct v3d_qpu_instr *inst) +{ + if (inst->sig.ldvpm) + return true; + + if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { + if (v3d_qpu_add_op_reads_vpm(inst->alu.add.op)) + return true; + } + + return false; +} + +bool +v3d_qpu_writes_vpm(const struct v3d_qpu_instr *inst) +{ + if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { + if (v3d_qpu_add_op_writes_vpm(inst->alu.add.op)) + return true; + + if (inst->alu.add.magic_write && + v3d_qpu_magic_waddr_is_vpm(inst->alu.add.waddr)) { + return true; + } + + if (inst->alu.mul.magic_write && + v3d_qpu_magic_waddr_is_vpm(inst->alu.mul.waddr)) { + return true; + } + } + + return false; +} + +bool +v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst) +{ + return v3d_qpu_reads_vpm(inst) || v3d_qpu_writes_vpm(inst); +} + +bool +v3d_qpu_writes_r3(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *inst) +{ + if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { + if (inst->alu.add.magic_write && + inst->alu.add.waddr == V3D_QPU_WADDR_R3) { + return true; + } + + if (inst->alu.mul.magic_write && + inst->alu.mul.waddr == V3D_QPU_WADDR_R3) { + return true; + } + } + + if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) && + inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R3) { + return true; + } + return inst->sig.ldvary || inst->sig.ldvpm; } bool -v3d_qpu_writes_r4(const struct v3d_qpu_instr *inst) +v3d_qpu_writes_r4(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *inst) { if (inst->sig.ldtmu) return true; if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { if (inst->alu.add.magic_write && - v3d_qpu_magic_waddr_is_sfu(inst->alu.add.waddr)) { + (inst->alu.add.waddr == V3D_QPU_WADDR_R4 || + v3d_qpu_magic_waddr_is_sfu(inst->alu.add.waddr))) { return true; } if (inst->alu.mul.magic_write && - v3d_qpu_magic_waddr_is_sfu(inst->alu.mul.waddr)) { + (inst->alu.mul.waddr == V3D_QPU_WADDR_R4 || + v3d_qpu_magic_waddr_is_sfu(inst->alu.mul.waddr))) { return true; } } + if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) && + inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R4) { + return true; + } + return false; } bool -v3d_qpu_writes_r5(const struct v3d_qpu_instr *inst) +v3d_qpu_writes_r5(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *inst) { - return inst->sig.ldvary || inst->sig.ldunif; + if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { + if (inst->alu.add.magic_write && + inst->alu.add.waddr == V3D_QPU_WADDR_R5) { + return true; + } + + if (inst->alu.mul.magic_write && + inst->alu.mul.waddr == V3D_QPU_WADDR_R5) { + return true; + } + } + + if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) && + inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R5) { + return true; + } + + return inst->sig.ldvary || inst->sig.ldunif || inst->sig.ldunifa; } bool @@ -643,3 +780,18 @@ v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux) (mul_nsrc > 0 && inst->alu.mul.a == mux) || (mul_nsrc > 1 && inst->alu.mul.b == mux)); } + +bool +v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo, + const struct v3d_qpu_sig *sig) +{ + if (devinfo->ver < 41) + return false; + + return (sig->ldunifrf || + sig->ldunifarf || + sig->ldvary || + sig->ldtmu || + sig->ldtlb || + sig->ldtlbu); +} diff --git a/lib/mesa/src/broadcom/qpu/qpu_instr.h b/lib/mesa/src/broadcom/qpu/qpu_instr.h index a425fae8b..c2b4ebd19 100644 --- a/lib/mesa/src/broadcom/qpu/qpu_instr.h +++ b/lib/mesa/src/broadcom/qpu/qpu_instr.h @@ -42,6 +42,9 @@ struct v3d_device_info; struct v3d_qpu_sig { bool thrsw:1; bool ldunif:1; + bool ldunifa:1; + bool ldunifrf:1; + bool ldunifarf:1; bool ldtmu:1; bool ldvary:1; bool ldvpm:1; @@ -104,13 +107,29 @@ enum v3d_qpu_waddr { V3D_QPU_WADDR_VPMU = 15, V3D_QPU_WADDR_SYNC = 16, V3D_QPU_WADDR_SYNCU = 17, - /* reserved */ + V3D_QPU_WADDR_SYNCB = 18, V3D_QPU_WADDR_RECIP = 19, V3D_QPU_WADDR_RSQRT = 20, V3D_QPU_WADDR_EXP = 21, V3D_QPU_WADDR_LOG = 22, V3D_QPU_WADDR_SIN = 23, V3D_QPU_WADDR_RSQRT2 = 24, + V3D_QPU_WADDR_TMUC = 32, + V3D_QPU_WADDR_TMUS = 33, + V3D_QPU_WADDR_TMUT = 34, + V3D_QPU_WADDR_TMUR = 35, + V3D_QPU_WADDR_TMUI = 36, + V3D_QPU_WADDR_TMUB = 37, + V3D_QPU_WADDR_TMUDREF = 38, + V3D_QPU_WADDR_TMUOFF = 39, + V3D_QPU_WADDR_TMUSCM = 40, + V3D_QPU_WADDR_TMUSF = 41, + V3D_QPU_WADDR_TMUSLOD = 42, + V3D_QPU_WADDR_TMUHS = 43, + V3D_QPU_WADDR_TMUHSCM = 44, + V3D_QPU_WADDR_TMUHSF = 45, + V3D_QPU_WADDR_TMUHSLOD = 46, + V3D_QPU_WADDR_R5REP = 55, }; struct v3d_qpu_flags { @@ -146,7 +165,8 @@ enum v3d_qpu_add_op { V3D_QPU_A_NEG, V3D_QPU_A_FLAPUSH, V3D_QPU_A_FLBPUSH, - V3D_QPU_A_FLBPOP, + V3D_QPU_A_FLPOP, + V3D_QPU_A_RECIP, V3D_QPU_A_SETMSF, V3D_QPU_A_SETREVF, V3D_QPU_A_NOP, @@ -166,14 +186,22 @@ enum v3d_qpu_add_op { V3D_QPU_A_VDWWT, V3D_QPU_A_IID, V3D_QPU_A_SAMPID, - V3D_QPU_A_PATCHID, + V3D_QPU_A_BARRIERID, V3D_QPU_A_TMUWT, V3D_QPU_A_VPMSETUP, V3D_QPU_A_VPMWT, - V3D_QPU_A_LDVPMV, - V3D_QPU_A_LDVPMD, + V3D_QPU_A_LDVPMV_IN, + V3D_QPU_A_LDVPMV_OUT, + V3D_QPU_A_LDVPMD_IN, + V3D_QPU_A_LDVPMD_OUT, V3D_QPU_A_LDVPMP, - V3D_QPU_A_LDVPMG, + V3D_QPU_A_RSQRT, + V3D_QPU_A_EXP, + V3D_QPU_A_LOG, + V3D_QPU_A_SIN, + V3D_QPU_A_RSQRT2, + V3D_QPU_A_LDVPMG_IN, + V3D_QPU_A_LDVPMG_OUT, V3D_QPU_A_FCMP, V3D_QPU_A_VFMAX, V3D_QPU_A_FROUND, @@ -347,6 +375,8 @@ struct v3d_qpu_instr { enum v3d_qpu_instr_type type; struct v3d_qpu_sig sig; + uint8_t sig_addr; + bool sig_magic; /* If the signal writes to a magic address */ uint8_t raddr_a; uint8_t raddr_b; struct v3d_qpu_flags flags; @@ -390,6 +420,16 @@ v3d_qpu_flags_unpack(const struct v3d_device_info *devinfo, struct v3d_qpu_flags *cond); bool +v3d_qpu_small_imm_pack(const struct v3d_device_info *devinfo, + uint32_t value, + uint32_t *packed_small_immediate); + +bool +v3d_qpu_small_imm_unpack(const struct v3d_device_info *devinfo, + uint32_t packed_small_immediate, + uint32_t *small_immediate); + +bool v3d_qpu_instr_pack(const struct v3d_device_info *devinfo, const struct v3d_qpu_instr *instr, uint64_t *packed_instr); @@ -403,9 +443,21 @@ bool v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; bool v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; bool v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; bool v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; -bool v3d_qpu_writes_r3(const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; -bool v3d_qpu_writes_r4(const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; -bool v3d_qpu_writes_r5(const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; +bool v3d_qpu_uses_tlb(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST; +bool v3d_qpu_uses_sfu(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST; +bool v3d_qpu_writes_tmu(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST; +bool v3d_qpu_writes_r3(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; +bool v3d_qpu_writes_r4(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; +bool v3d_qpu_writes_r5(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; +bool v3d_qpu_waits_on_tmu(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST; bool v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux); +bool v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST; +bool v3d_qpu_reads_vpm(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST; +bool v3d_qpu_writes_vpm(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST; +bool v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo, + const struct v3d_qpu_sig *sig) ATTRIBUTE_CONST; #endif diff --git a/lib/mesa/src/broadcom/qpu/qpu_pack.c b/lib/mesa/src/broadcom/qpu/qpu_pack.c index 0ecce8666..70f31d734 100644 --- a/lib/mesa/src/broadcom/qpu/qpu_pack.c +++ b/lib/mesa/src/broadcom/qpu/qpu_pack.c @@ -48,18 +48,10 @@ #define VC5_QPU_SIG_SHIFT 53 #define VC5_QPU_SIG_MASK QPU_MASK(57, 53) -# define VC5_QPU_SIG_THRSW_BIT 0x1 -# define VC5_QPU_SIG_LDUNIF_BIT 0x2 -# define VC5_QPU_SIG_LDTMU_BIT 0x4 -# define VC5_QPU_SIG_LDVARY_BIT 0x8 #define VC5_QPU_COND_SHIFT 46 #define VC5_QPU_COND_MASK QPU_MASK(52, 46) - -#define VC5_QPU_COND_IFA 0 -#define VC5_QPU_COND_IFB 1 -#define VC5_QPU_COND_IFNA 2 -#define VC5_QPU_COND_IFNB 3 +#define VC5_QPU_COND_SIG_MAGIC_ADDR (1 << 6) #define VC5_QPU_MM QPU_MASK(45, 45) #define VC5_QPU_MA QPU_MASK(44, 44) @@ -113,6 +105,9 @@ #define THRSW .thrsw = true #define LDUNIF .ldunif = true +#define LDUNIFRF .ldunifrf = true +#define LDUNIFA .ldunifa = true +#define LDUNIFARF .ldunifarf = true #define LDTMU .ldtmu = true #define LDVARY .ldvary = true #define LDVPM .ldvpm = true @@ -156,6 +151,67 @@ static const struct v3d_qpu_sig v33_sig_map[] = { [31] = { SMIMM, }, }; +static const struct v3d_qpu_sig v40_sig_map[] = { + /* MISC R3 R4 R5 */ + [0] = { }, + [1] = { THRSW, }, + [2] = { LDUNIF }, + [3] = { THRSW, LDUNIF }, + [4] = { LDTMU, }, + [5] = { THRSW, LDTMU, }, + [6] = { LDTMU, LDUNIF }, + [7] = { THRSW, LDTMU, LDUNIF }, + [8] = { LDVARY, }, + [9] = { THRSW, LDVARY, }, + [10] = { LDVARY, LDUNIF }, + [11] = { THRSW, LDVARY, LDUNIF }, + /* 12-13 reserved */ + [14] = { SMIMM, LDVARY, }, + [15] = { SMIMM, }, + [16] = { LDTLB, }, + [17] = { LDTLBU, }, + [18] = { WRTMUC }, + [19] = { THRSW, WRTMUC }, + [20] = { LDVARY, WRTMUC }, + [21] = { THRSW, LDVARY, WRTMUC }, + [22] = { UCB, }, + [23] = { ROT, }, + /* 24-30 reserved */ + [31] = { SMIMM, LDTMU, }, +}; + +static const struct v3d_qpu_sig v41_sig_map[] = { + /* MISC phys R5 */ + [0] = { }, + [1] = { THRSW, }, + [2] = { LDUNIF }, + [3] = { THRSW, LDUNIF }, + [4] = { LDTMU, }, + [5] = { THRSW, LDTMU, }, + [6] = { LDTMU, LDUNIF }, + [7] = { THRSW, LDTMU, LDUNIF }, + [8] = { LDVARY, }, + [9] = { THRSW, LDVARY, }, + [10] = { LDVARY, LDUNIF }, + [11] = { THRSW, LDVARY, LDUNIF }, + [12] = { LDUNIFRF }, + [13] = { THRSW, LDUNIFRF }, + [14] = { SMIMM, LDVARY, }, + [15] = { SMIMM, }, + [16] = { LDTLB, }, + [17] = { LDTLBU, }, + [18] = { WRTMUC }, + [19] = { THRSW, WRTMUC }, + [20] = { LDVARY, WRTMUC }, + [21] = { THRSW, LDVARY, WRTMUC }, + [22] = { UCB, }, + [23] = { ROT, }, + /* 24-30 reserved */ + [24] = { LDUNIFA}, + [25] = { LDUNIFARF }, + [31] = { SMIMM, LDTMU, }, +}; + bool v3d_qpu_sig_unpack(const struct v3d_device_info *devinfo, uint32_t packed_sig, @@ -164,11 +220,16 @@ v3d_qpu_sig_unpack(const struct v3d_device_info *devinfo, if (packed_sig >= ARRAY_SIZE(v33_sig_map)) return false; - *sig = v33_sig_map[packed_sig]; + if (devinfo->ver >= 41) + *sig = v41_sig_map[packed_sig]; + else if (devinfo->ver == 40) + *sig = v40_sig_map[packed_sig]; + else + *sig = v33_sig_map[packed_sig]; /* Signals with zeroed unpacked contents after element 0 are reserved. */ return (packed_sig == 0 || - memcmp(sig, &v33_sig_map[0], sizeof(*sig) != 0)); + memcmp(sig, &v33_sig_map[0], sizeof(*sig)) != 0); } bool @@ -178,7 +239,12 @@ v3d_qpu_sig_pack(const struct v3d_device_info *devinfo, { static const struct v3d_qpu_sig *map; - map = v33_sig_map; + if (devinfo->ver >= 41) + map = v41_sig_map; + else if (devinfo->ver == 40) + map = v40_sig_map; + else + map = v33_sig_map; for (int i = 0; i < ARRAY_SIZE(v33_sig_map); i++) { if (memcmp(&map[i], sig, sizeof(*sig)) == 0) { @@ -189,6 +255,69 @@ v3d_qpu_sig_pack(const struct v3d_device_info *devinfo, return false; } +static inline unsigned +fui( float f ) +{ + union {float f; unsigned ui;} fi; + fi.f = f; + return fi.ui; +} + +static const uint32_t small_immediates[] = { + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + -16, -15, -14, -13, + -12, -11, -10, -9, + -8, -7, -6, -5, + -4, -3, -2, -1, + 0x3b800000, /* 2.0^-8 */ + 0x3c000000, /* 2.0^-7 */ + 0x3c800000, /* 2.0^-6 */ + 0x3d000000, /* 2.0^-5 */ + 0x3d800000, /* 2.0^-4 */ + 0x3e000000, /* 2.0^-3 */ + 0x3e800000, /* 2.0^-2 */ + 0x3f000000, /* 2.0^-1 */ + 0x3f800000, /* 2.0^0 */ + 0x40000000, /* 2.0^1 */ + 0x40800000, /* 2.0^2 */ + 0x41000000, /* 2.0^3 */ + 0x41800000, /* 2.0^4 */ + 0x42000000, /* 2.0^5 */ + 0x42800000, /* 2.0^6 */ + 0x43000000, /* 2.0^7 */ +}; + +bool +v3d_qpu_small_imm_unpack(const struct v3d_device_info *devinfo, + uint32_t packed_small_immediate, + uint32_t *small_immediate) +{ + if (packed_small_immediate >= ARRAY_SIZE(small_immediates)) + return false; + + *small_immediate = small_immediates[packed_small_immediate]; + return true; +} + +bool +v3d_qpu_small_imm_pack(const struct v3d_device_info *devinfo, + uint32_t value, + uint32_t *packed_small_immediate) +{ + STATIC_ASSERT(ARRAY_SIZE(small_immediates) == 48); + + for (int i = 0; i < ARRAY_SIZE(small_immediates); i++) { + if (small_immediates[i] == value) { + *packed_small_immediate = i; + return true; + } + } + + return false; +} bool v3d_qpu_flags_unpack(const struct v3d_device_info *devinfo, @@ -363,7 +492,8 @@ static const struct opcode_desc add_ops[] = { { 186, 186, 1 << 1, ANYMUX, V3D_QPU_A_NEG }, { 186, 186, 1 << 2, ANYMUX, V3D_QPU_A_FLAPUSH }, { 186, 186, 1 << 3, ANYMUX, V3D_QPU_A_FLBPUSH }, - { 186, 186, 1 << 4, ANYMUX, V3D_QPU_A_FLBPOP }, + { 186, 186, 1 << 4, ANYMUX, V3D_QPU_A_FLPOP }, + { 186, 186, 1 << 5, ANYMUX, V3D_QPU_A_RECIP }, { 186, 186, 1 << 6, ANYMUX, V3D_QPU_A_SETMSF }, { 186, 186, 1 << 7, ANYMUX, V3D_QPU_A_SETREVF }, { 187, 187, 1 << 0, 1 << 0, V3D_QPU_A_NOP, 0 }, @@ -382,11 +512,23 @@ static const struct opcode_desc add_ops[] = { { 187, 187, 1 << 2, 1 << 0, V3D_QPU_A_MSF }, { 187, 187, 1 << 2, 1 << 1, V3D_QPU_A_REVF }, - { 187, 187, 1 << 2, 1 << 2, V3D_QPU_A_VDWWT }, + { 187, 187, 1 << 2, 1 << 2, V3D_QPU_A_VDWWT, 33 }, + { 187, 187, 1 << 2, 1 << 2, V3D_QPU_A_IID, 40 }, + { 187, 187, 1 << 2, 1 << 3, V3D_QPU_A_SAMPID, 40 }, + { 187, 187, 1 << 2, 1 << 4, V3D_QPU_A_BARRIERID, 40 }, { 187, 187, 1 << 2, 1 << 5, V3D_QPU_A_TMUWT }, { 187, 187, 1 << 2, 1 << 6, V3D_QPU_A_VPMWT }, - { 187, 187, 1 << 3, ANYMUX, V3D_QPU_A_VPMSETUP }, + { 187, 187, 1 << 3, ANYMUX, V3D_QPU_A_VPMSETUP, 33 }, + { 188, 188, 1 << 0, ANYMUX, V3D_QPU_A_LDVPMV_IN, 40 }, + { 188, 188, 1 << 1, ANYMUX, V3D_QPU_A_LDVPMD_IN, 40 }, + { 188, 188, 1 << 2, ANYMUX, V3D_QPU_A_LDVPMP, 40 }, + { 188, 188, 1 << 3, ANYMUX, V3D_QPU_A_RSQRT, 41 }, + { 188, 188, 1 << 4, ANYMUX, V3D_QPU_A_EXP, 41 }, + { 188, 188, 1 << 5, ANYMUX, V3D_QPU_A_LOG, 41 }, + { 188, 188, 1 << 6, ANYMUX, V3D_QPU_A_SIN, 41 }, + { 188, 188, 1 << 7, ANYMUX, V3D_QPU_A_RSQRT2, 41 }, + { 189, 189, ANYMUX, ANYMUX, V3D_QPU_A_LDVPMG_IN, 40 }, /* FIXME: MORE COMPLICATED */ /* { 190, 191, ANYMUX, ANYMUX, V3D_QPU_A_VFMOVABSNEGNAB }, */ @@ -694,7 +836,24 @@ v3d_qpu_add_unpack(const struct v3d_device_info *devinfo, uint64_t packed_inst, instr->alu.add.a = mux_a; instr->alu.add.b = mux_b; instr->alu.add.waddr = QPU_GET_FIELD(packed_inst, V3D_QPU_WADDR_A); - instr->alu.add.magic_write = packed_inst & VC5_QPU_MA; + + instr->alu.add.magic_write = false; + if (packed_inst & VC5_QPU_MA) { + switch (instr->alu.add.op) { + case V3D_QPU_A_LDVPMV_IN: + instr->alu.add.op = V3D_QPU_A_LDVPMV_OUT; + break; + case V3D_QPU_A_LDVPMD_IN: + instr->alu.add.op = V3D_QPU_A_LDVPMD_OUT; + break; + case V3D_QPU_A_LDVPMG_IN: + instr->alu.add.op = V3D_QPU_A_LDVPMG_OUT; + break; + default: + instr->alu.add.magic_write = true; + break; + } + } return true; } @@ -743,6 +902,19 @@ v3d_qpu_mul_unpack(const struct v3d_device_info *devinfo, uint64_t packed_inst, } break; + + case V3D_QPU_M_VFMUL: + instr->alu.mul.output_pack = V3D_QPU_PACK_NONE; + + if (!v3d_qpu_float16_unpack_unpack(((op & 0x7) - 4) & 7, + &instr->alu.mul.a_unpack)) { + return false; + } + + instr->alu.mul.b_unpack = V3D_QPU_UNPACK_NONE; + + break; + default: instr->alu.mul.output_pack = V3D_QPU_PACK_NONE; instr->alu.mul.a_unpack = V3D_QPU_UNPACK_NONE; @@ -788,16 +960,36 @@ v3d_qpu_add_pack(const struct v3d_device_info *devinfo, if (nsrc < 1) mux_a = ffs(desc->mux_a_mask) - 1; + bool no_magic_write = false; + switch (instr->alu.add.op) { case V3D_QPU_A_STVPMV: waddr = 0; + no_magic_write = true; break; case V3D_QPU_A_STVPMD: waddr = 1; + no_magic_write = true; break; case V3D_QPU_A_STVPMP: waddr = 2; + no_magic_write = true; break; + + case V3D_QPU_A_LDVPMV_IN: + case V3D_QPU_A_LDVPMD_IN: + case V3D_QPU_A_LDVPMP: + case V3D_QPU_A_LDVPMG_IN: + assert(!instr->alu.add.magic_write); + break; + + case V3D_QPU_A_LDVPMV_OUT: + case V3D_QPU_A_LDVPMD_OUT: + case V3D_QPU_A_LDVPMG_OUT: + assert(!instr->alu.add.magic_write); + *packed_instr |= VC5_QPU_MA; + break; + default: break; } @@ -923,7 +1115,7 @@ v3d_qpu_add_pack(const struct v3d_device_info *devinfo, *packed_instr |= QPU_SET_FIELD(mux_b, VC5_QPU_ADD_B); *packed_instr |= QPU_SET_FIELD(opcode, VC5_QPU_OP_ADD); *packed_instr |= QPU_SET_FIELD(waddr, V3D_QPU_WADDR_A); - if (instr->alu.add.magic_write) + if (instr->alu.add.magic_write && !no_magic_write) *packed_instr |= VC5_QPU_MA; return true; @@ -1002,6 +1194,27 @@ v3d_qpu_mul_pack(const struct v3d_device_info *devinfo, break; } + case V3D_QPU_M_VFMUL: { + uint32_t packed; + + if (instr->alu.mul.output_pack != V3D_QPU_PACK_NONE) + return false; + + if (!v3d_qpu_float16_unpack_pack(instr->alu.mul.a_unpack, + &packed)) { + return false; + } + if (instr->alu.mul.a_unpack == V3D_QPU_UNPACK_SWAP_16) + opcode = 8; + else + opcode |= (packed + 4) & 7; + + if (instr->alu.mul.b_unpack != V3D_QPU_UNPACK_NONE) + return false; + + break; + } + default: break; } @@ -1029,10 +1242,21 @@ v3d_qpu_instr_unpack_alu(const struct v3d_device_info *devinfo, &instr->sig)) return false; - if (!v3d_qpu_flags_unpack(devinfo, - QPU_GET_FIELD(packed_instr, VC5_QPU_COND), - &instr->flags)) - return false; + uint32_t packed_cond = QPU_GET_FIELD(packed_instr, VC5_QPU_COND); + if (v3d_qpu_sig_writes_address(devinfo, &instr->sig)) { + instr->sig_addr = packed_cond & ~VC5_QPU_COND_SIG_MAGIC_ADDR; + instr->sig_magic = packed_cond & VC5_QPU_COND_SIG_MAGIC_ADDR; + + instr->flags.ac = V3D_QPU_COND_NONE; + instr->flags.mc = V3D_QPU_COND_NONE; + instr->flags.apf = V3D_QPU_PF_NONE; + instr->flags.mpf = V3D_QPU_PF_NONE; + instr->flags.auf = V3D_QPU_UF_NONE; + instr->flags.muf = V3D_QPU_UF_NONE; + } else { + if (!v3d_qpu_flags_unpack(devinfo, packed_cond, &instr->flags)) + return false; + } instr->raddr_a = QPU_GET_FIELD(packed_instr, VC5_QPU_RADDR_A); instr->raddr_b = QPU_GET_FIELD(packed_instr, VC5_QPU_RADDR_B); @@ -1130,9 +1354,28 @@ v3d_qpu_instr_pack_alu(const struct v3d_device_info *devinfo, return false; uint32_t flags; - if (!v3d_qpu_flags_pack(devinfo, &instr->flags, &flags)) - return false; + if (v3d_qpu_sig_writes_address(devinfo, &instr->sig)) { + if (instr->flags.ac != V3D_QPU_COND_NONE || + instr->flags.mc != V3D_QPU_COND_NONE || + instr->flags.apf != V3D_QPU_PF_NONE || + instr->flags.mpf != V3D_QPU_PF_NONE || + instr->flags.auf != V3D_QPU_UF_NONE || + instr->flags.muf != V3D_QPU_UF_NONE) { + return false; + } + + flags = instr->sig_addr; + if (instr->sig_magic) + flags |= VC5_QPU_COND_SIG_MAGIC_ADDR; + } else { + if (!v3d_qpu_flags_pack(devinfo, &instr->flags, &flags)) + return false; + } + *packed_instr |= QPU_SET_FIELD(flags, VC5_QPU_COND); + } else { + if (v3d_qpu_sig_writes_address(devinfo, &instr->sig)) + return false; } return true; diff --git a/lib/mesa/src/broadcom/qpu/tests/qpu_disasm.c b/lib/mesa/src/broadcom/qpu/tests/qpu_disasm.c index c7f6476de..2e8d98058 100644 --- a/lib/mesa/src/broadcom/qpu/tests/qpu_disasm.c +++ b/lib/mesa/src/broadcom/qpu/tests/qpu_disasm.c @@ -39,6 +39,20 @@ static const struct { { 33, 0x3f003186bb800000ull, "nop ; nop ; ldvpm" }, { 33, 0x3c002380b6edb000ull, "or rf0, r3, r3 ; mov vpm, r3" }, { 33, 0x57403006bbb80000ull, "nop ; fmul r0, rf0, r5 ; ldvpm; ldunif" }, + { 33, 0x9c094adef634b000ull, "ffloor.ifb rf30.l, r3; fmul.pushz rf43.l, r5, r1.h" }, + { 33, 0xb0044c56ba326840ull, "flpop rf22, rf33 ; fmul.pushz rf49.l, r4.h, r1.abs" }, + + /* vfmul input packing */ + { 33, 0x101e8b6e8aad4000ull, "fmax.nornn rf46, r4.l, r2.l; vfmul.ifnb rf45, r3, r5" }, + { 33, 0x1857d3c219825000ull, "faddnf.norc r2.l, r5.l, r4; vfmul.ifb rf15, r0.ll, r4; ldunif" }, + { 33, 0x1c0a0dfde2294000ull, "fcmp.ifna rf61.h, r4.abs, r2.l; vfmul rf55, r2.hh, r1" }, + { 33, 0x2011c89b402cc000ull, "fsub.norz rf27, r4.abs, r1.abs; vfmul.ifa rf34, r3.swp, r1" }, + + /* small immediates */ + { 33, 0x5de24398bbdc6218ull, "vflb.andnn rf24 ; fmul rf14, -8, rf8.h" }, + { 33, 0x25ef83d8b166f00full, "vfmin.pushn rf24, 15.ff, r5; smul24.ifnb rf15, r1, r3" }, + { 33, 0xadedcdf70839f990ull, "faddnf.pushc rf55, -16.l, r3.abs; fmul.ifb rf55.l, rf38.l, r1.h" }, + { 33, 0x7dff89fa6a01f020ull, "fsub.nornc rf58.h, 0x3b800000.l, r3.l; fmul.ifnb rf39, r0.h, r0.h" }, /* branch conditions */ { 33, 0x02000006002034c0ull, "b.anyap rf19" }, @@ -57,6 +71,29 @@ static const struct { { 33, 0x041618d57c453000ull, "shl.andn exp, r3, r2; add.ifb rf35, r1, r2" }, { 33, 0x7048e5da49272800ull, "fsub.ifa rf26, r2.l, rf32; fmul.pushc sin, r1.h, r1.abs; ldunif" }, + /* v4.1 signals */ + { 41, 0x1f010520cf60a000ull, "fcmp.andz rf32, r2.h, r1.h; vfmul rf20, r0.hh, r3; ldunifa" }, + { 41, 0x932045e6c16ea000ull, "fcmp rf38, r2.abs, r5; fmul rf23.l, r3, r3.abs; ldunifarf.rf1" }, + { 41, 0xd72f0434e43ae5c0ull, "fcmp rf52.h, rf23, r5.abs; fmul rf16.h, rf23, r1; ldunifarf.rf60" }, + { 41, 0xdb3048eb9d533780ull, "fmax rf43.l, r3.h, rf30; fmul rf35.h, r4, r2.l; ldunifarf.r1" }, + { 41, 0x733620471e6ce700ull, "faddnf rf7.l, rf28.h, r1.l; fmul r1, r3.h, r3.abs; ldunifarf.rsqrt2" }, + { 41, 0x9c094adef634b000ull, "ffloor.ifb rf30.l, r3; fmul.pushz rf43.l, r5, r1.h" }, + + /* v4.1 opcodes */ + { 41, 0x3de020c7bdfd200dull, "ldvpmg_in rf7, r2, r2; mov r3, 13" }, + { 41, 0x3de02040f8ff7201ull, "stvpmv 1, rf8 ; mov r1, 1" }, + { 41, 0xd8000e50bb2d3000ull, "sampid rf16 ; fmul rf57.h, r3, r1.l" }, + + /* v4.1 SFU instructions. */ + { 41, 0xe98d60c1ba2aef80ull, "recip rf1, rf62 ; fmul r3.h, r2.l, r1.l; ldunifrf.rf53" }, + { 41, 0x7d87c2debc51c000ull, "rsqrt rf30, r4 ; fmul rf11, r4.h, r2.h; ldunifrf.rf31" }, + { 41, 0xb182475abc2bb000ull, "rsqrt2 rf26, r3 ; fmul rf29.l, r2.h, r1.abs; ldunifrf.rf9" }, + { 41, 0x79880808bc0b6900ull, "sin rf8, rf36 ; fmul rf32, r2.h, r0.l; ldunifrf.rf32" }, + { 41, 0x04092094bc5a28c0ull, "exp.ifb rf20, r2 ; add r2, rf35, r2" }, + { 41, 0xe00648bfbc32a000ull, "log rf63, r2 ; fmul.andnn rf34.h, r4.l, r1.abs" }, + + /* v4.2 changes */ + { 42, 0x3c203192bb814000ull, "barrierid syncb ; nop ; thrsw" }, }; static void @@ -84,9 +121,10 @@ main(int argc, char **argv) for (int i = 0; i < ARRAY_SIZE(tests); i++) { devinfo.ver = tests[i].ver; - printf("Testing v%d.%d 0x%016llx... ", + printf("Testing v%d.%d 0x%016llx (\"%s\")... ", devinfo.ver / 10, devinfo.ver % 10, - (long long)tests[i].inst); + (long long)tests[i].inst, + tests[i].expected); const char *disasm_output = v3d_qpu_disasm(&devinfo, tests[i].inst); diff --git a/lib/mesa/src/glx/apple/apple_glx_log.c b/lib/mesa/src/glx/apple/apple_glx_log.c index a3f446c26..ea39d3095 100644 --- a/lib/mesa/src/glx/apple/apple_glx_log.c +++ b/lib/mesa/src/glx/apple/apple_glx_log.c @@ -97,6 +97,7 @@ void _apple_glx_vlog(int level, const char *file, const char *function, fprintf(stderr, "%-9s %24s:%-4d %s(%"PRIu64"): ", _asl_level_string(level), file, line, function, thread); vfprintf(stderr, fmt, args2); + va_end(args2); } msg = asl_new(ASL_TYPE_MSG); diff --git a/lib/mesa/src/glx/apple/meson.build b/lib/mesa/src/glx/apple/meson.build new file mode 100644 index 000000000..c6b1d617c --- /dev/null +++ b/lib/mesa/src/glx/apple/meson.build @@ -0,0 +1,61 @@ +# Copyright © 2017 Jon Turney + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# library for native GL on macos +files_libappleglx = files( + 'apple_cgl.c', + 'apple_cgl.h', + 'appledri.c', + 'appledri.h', + 'appledristr.h', + 'apple_glapi.c', + 'apple_glx.c', + 'apple_glx_context.c', + 'apple_glx_context.h', + 'apple_glx_drawable.c', + 'apple_glx_drawable.h', + 'apple_glx.h', + 'apple_glx_log.c', + 'apple_glx_log.h', + 'apple_glx_pbuffer.c', + 'apple_glx_pixmap.c', + 'apple_glx_surface.c', + 'apple_visual.c', + 'apple_visual.h', + 'apple_xgl_api.h', + 'apple_xgl_api_read.c', + 'apple_xgl_api_stereo.c', + 'apple_xgl_api_viewport.c', + 'glx_empty.c', +) + +dep_xplugin = null_dep +if with_dri_platform == 'apple' + dep_xplugin = meson.get_compiler('c').find_library('Xplugin') +endif + +libappleglx = static_library( + 'glxapple', + [files_libappleglx, glapitable_h], + include_directories: [inc_mesa, inc_glx, inc_src, inc_include, inc_glapi], + dependencies: [dep_xext, dep_xplugin], + c_args: [c_vis_args], + build_by_default: false, +) diff --git a/lib/mesa/src/glx/dri2_priv.h b/lib/mesa/src/glx/dri2_priv.h index 30ab2cdd8..a93551b14 100644 --- a/lib/mesa/src/glx/dri2_priv.h +++ b/lib/mesa/src/glx/dri2_priv.h @@ -30,6 +30,9 @@ * Kristian Høgsberg (krh@redhat.com) */ +#ifndef DRI2_PRIV_H +#define DRI2_PRIV_H + #ifdef __cplusplus extern "C" { #endif @@ -82,3 +85,5 @@ dri2_interop_export_object(struct glx_context *ctx, #ifdef __cplusplus } #endif + +#endif diff --git a/lib/mesa/src/glx/dri_common.h b/lib/mesa/src/glx/dri_common.h index 947d33177..4d97ff82b 100644 --- a/lib/mesa/src/glx/dri_common.h +++ b/lib/mesa/src/glx/dri_common.h @@ -78,6 +78,6 @@ extern bool dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, unsigned *major_ver, unsigned *minor_ver, uint32_t *render_type, uint32_t *flags, unsigned *api, - int *reset, unsigned *error); + int *reset, int *release, unsigned *error); #endif /* _DRI_COMMON_H */ diff --git a/lib/mesa/src/glx/drisw_priv.h b/lib/mesa/src/glx/drisw_priv.h index 5d4790031..259fc864f 100644 --- a/lib/mesa/src/glx/drisw_priv.h +++ b/lib/mesa/src/glx/drisw_priv.h @@ -23,6 +23,11 @@ * SOFTWARE. */ +#ifndef DRISW_PRIV_H +#define DRISW_PRIV_H + +#include <X11/extensions/XShm.h> + struct drisw_display { __GLXDRIdisplay base; @@ -62,6 +67,7 @@ struct drisw_drawable __DRIdrawable *driDrawable; XVisualInfo *visinfo; XImage *ximage; + XShmSegmentInfo shminfo; }; _X_HIDDEN int @@ -70,3 +76,5 @@ drisw_query_renderer_integer(struct glx_screen *base, int attribute, _X_HIDDEN int drisw_query_renderer_string(struct glx_screen *base, int attribute, const char **value); + +#endif diff --git a/lib/mesa/src/glx/glx_error.h b/lib/mesa/src/glx/glx_error.h index 5d3992672..6a2f32aa5 100644 --- a/lib/mesa/src/glx/glx_error.h +++ b/lib/mesa/src/glx/glx_error.h @@ -26,6 +26,10 @@ promote the sale, use or other dealings in this Software without prior written authorization. */ + +#ifndef GLX_ERROR_H +#define GLX_ERROR_H + #include <stdbool.h> #include <stdint.h> #include <X11/Xlib.h> @@ -45,3 +49,5 @@ _X_HIDDEN void __glXSendErrorForXcb(Display * dpy, #ifdef __cplusplus } #endif + +#endif diff --git a/lib/mesa/src/glx/glxcurrent.c b/lib/mesa/src/glx/glxcurrent.c index d1193265f..2b9c708c3 100644 --- a/lib/mesa/src/glx/glxcurrent.c +++ b/lib/mesa/src/glx/glxcurrent.c @@ -36,8 +36,8 @@ #include <pthread.h> #include "glxclient.h" - #include "glapi.h" +#include "glx_error.h" /* ** We setup some dummy structures here so that the API can be used @@ -165,21 +165,6 @@ glXGetCurrentDrawable(void) return gc->currentDrawable; } -static void -__glXGenerateError(Display * dpy, XID resource, - BYTE errorCode, CARD16 minorCode) -{ - xError error; - - error.errorCode = errorCode; - error.resourceID = resource; - error.sequenceNumber = dpy->request; - error.type = X_Error; - error.majorCode = __glXSetupForCommand(dpy); - error.minorCode = minorCode; - _XError(dpy, &error); -} - /** * Make a particular context current. * @@ -209,6 +194,13 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, return True; } + /* can't have only one be 0 */ + if (!!draw != !!read) { + __glXUnlock(); + __glXSendError(dpy, BadMatch, None, X_GLXMakeContextCurrent, True); + return False; + } + if (oldGC != &dummyContext) { if (--oldGC->thread_refcount == 0) { oldGC->vtable->unbind(oldGC, gc); @@ -228,7 +220,8 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, if (gc->vtable->bind(gc, oldGC, draw, read) != Success) { __glXSetCurrentContextNull(); __glXUnlock(); - __glXGenerateError(dpy, None, GLXBadContext, X_GLXMakeContextCurrent); + __glXSendError(dpy, GLXBadContext, None, X_GLXMakeContextCurrent, + False); return GL_FALSE; } diff --git a/lib/mesa/src/glx/glxext.c b/lib/mesa/src/glx/glxext.c index 5f23d3717..cef819203 100644 --- a/lib/mesa/src/glx/glxext.c +++ b/lib/mesa/src/glx/glxext.c @@ -343,9 +343,12 @@ static GLint convert_from_x_visual_type(int visualType) { static const int glx_visual_types[] = { - GLX_STATIC_GRAY, GLX_GRAY_SCALE, - GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, - GLX_TRUE_COLOR, GLX_DIRECT_COLOR + [StaticGray] = GLX_STATIC_GRAY, + [GrayScale] = GLX_GRAY_SCALE, + [StaticColor] = GLX_STATIC_COLOR, + [PseudoColor] = GLX_PSEUDO_COLOR, + [TrueColor] = GLX_TRUE_COLOR, + [DirectColor] = GLX_DIRECT_COLOR, }; if (visualType < ARRAY_SIZE(glx_visual_types)) @@ -402,8 +405,6 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count, #endif } - config->sRGBCapable = GL_FALSE; - /* ** Additional properties may be in a list at the end ** of the reply. They are in pairs of property type @@ -660,6 +661,8 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, */ m->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; #endif + /* Older X servers don't send this so we default it here. */ + m->sRGBCapable = GL_FALSE; __glXInitializeVisualConfigFromTags(m, nprops, props, tagged_only, GL_TRUE); m->screen = screen; diff --git a/lib/mesa/src/glx/glxextensions.c b/lib/mesa/src/glx/glxextensions.c index 6882e442f..e85a8c928 100644 --- a/lib/mesa/src/glx/glxextensions.c +++ b/lib/mesa/src/glx/glxextensions.c @@ -132,6 +132,7 @@ struct extension_info /* *INDENT-OFF* */ static const struct extension_info known_glx_extensions[] = { + { GLX(ARB_context_flush_control), VER(0,0), Y, N, N, N }, { GLX(ARB_create_context), VER(0,0), Y, N, N, N }, { GLX(ARB_create_context_profile), VER(0,0), Y, N, N, N }, { GLX(ARB_create_context_robustness), VER(0,0), Y, N, N, N }, @@ -151,7 +152,7 @@ static const struct extension_info known_glx_extensions[] = { { GLX(ATI_pixel_format_float), VER(0,0), N, N, N, N }, { GLX(INTEL_swap_event), VER(0,0), Y, N, N, N }, { GLX(MESA_copy_sub_buffer), VER(0,0), Y, N, N, N }, - { GLX(MESA_multithread_makecurrent),VER(0,0), Y, N, Y, N }, + { GLX(MESA_multithread_makecurrent),VER(0,0), Y, N, N, Y }, { GLX(MESA_query_renderer), VER(0,0), Y, N, N, Y }, { GLX(MESA_swap_control), VER(0,0), Y, N, N, Y }, { GLX(NV_float_buffer), VER(0,0), N, N, N, N }, @@ -160,8 +161,6 @@ static const struct extension_info known_glx_extensions[] = { { GLX(SGIS_multisample), VER(0,0), Y, Y, N, N }, { GLX(SGIX_fbconfig), VER(1,3), Y, Y, N, N }, { GLX(SGIX_pbuffer), VER(1,3), Y, Y, N, N }, - { GLX(SGIX_swap_barrier), VER(0,0), N, N, N, N }, - { GLX(SGIX_swap_group), VER(0,0), N, N, N, N }, { GLX(SGIX_visual_select_group), VER(0,0), Y, Y, N, N }, { GLX(SGI_make_current_read), VER(1,3), Y, N, N, N }, { GLX(SGI_swap_control), VER(0,0), Y, N, N, N }, diff --git a/lib/mesa/src/glx/indirect_glx.c b/lib/mesa/src/glx/indirect_glx.c index 4302a8ff2..cfae12f6c 100644 --- a/lib/mesa/src/glx/indirect_glx.c +++ b/lib/mesa/src/glx/indirect_glx.c @@ -62,13 +62,13 @@ indirect_destroy_context(struct glx_context *gc) } static Bool -SendMakeCurrentRequest(Display * dpy, CARD8 opcode, - GLXContextID gc_id, GLXContextTag gc_tag, - GLXDrawable draw, GLXDrawable read, - GLXContextTag *out_tag) +SendMakeCurrentRequest(Display * dpy, GLXContextID gc_id, + GLXContextTag gc_tag, GLXDrawable draw, + GLXDrawable read, GLXContextTag *out_tag) { xGLXMakeCurrentReply reply; Bool ret; + int opcode = __glXSetupForCommand(dpy); LockDisplay(dpy); @@ -136,7 +136,6 @@ indirect_bind_context(struct glx_context *gc, struct glx_context *old, { GLXContextTag tag; Display *dpy = gc->psc->dpy; - int opcode = __glXSetupForCommand(dpy); Bool sent; if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) { @@ -146,7 +145,7 @@ indirect_bind_context(struct glx_context *gc, struct glx_context *old, tag = 0; } - sent = SendMakeCurrentRequest(dpy, opcode, gc->xid, tag, draw, read, + sent = SendMakeCurrentRequest(dpy, gc->xid, tag, draw, read, &gc->currentContextTag); if (!IndirectAPI) @@ -160,7 +159,6 @@ static void indirect_unbind_context(struct glx_context *gc, struct glx_context *new) { Display *dpy = gc->psc->dpy; - int opcode = __glXSetupForCommand(dpy); if (gc == new) return; @@ -170,8 +168,8 @@ indirect_unbind_context(struct glx_context *gc, struct glx_context *new) * to send a request to the dpy to unbind the previous context. */ if (!new || new->isDirect || new->psc->dpy != dpy) { - SendMakeCurrentRequest(dpy, opcode, None, - gc->currentContextTag, None, None, NULL); + SendMakeCurrentRequest(dpy, None, gc->currentContextTag, None, None, + NULL); gc->currentContextTag = 0; } } diff --git a/lib/mesa/src/glx/meson.build b/lib/mesa/src/glx/meson.build new file mode 100644 index 000000000..a61f959e8 --- /dev/null +++ b/lib/mesa/src/glx/meson.build @@ -0,0 +1,172 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +inc_glx = include_directories('.') + +subdir('apple') +if with_dri_platform == 'windows' + subdir('windows') +endif + +files_libglx = files( + 'clientattrib.c', + 'clientinfo.c', + 'compsize.c', + 'create_context.c', + 'eval.c', + 'glxclient.h', + 'glxcmds.c', + 'glxconfig.c', + 'glxconfig.h', + 'glxcurrent.c', + 'glx_error.c', + 'glx_error.h', + 'glxext.c', + 'glxextensions.c', + 'glxextensions.h', + 'glxhash.c', + 'glxhash.h', + 'glx_pbuffer.c', + 'glx_query.c', + 'indirect_glx.c', + 'indirect_init.h', + 'indirect_texture_compression.c', + 'indirect_transpose_matrix.c', + 'indirect_vertex_array.c', + 'indirect_vertex_array.h', + 'indirect_vertex_array_priv.h', + 'indirect_vertex_program.c', + 'indirect_window_pos.c', + 'packrender.h', + 'packsingle.h', + 'pixel.c', + 'pixelstore.c', + 'query_renderer.c', + 'render2.c', + 'renderpix.c', + 'single2.c', + 'singlepix.c', + 'vertarr.c', +) + +extra_libs_libglx = [] +extra_deps_libgl = [] +extra_ld_args_libgl = [] + +if with_dri + files_libglx += files( + 'dri_common.c', + 'dri_common.h', + 'dri_common_query_renderer.c', + 'dri_common_interop.c', + 'xfont.c', + 'drisw_glx.c', + 'drisw_priv.h', + ) +endif + +# dri2 +if with_dri and with_dri_platform == 'drm' and dep_libdrm.found() + files_libglx += files( + 'dri2.c', + 'dri2_glx.c', + 'dri2.h', + 'dri2_priv.h', + 'dri_glx.c', + 'dri_sarea.h', + 'XF86dri.c', + 'xf86dri.h', + 'xf86dristr.h', + ) +endif + +if with_dri3 + files_libglx += files('dri3_glx.c', 'dri3_priv.h') +endif + +if with_dri_platform == 'apple' + files_libglx += files('applegl_glx.c') + extra_libs_libglx += libappleglx +elif with_dri_platform == 'windows' + files_libglx += files('driwindows_glx.c') + extra_libs_libglx += [ + libwindowsdri, + libwindowsglx, + ] + extra_deps_libgl = [ + meson.get_compiler('c').find_library('gdi32'), + meson.get_compiler('c').find_library('opengl32') + ] + extra_ld_args_libgl = '-Wl,--disable-stdcall-fixup' +endif + +if not with_glvnd + gl_lib_name = 'GL' + gl_lib_version = '1.2.0' +else + gl_lib_name = 'GLX_mesa' + gl_lib_version = '0.0.0' + files_libglx += files( + 'g_glxglvnddispatchfuncs.c', + 'g_glxglvnddispatchindices.h', + 'glxglvnd.c', + 'glxglvnd.h', + 'glxglvnddispatchfuncs.h', + ) +endif + +gl_lib_cargs = [ + '-D_REENTRANT', + '-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path), +] + +libglx = static_library( + 'glx', + [files_libglx, glx_generated], + include_directories : [inc_common, inc_glapi, inc_loader, inc_gl_internal], + c_args : [ + c_vis_args, gl_lib_cargs, + '-DGL_LIB_NAME="lib@0@.so.@1@"'.format(gl_lib_name, gl_lib_version.split('.')[0]), + ], + link_with : [ + libloader, libloader_dri3_helper, libmesa_util, libxmlconfig, + extra_libs_libglx, + ], + dependencies : [dep_libdrm, dep_dri2proto, dep_glproto, dep_x11, dep_glvnd], +) + +libgl = shared_library( + gl_lib_name, + [], + link_with : [libglapi_static, libglapi], + link_whole : libglx, + link_args : [ld_args_bsymbolic, ld_args_gc_sections, extra_ld_args_libgl], + dependencies : [ + dep_libdrm, dep_dl, dep_m, dep_thread, dep_x11, dep_xcb_glx, dep_xcb, + dep_x11_xcb, dep_xcb_dri2, dep_xext, dep_xfixes, dep_xdamage, dep_xxf86vm, + extra_deps_libgl, + ], + version : gl_lib_version, + install : true, +) + +if with_tests + subdir('tests') +endif diff --git a/lib/mesa/src/glx/tests/fake_glx_screen.cpp b/lib/mesa/src/glx/tests/fake_glx_screen.cpp index 801f54a6f..ca0ca3680 100644 --- a/lib/mesa/src/glx/tests/fake_glx_screen.cpp +++ b/lib/mesa/src/glx/tests/fake_glx_screen.cpp @@ -75,6 +75,18 @@ indirect_create_context_attribs(struct glx_screen *base, return indirect_create_context(base, config_base, shareList, 0); } +#ifdef GLX_USE_APPLEGL +#warning Indirect GLX tests are not built +extern "C" struct glx_context * +applegl_create_context(struct glx_screen *base, + struct glx_config *config_base, + struct glx_context *shareList, + int renderType) +{ + return indirect_create_context(base, config_base, shareList, renderType); +} +#endif + /* This is necessary so that we don't have to link with glxcurrent.c * which would require us to link with X libraries and what not. */ diff --git a/lib/mesa/src/glx/tests/indirect_api.cpp b/lib/mesa/src/glx/tests/indirect_api.cpp index 34304a185..b9a4ca065 100644 --- a/lib/mesa/src/glx/tests/indirect_api.cpp +++ b/lib/mesa/src/glx/tests/indirect_api.cpp @@ -705,6 +705,8 @@ void __indirect_glFramebufferTextureLayer(void) { } } /*@}*/ +#ifndef GLX_USE_APPLEGL + class IndirectAPI : public ::testing::Test { public: virtual void SetUp(); @@ -1518,3 +1520,5 @@ TEST_F(IndirectAPI, EXT_texture_array) { EXPECT_EQ((_glapi_proc) __indirect_glFramebufferTextureLayer, table[_glapi_get_proc_offset("glFramebufferTextureLayerEXT")]); } + +#endif diff --git a/lib/mesa/src/glx/tests/meson.build b/lib/mesa/src/glx/tests/meson.build new file mode 100644 index 000000000..e59b42d19 --- /dev/null +++ b/lib/mesa/src/glx/tests/meson.build @@ -0,0 +1,54 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if with_shared_glapi + files_glx_test = files( + 'clientinfo_unittest.cpp', + 'create_context_unittest.cpp', + 'enum_sizes.cpp', + 'fake_glx_screen.cpp', + 'fake_glx_screen.h', + 'indirect_api.cpp', + 'mock_xdisplay.h', + 'query_renderer_unittest.cpp', + ) + if with_dri2 + files_glx_test += files('query_renderer_implementation_unittest.cpp') + endif + + test( + 'dispatch-index-check', + files('dispatch-index-check'), + suite : ['glx'], + ) + test( + 'glx-test', + executable( + 'glx-test', + [files_glx_test, glx_indirect_size_h, main_dispatch_h], + link_with : [libglx, libglapi], + include_directories : [ + inc_src, inc_include, inc_mesa, inc_mapi, inc_gl_internal, + inc_glx, + ], + dependencies : [dep_libdrm, dep_glproto, dep_thread, idep_gtest] + ), + ) +endif diff --git a/lib/mesa/src/glx/windows/meson.build b/lib/mesa/src/glx/windows/meson.build new file mode 100644 index 000000000..153f41ab7 --- /dev/null +++ b/lib/mesa/src/glx/windows/meson.build @@ -0,0 +1,68 @@ +# Copyright © 2017 Jon Turney + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# protocol defines for the Windows-DRI server extension + +files_windowsdriproto = files( + 'windowsdriconst.h', + 'windowsdristr.h', + ) + +install_headers( + files_windowsdriproto, + subdir: 'X11/extensions', +) + +pkg.generate( + name : 'windowsdriproto', + description : 'Windows-DRI extension headers', + version : '1.0.0', +) + +# library for using the Windows-DRI server extension +files_libwindowsdri = files( + 'xwindowsdri.c', + 'xwindowsdri.h', +) + +libwindowsdri = static_library( + 'driwindows', + [files_libwindowsdri, files_windowsdriproto], + dependencies: dep_xext, + build_by_default: false, +) + +# library for native GL on windows +files_libwindowsglx = files( + 'windowsgl.c', + 'windowsgl.h', + 'windowsgl_internal.h', + 'windows_drawable.c', + 'wgl.c', + 'wgl.h', +) + +libwindowsglx = static_library( + 'glxwindows', + [files_libwindowsglx, files_windowsdriproto], + include_directories: [inc_include, inc_src, inc_glapi], + c_args : [c_vis_args], + build_by_default: false, +) diff --git a/lib/mesa/src/gtest/Makefile.am b/lib/mesa/src/gtest/Makefile.am index 29d6c6d19..23b755361 100644 --- a/lib/mesa/src/gtest/Makefile.am +++ b/lib/mesa/src/gtest/Makefile.am @@ -37,4 +37,5 @@ EXTRA_DIST = \ src/gtest-port.cc \ src/gtest-printers.cc \ src/gtest-test-part.cc \ - src/gtest-typed-test.cc + src/gtest-typed-test.cc \ + meson.build diff --git a/lib/mesa/src/gtest/meson.build b/lib/mesa/src/gtest/meson.build new file mode 100644 index 000000000..23c21423d --- /dev/null +++ b/lib/mesa/src/gtest/meson.build @@ -0,0 +1,32 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libgtest = static_library( + 'gtest', + files('src/gtest-all.cc', 'src/gtest_main.cc'), + include_directories : include_directories('include'), + cpp_args : '-w', + build_by_default : false, +) + +idep_gtest = declare_dependency( + link_with : libgtest, + include_directories : include_directories('include', is_system : true), +) diff --git a/lib/mesa/src/hgl/meson.build b/lib/mesa/src/hgl/meson.build new file mode 100644 index 000000000..ec06272ed --- /dev/null +++ b/lib/mesa/src/hgl/meson.build @@ -0,0 +1,36 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libgl = shared_library( + 'GL', + files( + 'GLView.cpp', 'GLRenderer.cpp', 'GLRendererRoster.cpp', 'GLDispatcher.cpp', + ), + link_args : [ld_args_bsymbolic, ld_args_gc_sections], + include_directories : [ + inc_src, inc_mapi, inc_mesa, inc_include, inc_glapi, inc_haikugl, + inc_gl_internal, include_directories('/system/develop/headers/private') + ], + link_with : [libglapi_static, libglapi], + dependencies : cpp.find_library('be'), + install : true, +) + +# TODO: We need some tests here diff --git a/lib/mesa/src/mapi/es1api/meson.build b/lib/mesa/src/mapi/es1api/meson.build new file mode 100644 index 000000000..d8a77a41d --- /dev/null +++ b/lib/mesa/src/mapi/es1api/meson.build @@ -0,0 +1,61 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +es1_glapi_mapi_tmp_h = custom_target( + 'es1_glapi_mapi_tmp.h', + input : [mapi_abi_py, gl_and_es_api_files], + output : 'glapi_mapi_tmp.h', + command : [prog_python, '@INPUT0@', '--printer', 'es1api', '@INPUT1@'], + depend_files : api_xml_files, + capture : true, +) + +libglesv1_cm = shared_library( + 'GLESv1_CM', + ['../entry.c', es1_glapi_mapi_tmp_h], + c_args : [ + c_msvc_compat_args, c_vis_args, '-DMAPI_MODE_BRIDGE', + '-DMAPI_ABI_HEADER="@0@"'.format(es1_glapi_mapi_tmp_h.full_path()), + ], + link_args : [ld_args_gc_sections], + include_directories : [inc_src, inc_include, inc_mapi], + link_with : libglapi, + dependencies : [dep_thread, dep_libdrm, dep_m, dep_dl], + version : '1.0.0', + install : true, +) + +pkg.generate( + name : 'glesv1_cm', + filebase : 'glesv1_cm', + description : 'Mesa OpenGL ES 1.1 CM library', + version : meson.project_version(), + libraries : libglesv1_cm, + libraries_private : gl_priv_libs, +) + +if with_tests + test( + 'es1-ABI-check', + find_program('ABI-check'), + env : env_test, + args : libglesv1_cm + ) +endif diff --git a/lib/mesa/src/mapi/es2api/meson.build b/lib/mesa/src/mapi/es2api/meson.build new file mode 100644 index 000000000..891e6f7b2 --- /dev/null +++ b/lib/mesa/src/mapi/es2api/meson.build @@ -0,0 +1,61 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +es2_glapi_mapi_tmp_h = custom_target( + 'es2_glapi_mapi_tmp.h', + input : [mapi_abi_py, gl_and_es_api_files], + output : 'glapi_mapi_tmp.h', + command : [prog_python, '@INPUT0@', '--printer', 'es2api', '@INPUT1@'], + depend_files : api_xml_files, + capture : true, +) + +libgles2 = shared_library( + 'GLESv2', + ['../entry.c', es2_glapi_mapi_tmp_h], + c_args : [ + c_msvc_compat_args, c_vis_args, '-DMAPI_MODE_BRIDGE', + '-DMAPI_ABI_HEADER="@0@"'.format(es2_glapi_mapi_tmp_h.full_path()), + ], + link_args : [ld_args_gc_sections], + include_directories : [inc_src, inc_include, inc_mapi], + link_with : libglapi, + dependencies : [dep_thread, dep_libdrm, dep_m, dep_dl], + version : '2.0.0', + install : true, +) + +pkg.generate( + name : 'glesv2', + filebase : 'glesv2', + description : 'Mesa OpenGL ES 2.0 library', + version : meson.project_version(), + libraries : libgles2, + libraries_private : gl_priv_libs, +) + +if with_tests + test( + 'es2-ABI-check', + find_program('ABI-check'), + env : env_test, + args : libgles2 + ) +endif diff --git a/lib/mesa/src/mapi/glapi/SConscript b/lib/mesa/src/mapi/glapi/SConscript index 994778a8f..118da1d53 100644 --- a/lib/mesa/src/mapi/glapi/SConscript +++ b/lib/mesa/src/mapi/glapi/SConscript @@ -19,17 +19,14 @@ if env['platform'] == 'windows': '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers 'KHRONOS_DLL_EXPORTS', # declare gl* as __declspec(dllexport) in Khronos headers + '_GLAPI_NO_EXPORTS', # prevent _glapi_* from being declared __declspec(dllimport) ]) - if env['gles']: - env.Append(CPPDEFINES = ['_GLAPI_DLL_EXPORTS']) - else: - # prevent _glapi_* from being declared __declspec(dllimport) - env.Append(CPPDEFINES = ['_GLAPI_NO_EXPORTS']) env.Append(CPPPATH = [ '#/src', '#/src/mapi', '#/src/mesa', + Dir('.'), # src/mapi/glapi build path Dir('..'), # src/mapi build path ]) diff --git a/lib/mesa/src/mapi/glapi/gen/AMD_depth_clamp_separate.xml b/lib/mesa/src/mapi/glapi/gen/AMD_depth_clamp_separate.xml new file mode 100644 index 000000000..b7142f1b7 --- /dev/null +++ b/lib/mesa/src/mapi/glapi/gen/AMD_depth_clamp_separate.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> + +<OpenGLAPI> + +<category name="GL_AMD_depth_clamp_separate" number="401"> + <enum name="DEPTH_CLAMP_NEAR_AMD" count="1" value="0x901E"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEPTH_CLAMP_FAR_AMD" count="1" value="0x901F"> + <size name="Get" mode="get"/> + </enum> +</category> + +</OpenGLAPI> diff --git a/lib/mesa/src/mapi/glapi/gen/AMD_gpu_shader_int64.xml b/lib/mesa/src/mapi/glapi/gen/AMD_gpu_shader_int64.xml new file mode 100644 index 000000000..42eb750d1 --- /dev/null +++ b/lib/mesa/src/mapi/glapi/gen/AMD_gpu_shader_int64.xml @@ -0,0 +1,239 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> + +<OpenGLAPI> + +<category name="GL_AMD_gpu_shader_int64" number="451"> + + <function name="Uniform1i64NV" alias="Uniform1i64ARB"> + <param name="location" type="GLint"/> + <param name="x" type="GLint64"/> + </function> + + <function name="Uniform2i64NV" alias="Uniform2i64ARB"> + <param name="location" type="GLint"/> + <param name="x" type="GLint64"/> + <param name="y" type="GLint64"/> + </function> + + <function name="Uniform3i64NV" alias="Uniform3i64ARB"> + <param name="location" type="GLint"/> + <param name="x" type="GLint64"/> + <param name="y" type="GLint64"/> + <param name="z" type="GLint64"/> + </function> + + <function name="Uniform4i64NV" alias="Uniform4i64ARB"> + <param name="location" type="GLint"/> + <param name="x" type="GLint64"/> + <param name="y" type="GLint64"/> + <param name="z" type="GLint64"/> + <param name="w" type="GLint64"/> + </function> + + <function name="Uniform1i64vNV" alias="Uniform1i64vARB"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint64 *" count="count"/> + </function> + + <function name="Uniform2i64vNV" alias="Uniform2i64vARB"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint64 *" count="count" count_scale="2"/> + </function> + + <function name="Uniform3i64vNV" alias="Uniform3i64vARB"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint64 *" count="count" count_scale="3"/> + </function> + + <function name="Uniform4i64vNV" alias="Uniform4i64vARB"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint64 *" count="count" count_scale="4"/> + </function> + + <function name="Uniform1ui64NV" alias="Uniform1ui64ARB"> + <param name="location" type="GLint"/> + <param name="x" type="GLuint64"/> + </function> + + <function name="Uniform2ui64NV" alias="Uniform2ui64ARB"> + <param name="location" type="GLint"/> + <param name="x" type="GLuint64"/> + <param name="y" type="GLuint64"/> + </function> + + <function name="Uniform3ui64NV" alias="Uniform3ui64ARB"> + <param name="location" type="GLint"/> + <param name="x" type="GLuint64"/> + <param name="y" type="GLuint64"/> + <param name="z" type="GLuint64"/> + </function> + + <function name="Uniform4ui64NV" alias="Uniform4ui64ARB"> + <param name="location" type="GLint"/> + <param name="x" type="GLuint64"/> + <param name="y" type="GLuint64"/> + <param name="z" type="GLuint64"/> + <param name="w" type="GLuint64"/> + </function> + + <function name="Uniform1ui64vNV" alias="Uniform1ui64vARB"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint64 *" count="count"/> + </function> + + <function name="Uniform2ui64vNV" alias="Uniform2ui64vARB"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint64 *" count="count" count_scale="2"/> + </function> + + <function name="Uniform3ui64vNV" alias="Uniform3ui64vARB"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint64 *" count="count" count_scale="3"/> + </function> + + <function name="Uniform4ui64vNV" alias="Uniform4ui64vARB"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint64 *" count="count" count_scale="4"/> + </function> + + <function name="GetUniformi64vNV" alias="GetUniformi64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="params" type="GLint64 *"/> + </function> + + <function name="GetUniformui64vNV" alias="GetUniformui64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="params" type="GLuint64 *"/> + </function> + + <function name="ProgramUniform1i64NV" alias="ProgramUniform1i64ARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="x" type="GLint64"/> + </function> + + <function name="ProgramUniform2i64NV" alias="ProgramUniform2i64ARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="x" type="GLint64"/> + <param name="y" type="GLint64"/> + </function> + + <function name="ProgramUniform3i64NV" alias="ProgramUniform3i64ARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="x" type="GLint64"/> + <param name="y" type="GLint64"/> + <param name="z" type="GLint64"/> + </function> + + <function name="ProgramUniform4i64NV" alias="ProgramUniform4i64ARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="x" type="GLint64"/> + <param name="y" type="GLint64"/> + <param name="z" type="GLint64"/> + <param name="w" type="GLint64"/> + </function> + + <function name="ProgramUniform1i64vNV" alias="ProgramUniform1i64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint64 *" count="count"/> + </function> + + <function name="ProgramUniform2i64vNV" alias="ProgramUniform2i64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint64 *" count="count" count_scale="2"/> + </function> + + <function name="ProgramUniform3i64vNV" alias="ProgramUniform3i64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint64 *" count="count" count_scale="3"/> + </function> + + <function name="ProgramUniform4i64vNV" alias="ProgramUniform4i64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint64 *" count="count" count_scale="4"/> + </function> + + <function name="ProgramUniform1ui64NV" alias="ProgramUniform1ui64ARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="x" type="GLuint64"/> + </function> + + <function name="ProgramUniform2ui64NV" alias="ProgramUniform2ui64ARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="x" type="GLuint64"/> + <param name="y" type="GLuint64"/> + </function> + + <function name="ProgramUniform3ui64NV" alias="ProgramUniform3ui64ARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="x" type="GLuint64"/> + <param name="y" type="GLuint64"/> + <param name="z" type="GLuint64"/> + </function> + + <function name="ProgramUniform4ui64NV" alias="ProgramUniform4ui64ARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="x" type="GLuint64"/> + <param name="y" type="GLuint64"/> + <param name="z" type="GLuint64"/> + <param name="w" type="GLuint64"/> + </function> + + <function name="ProgramUniform1ui64vNV" alias="ProgramUniform1ui64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint64 *" count="count"/> + </function> + + <function name="ProgramUniform2ui64vNV" alias="ProgramUniform2ui64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint64 *" count="count" count_scale="2"/> + </function> + + <function name="ProgramUniform3ui64vNV" alias="ProgramUniform3ui64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint64 *" count="count" count_scale="3"/> + </function> + + <function name="ProgramUniform4ui64vNV" alias="ProgramUniform4ui64vARB"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint64 *" count="count" count_scale="4"/> + </function> + +</category> + +</OpenGLAPI> + diff --git a/lib/mesa/src/mapi/glapi/gen/AMD_performance_monitor.xml b/lib/mesa/src/mapi/glapi/gen/AMD_performance_monitor.xml index b29dc5d90..785ea076c 100644 --- a/lib/mesa/src/mapi/glapi/gen/AMD_performance_monitor.xml +++ b/lib/mesa/src/mapi/glapi/gen/AMD_performance_monitor.xml @@ -5,13 +5,13 @@ <category name="GL_AMD_performance_monitor" number="360"> - <function name="GetPerfMonitorGroupsAMD"> + <function name="GetPerfMonitorGroupsAMD" es2="2.0"> <param name="numGroups" type="GLint *"/> <param name="groupsSize" type="GLsizei"/> <param name="groups" type="GLuint *"/> </function> - <function name="GetPerfMonitorCountersAMD"> + <function name="GetPerfMonitorCountersAMD" es2="2.0"> <param name="group" type="GLuint"/> <param name="numCounters" type="GLint *"/> <param name="maxActiveCounters" type="GLint *"/> @@ -19,14 +19,14 @@ <param name="counters" type="GLuint *"/> </function> - <function name="GetPerfMonitorGroupStringAMD"> + <function name="GetPerfMonitorGroupStringAMD" es2="2.0"> <param name="group" type="GLuint"/> <param name="bufSize" type="GLsizei"/> <param name="length" type="GLsizei *"/> <param name="groupString" type="GLchar *"/> </function> - <function name="GetPerfMonitorCounterStringAMD"> + <function name="GetPerfMonitorCounterStringAMD" es2="2.0"> <param name="group" type="GLuint"/> <param name="counter" type="GLuint"/> <param name="bufSize" type="GLsizei"/> @@ -34,24 +34,24 @@ <param name="counterString" type="GLchar *"/> </function> - <function name="GetPerfMonitorCounterInfoAMD"> + <function name="GetPerfMonitorCounterInfoAMD" es2="2.0"> <param name="group" type="GLuint"/> <param name="counter" type="GLuint"/> <param name="pname" type="GLenum"/> <param name="data" type="GLvoid *"/> </function> - <function name="GenPerfMonitorsAMD"> + <function name="GenPerfMonitorsAMD" es2="2.0"> <param name="n" type="GLsizei"/> <param name="monitors" type="GLuint *"/> </function> - <function name="DeletePerfMonitorsAMD"> + <function name="DeletePerfMonitorsAMD" es2="2.0"> <param name="n" type="GLsizei"/> <param name="monitors" type="GLuint *"/> </function> - <function name="SelectPerfMonitorCountersAMD"> + <function name="SelectPerfMonitorCountersAMD" es2="2.0"> <param name="monitor" type="GLuint"/> <param name="enable" type="GLboolean"/> <param name="group" type="GLuint"/> @@ -59,15 +59,15 @@ <param name="counterList" type="GLuint *"/> </function> - <function name="BeginPerfMonitorAMD"> + <function name="BeginPerfMonitorAMD" es2="2.0"> <param name="monitor" type="GLuint"/> </function> - <function name="EndPerfMonitorAMD"> + <function name="EndPerfMonitorAMD" es2="2.0"> <param name="monitor" type="GLuint"/> </function> - <function name="GetPerfMonitorCounterDataAMD"> + <function name="GetPerfMonitorCounterDataAMD" es2="2.0"> <param name="monitor" type="GLuint"/> <param name="pname" type="GLenum"/> <param name="dataSize" type="GLsizei"/> diff --git a/lib/mesa/src/mapi/glapi/gen/ARB_draw_indirect.xml b/lib/mesa/src/mapi/glapi/gen/ARB_draw_indirect.xml index 3b29d6b86..b4399f1e8 100644 --- a/lib/mesa/src/mapi/glapi/gen/ARB_draw_indirect.xml +++ b/lib/mesa/src/mapi/glapi/gen/ARB_draw_indirect.xml @@ -42,4 +42,24 @@ </category> +<category name="GL_AMD_multi_draw_indirect" number="408"> + + <function name="MultiDrawArraysIndirectAMD" exec="dynamic" alias="MultiDrawArraysIndirect"> + <param name="mode" type="GLenum"/> + <param name="indirect" type="const GLvoid *"/> + <param name="primcount" type="GLsizei"/> + <param name="stride" type="GLsizei"/> + </function> + + <function name="MultiDrawElementsIndirectAMD" exec="dynamic" alias="MultiDrawElementsIndirect"> + <param name="mode" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="indirect" type="const GLvoid *"/> + <param name="primcount" type="GLsizei"/> + <param name="stride" type="GLsizei"/> + </function> + +</category> + + </OpenGLAPI> diff --git a/lib/mesa/src/mapi/glapi/gen/ARB_gl_spirv.xml b/lib/mesa/src/mapi/glapi/gen/ARB_gl_spirv.xml new file mode 100644 index 000000000..0dd615480 --- /dev/null +++ b/lib/mesa/src/mapi/glapi/gen/ARB_gl_spirv.xml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> + +<OpenGLAPI> + +<category name="GL_ARB_gl_spirv" number="190"> + + <enum name="SHADER_BINARY_FORMAT_SPIR_V_ARB" value="0x9551"/> + <enum name="SPIR_V_BINARY_ARB" value="0x9552"/> + + <function name="SpecializeShaderARB"> + <param name="shader" type="GLuint"/> + <param name="pEntryPoint" type="const GLchar *"/> + <param name="numSpecializationConstants" type="GLuint"/> + <param name="pConstantIndex" type="const GLuint *"/> + <param name="pConstantValue" type="const GLuint *"/> + </function> + +</category> + +</OpenGLAPI> diff --git a/lib/mesa/src/mapi/glapi/gen/EXT_framebuffer_object.xml b/lib/mesa/src/mapi/glapi/gen/EXT_framebuffer_object.xml index 310e8ee95..6c0e54af1 100644 --- a/lib/mesa/src/mapi/glapi/gen/EXT_framebuffer_object.xml +++ b/lib/mesa/src/mapi/glapi/gen/EXT_framebuffer_object.xml @@ -75,7 +75,7 @@ <return type="GLboolean"/> </function> - <function name="BindRenderbufferEXT" deprecated="3.1"> + <function name="BindRenderbufferEXT"> <param name="target" type="GLenum"/> <param name="renderbuffer" type="GLuint"/> <glx rop="4316"/> @@ -109,7 +109,7 @@ <return type="GLboolean"/> </function> - <function name="BindFramebufferEXT" deprecated="3.1"> + <function name="BindFramebufferEXT"> <param name="target" type="GLenum"/> <param name="framebuffer" type="GLuint"/> <glx rop="4319"/> diff --git a/lib/mesa/src/mapi/glapi/gen/EXT_vertex_attrib_64bit.xml b/lib/mesa/src/mapi/glapi/gen/EXT_vertex_attrib_64bit.xml new file mode 100644 index 000000000..6b63b122f --- /dev/null +++ b/lib/mesa/src/mapi/glapi/gen/EXT_vertex_attrib_64bit.xml @@ -0,0 +1,70 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> + +<OpenGLAPI> + +<category name="GL_EXT_vertex_attrib_64bit" number="387"> + + <function name="VertexAttribL1dEXT" alias="VertexAttribL1d"> + <param name="index" type="GLuint"/> + <param name="x" type="GLdouble"/> + </function> + + <function name="VertexAttribL2dEXT" alias="VertexAttribL2d"> + <param name="index" type="GLuint"/> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + </function> + + <function name="VertexAttribL3dEXT" alias="VertexAttribL3d"> + <param name="index" type="GLuint"/> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + <param name="z" type="GLdouble"/> + </function> + + <function name="VertexAttribL4dEXT" alias="VertexAttribL4d"> + <param name="index" type="GLuint"/> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + <param name="z" type="GLdouble"/> + <param name="w" type="GLdouble"/> + </function> + + <function name="VertexAttribL1dvEXT" alias="VertexAttribL1dv"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLdouble *"/> + </function> + + <function name="VertexAttribL2dvEXT" alias="VertexAttribL2dv"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLdouble *"/> + </function> + + <function name="VertexAttribL3dvEXT" alias="VertexAttribL3dv"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLdouble *"/> + </function> + + <function name="VertexAttribL4dvEXT" alias="VertexAttribL4dv"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLdouble *"/> + </function> + + <function name="VertexAttribLPointerEXT" alias="VertexAttribLPointer"> + <param name="index" type="GLuint"/> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </function> + + <function name="GetVertexAttribLdvEXT" alias="GetVertexAttribLdv"> + <param name="index" type="GLuint"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLdouble *"/> + </function> +</category> + +</OpenGLAPI> + diff --git a/lib/mesa/src/mapi/glapi/gen/GL4x.xml b/lib/mesa/src/mapi/glapi/gen/GL4x.xml index 512addc2b..2116286b3 100644 --- a/lib/mesa/src/mapi/glapi/gen/GL4x.xml +++ b/lib/mesa/src/mapi/glapi/gen/GL4x.xml @@ -68,12 +68,50 @@ </category> <category name="4.6"> + <enum name="PARAMETER_BUFFER" value="0x80EE"/> + <enum name="PARAMETER_BUFFER_BINDING" value="0x80EF"/> + <enum name="POLYGON_OFFSET_CLAMP" value="0x8E1B"/> + <enum name="SHADER_BINARY_FORMAT_SPIR_V" value="0x9551"/> + <enum name="SPIR_V_BINARY" value="0x9552"/> + + <!-- This function aliases one from GL_EXT_polygon_offset_clamp --> + <function name="PolygonOffsetClamp" alias="PolygonOffsetClampEXT"> <param name="factor" type="GLfloat"/> <param name="units" type="GLfloat"/> <param name="clamp" type="GLfloat"/> </function> - <enum name="POLYGON_OFFSET_CLAMP" value="0x8E1B"/> + + <!-- This function aliases one from GL_ARB_gl_spirv --> + + <function name="SpecializeShader" alias="SpecializeShaderARB"> + <param name="shader" type="GLuint"/> + <param name="pEntryPoint" type="const GLchar *"/> + <param name="numSpecializationConstants" type="GLuint"/> + <param name="pConstantIndex" type="const GLuint *"/> + <param name="pConstantValue" type="const GLuint *"/> + </function> + + <!-- These functions alias ones from GL_ARB_indirect_parameters --> + + <function name="MultiDrawArraysIndirectCount" + alias="MultiDrawArraysIndirectCountARB"> + <param name="mode" type="GLenum"/> + <param name="indirect" type="GLintptr"/> + <param name="drawcount" type="GLintptr"/> + <param name="maxdrawcount" type="GLsizei"/> + <param name="stride" type="GLsizei"/> + </function> + + <function name="MultiDrawElementsIndirectCount" + alias="MultiDrawElementsIndirectCountARB"> + <param name="mode" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="indirect" type="GLintptr"/> + <param name="drawcount" type="GLintptr"/> + <param name="maxdrawcount" type="GLsizei"/> + <param name="stride" type="GLsizei"/> + </function> </category> </OpenGLAPI> diff --git a/lib/mesa/src/mapi/glapi/gen/KHR_robustness_es.xml b/lib/mesa/src/mapi/glapi/gen/KHR_robustness_es.xml index 84f6fd2cd..82b7edf31 100644 --- a/lib/mesa/src/mapi/glapi/gen/KHR_robustness_es.xml +++ b/lib/mesa/src/mapi/glapi/gen/KHR_robustness_es.xml @@ -60,4 +60,36 @@ </category> +<category name="GL_EXT_robustness" number="107"> + <function name="GetGraphicsResetStatusEXT" + alias="GetGraphicsResetStatusARB" es2="2.0"> + <return type="GLenum"/> + </function> + + <function name="ReadnPixelsEXT" alias="ReadnPixelsARB" es2="2.0"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="bufSize" type="GLsizei"/> + <param name="data" type="GLvoid *" output="true"/> + </function> + + <function name="GetnUniformfvEXT" alias="GetnUniformfvARB" es2="2.0"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="bufSize" type="GLsizei"/> + <param name="params" type="GLfloat *" output="true"/> + </function> + + <function name="GetnUniformivEXT" alias="GetnUniformivARB" es2="2.0"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="bufSize" type="GLsizei"/> + <param name="params" type="GLint *" output="true"/> + </function> +</category> + </OpenGLAPI> diff --git a/lib/mesa/src/mapi/glapi/gen/meson.build b/lib/mesa/src/mapi/glapi/gen/meson.build new file mode 100644 index 000000000..f494e9707 --- /dev/null +++ b/lib/mesa/src/mapi/glapi/gen/meson.build @@ -0,0 +1,273 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +gl_and_es_api_files = files('gl_and_es_API.xml') + +api_xml_files = files( + 'gl_API.xml', + 'es_EXT.xml', + 'gl_and_es_API.xml', + 'gl_and_glX_API.xml', + 'ARB_base_instance.xml', + 'ARB_blend_func_extended.xml', + 'ARB_bindless_texture.xml', + 'ARB_clear_buffer_object.xml', + 'ARB_clear_texture.xml', + 'ARB_clip_control.xml', + 'ARB_color_buffer_float.xml', + 'ARB_compressed_texture_pixel_storage.xml', + 'ARB_compute_shader.xml', + 'ARB_compute_variable_group_size.xml', + 'ARB_copy_buffer.xml', + 'ARB_copy_image.xml', + 'ARB_debug_output.xml', + 'ARB_depth_buffer_float.xml', + 'ARB_depth_clamp.xml', + 'ARB_direct_state_access.xml', + 'ARB_draw_buffers.xml', + 'ARB_draw_buffers_blend.xml', + 'ARB_draw_elements_base_vertex.xml', + 'ARB_draw_indirect.xml', + 'ARB_draw_instanced.xml', + 'ARB_ES2_compatibility.xml', + 'ARB_ES3_compatibility.xml', + 'ARB_framebuffer_no_attachments.xml', + 'ARB_framebuffer_object.xml', + 'ARB_get_program_binary.xml', + 'ARB_get_texture_sub_image.xml', + 'ARB_gl_spirv.xml', + 'ARB_gpu_shader_fp64.xml', + 'ARB_gpu_shader_int64.xml', + 'ARB_gpu_shader5.xml', + 'ARB_indirect_parameters.xml', + 'ARB_instanced_arrays.xml', + 'ARB_internalformat_query.xml', + 'ARB_internalformat_query2.xml', + 'ARB_invalidate_subdata.xml', + 'ARB_map_buffer_range.xml', + 'ARB_multi_bind.xml', + 'ARB_pipeline_statistics_query.xml', + 'ARB_program_interface_query.xml', + 'ARB_robustness.xml', + 'ARB_sample_shading.xml', + 'ARB_sampler_objects.xml', + 'ARB_seamless_cube_map.xml', + 'ARB_separate_shader_objects.xml', + 'ARB_shader_atomic_counters.xml', + 'ARB_shader_image_load_store.xml', + 'ARB_shader_subroutine.xml', + 'ARB_shader_storage_buffer_object.xml', + 'ARB_sparse_buffer.xml', + 'ARB_sync.xml', + 'ARB_tessellation_shader.xml', + 'ARB_texture_barrier.xml', + 'ARB_texture_buffer_object.xml', + 'ARB_texture_buffer_range.xml', + 'ARB_texture_compression_rgtc.xml', + 'ARB_texture_cube_map_array.xml', + 'ARB_texture_float.xml', + 'ARB_texture_gather.xml', + 'ARB_texture_multisample.xml', + 'ARB_texture_rgb10_a2ui.xml', + 'ARB_texture_rg.xml', + 'ARB_texture_storage_multisample.xml', + 'ARB_texture_storage.xml', + 'ARB_texture_view.xml', + 'ARB_uniform_buffer_object.xml', + 'ARB_vertex_array_object.xml', + 'ARB_vertex_attrib_64bit.xml', + 'ARB_vertex_attrib_binding.xml', + 'ARB_viewport_array.xml', + 'AMD_depth_clamp_separate.xml', + 'AMD_draw_buffers_blend.xml', + 'AMD_gpu_shader_int64.xml', + 'AMD_performance_monitor.xml', + 'ARB_vertex_type_2_10_10_10_rev.xml', + 'APPLE_object_purgeable.xml', + 'APPLE_vertex_array_object.xml', + 'EXT_draw_buffers2.xml', + 'EXT_external_objects.xml', + 'EXT_external_objects_fd.xml', + 'EXT_framebuffer_object.xml', + 'EXT_gpu_shader4.xml', + 'EXT_packed_depth_stencil.xml', + 'EXT_provoking_vertex.xml', + 'EXT_separate_shader_objects.xml', + 'EXT_texture_array.xml', + 'EXT_texture_integer.xml', + 'EXT_transform_feedback.xml', + 'EXT_vertex_attrib_64bit.xml', + 'EXT_window_rectangles.xml', + 'GREMEDY_string_marker.xml', + 'INTEL_performance_query.xml', + 'KHR_debug.xml', + 'KHR_context_flush_control.xml', + 'KHR_robustness.xml', + 'KHR_robustness_es.xml', + 'KHR_texture_compression_astc.xml', + 'NV_conditional_render.xml', + 'NV_primitive_restart.xml', + 'NV_texture_barrier.xml', + 'NV_vdpau_interop.xml', + 'OES_EGL_image.xml', + 'OES_fixed_point.xml', + 'OES_single_precision.xml', + 'OES_texture_compression_astc.xml', + 'GL3x.xml', + 'GL4x.xml', +) + +glapi_gen_depends = files( + 'gl_XML.py', + 'glX_XML.py', + 'license.py', + 'static_data.py', + 'typeexpr.py', +) + api_xml_files + +glx_gen_depends = files( + 'glX_API.xml', + 'glX_XML.py', + 'glX_proto_common.py', +) + api_xml_files + +glapi_mapi_tmp_h = custom_target( + 'glapi_mapi_tmp.h', + input : [mapi_abi_py, 'gl_and_es_API.xml'], + output : 'glapi_mapi_tmp.h', + command : [prog_python, '@INPUT0@', '--printer', 'glapi', '@INPUT1@'], + depend_files : glapi_gen_depends, + capture : true, +) + +glprocs_h = custom_target( + 'glprocs.h', + input : ['gl_procs.py', 'gl_and_es_API.xml'], + output : 'glprocs.h', + command : [prog_python, '@INPUT0@', '-c', '-f', '@INPUT1@'], + depend_files : glapi_gen_depends, + capture : true, +) + +glapitemp_h = custom_target( + 'glapitemp.h', + input : ['gl_apitemp.py', 'gl_and_es_API.xml'], + output : 'glapitemp.h', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : glapi_gen_depends, + capture : true, +) + +glapitable_h = custom_target( + 'glapitable.h', + input : ['gl_table.py', 'gl_and_es_API.xml'], + output : 'glapitable.h', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : glapi_gen_depends, + capture : true, +) + +glapi_gentable_c = custom_target( + 'glapi_gentable.c', + input : ['gl_gentable.py', 'gl_and_es_API.xml'], + output : 'glapi_gentable.c', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : glapi_gen_depends, + capture : true, +) + +main_enums_c = custom_target( + 'enums.c', + input : ['gl_enums.py', files('../registry/gl.xml')], + output : 'enums.c', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + capture : true, +) + +main_api_exec_c = custom_target( + 'api_exec.c', + input : ['gl_genexec.py', 'gl_and_es_API.xml'], + output : 'api_exec.c', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : files('apiexec.py') + glapi_gen_depends, + capture : true, +) + +main_marshal_generated_c = custom_target( + 'marshal_generated.c', + input : ['gl_marshal.py', 'gl_and_es_API.xml'], + output : 'marshal_generated.c', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : files('marshal_XML.py') + glapi_gen_depends, + capture : true, +) + +glx_generated = [] + +foreach x : [['indirect.c', 'proto'], ['indirect.h', 'init_h'], ['indirect_init.c', 'init_c']] + glx_generated += custom_target( + x[0], + input : ['glX_proto_send.py', 'gl_API.xml'], + output : x[0], + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@', '-m', x[1]], + depend_files : glx_gen_depends, + capture : true, + ) +endforeach + +foreach x : [['indirect_size.h', ['-m', 'size_h', '--header-tag', '_INDIRECT_SIZE_H_']], + ['indirect_size.c', ['-m', 'size_c']]] + glx_generated += custom_target( + x[0], + input : ['glX_proto_size.py', 'gl_API.xml'], + output : x[0], + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@', '--only-set', x[1]], + depend_files : glx_gen_depends, + capture : true, + ) +endforeach +glx_indirect_size_h = glx_generated[3] + +glapi_x86_s = custom_target( + 'glapi_x86.S', + input : ['gl_x86_asm.py', gl_and_es_api_files], + output : 'glapi_x86.S', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : glapi_gen_depends, + capture : true, +) + +glapi_x86_64_s = custom_target( + 'glapi_x86-64.S', + input : ['gl_x86-64_asm.py', gl_and_es_api_files], + output : 'glapi_x86-64.S', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : glapi_gen_depends, + capture : true, +) + +glapi_sparc_s = custom_target( + 'glapi_sparc.S', + input : ['gl_SPARC_asm.py', gl_and_es_api_files], + output : 'glapi_sparc.S', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : glapi_gen_depends, + capture : true, +) diff --git a/lib/mesa/src/mapi/glapi/glapi_dispatch.c b/lib/mesa/src/mapi/glapi/glapi_dispatch.c index df907ff9d..ca15449ed 100644 --- a/lib/mesa/src/mapi/glapi/glapi_dispatch.c +++ b/lib/mesa/src/mapi/glapi/glapi_dispatch.c @@ -38,7 +38,7 @@ */ #include "glapi/glapi_priv.h" -#include "glapi/glapitable.h" +#include "glapitable.h" #if !(defined(USE_X86_ASM) || defined(USE_X86_64_ASM) || defined(USE_SPARC_ASM)) @@ -97,6 +97,13 @@ */ #include <GLES/glplatform.h> + +/* Redefine GL_API to avoid MSVC/MinGW warnings about different dllimport + * attributes for these prototypes vs those in the GLES/gl.h header. + */ +#undef GL_API +#define GL_API KEYWORD1 + GL_API void GL_APIENTRY glClearDepthf (GLclampf depth); GL_API void GL_APIENTRY glClipPlanef (GLenum plane, const GLfloat *equation); GL_API void GL_APIENTRY glFrustumf (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); @@ -143,6 +150,8 @@ GL_API void GL_APIENTRY glTexParameterx (GLenum target, GLenum pname, GLfixed pa GL_API void GL_APIENTRY glTexParameterxv (GLenum target, GLenum pname, const GLfixed *params); GL_API void GL_APIENTRY glTranslatex (GLfixed x, GLfixed y, GLfixed z); GL_API void GL_APIENTRY glPointSizePointerOES (GLenum type, GLsizei stride, const GLvoid *pointer); +GL_API void GL_APIENTRY glBlendBarrier (void); +GL_API void GL_APIENTRY glPrimitiveBoundingBox (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); /* Enable frame pointer elimination on Windows, otherwise forgetting to add * APIENTRY to _mesa_* entrypoints will not cause crashes on debug builds, as diff --git a/lib/mesa/src/mapi/glapi/glapi_getproc.c b/lib/mesa/src/mapi/glapi/glapi_getproc.c index a6b2455f1..d3fd3f82d 100644 --- a/lib/mesa/src/mapi/glapi/glapi_getproc.c +++ b/lib/mesa/src/mapi/glapi/glapi_getproc.c @@ -34,7 +34,7 @@ #include <string.h> #include <stdlib.h> #include "glapi/glapi_priv.h" -#include "glapi/glapitable.h" +#include "glapitable.h" #define FIRST_DYNAMIC_OFFSET (sizeof(struct _glapi_table) / sizeof(void *)) @@ -49,7 +49,7 @@ #if !defined(DISPATCH_FUNCTION_SIZE) # define NEED_FUNCTION_POINTER #endif -#include "glapi/glprocs.h" +#include "glprocs.h" /** diff --git a/lib/mesa/src/mapi/glapi/glapi_nop.c b/lib/mesa/src/mapi/glapi/glapi_nop.c index 13db310b3..2e130e63e 100644 --- a/lib/mesa/src/mapi/glapi/glapi_nop.c +++ b/lib/mesa/src/mapi/glapi/glapi_nop.c @@ -116,7 +116,7 @@ NoOpUnused(void) #define DISPATCH_TABLE_NAME __glapi_noop_table #define UNUSED_TABLE_NAME __unused_noop_functions -#include "glapi/glapitemp.h" +#include "glapitemp.h" /** Return pointer to new dispatch table filled with no-op functions */ diff --git a/lib/mesa/src/mapi/glapi/glapi_priv.h b/lib/mesa/src/mapi/glapi/glapi_priv.h index 8f2c6775d..ddfc594a9 100644 --- a/lib/mesa/src/mapi/glapi/glapi_priv.h +++ b/lib/mesa/src/mapi/glapi/glapi_priv.h @@ -27,25 +27,12 @@ #define _GLAPI_PRIV_H -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#include "glapi/mesa.h" -#else /* HAVE_DIX_CONFIG_H */ #define GL_GLEXT_PROTOTYPES #include "GL/gl.h" #include "GL/glext.h" -#ifndef GL_OES_fixed_point -typedef int GLfixed; -#endif typedef int GLclampx; -#ifndef GL_OES_EGL_image -typedef void *GLeglImageOES; -#endif - -#endif /* HAVE_DIX_CONFIG_H */ - #include "glapi/glapi.h" diff --git a/lib/mesa/src/mapi/glapi/meson.build b/lib/mesa/src/mapi/glapi/meson.build new file mode 100644 index 000000000..048bee8a1 --- /dev/null +++ b/lib/mesa/src/mapi/glapi/meson.build @@ -0,0 +1,92 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +subdir('gen') + +inc_glapi = include_directories('.') + +static_glapi_files = [] +static_glapi_args = [] + +if ['apple', 'windows'].contains(with_dri_platform) + static_glapi_files += [glapi_gentable_c, glapitable_h] +endif + +if with_shared_glapi + static_glapi_files += files( + '../entry.c', + '../entry.h', + '../entry_x86-64_tls.h', + '../entry_x86_tls.h', + '../entry_x86_tsd.h', + '../entry_ppc64le_tls.h', + '../entry_ppc64le_tsd.h', + '../mapi_tmp.h', + ) + static_glapi_files += glapi_mapi_tmp_h + static_glapi_args += [ + '-DMAPI_MODE_BRIDGE', + '-DMAPI_ABI_HEADER="@0@"'.format(glapi_mapi_tmp_h.full_path()), + ] +else + static_glapi_args += '-DMAPI_MODE_UTIL' + static_glapi_files += files( + 'glapi_dispatch.c', + 'glapi_entrypoint.c', + 'glapi_getproc.c', + 'glapi_nop.c', + 'glapi.c', + 'glapi.h', + 'glapi_priv.h', + ) + static_glapi_files += files_mapi_util + static_glapi_files += [ + glapitable_h, glapi_mapi_tmp_h, glprocs_h, glapitemp_h, + ] + if with_asm_arch == 'x86' + static_glapi_files += glapi_x86_s + elif with_asm_arch == 'x86_64' + static_glapi_files += glapi_x86_64_s + elif with_asm_arch == 'sparc' + static_glapi_files += glapi_sparc_s + endif +endif + +libglapi_static = static_library( + 'glapi_static', + static_glapi_files, + include_directories : [inc_mesa, inc_include, inc_src, inc_mapi], + c_args : [c_msvc_compat_args, static_glapi_args], + dependencies : [dep_thread, dep_selinux], + build_by_default : false, +) + +if with_any_opengl and not with_shared_glapi and with_tests + test( + 'glapi_static_check_table', + executable( + 'glapi_static_check_table', + ['tests/check_table.cpp', glapitable_h], + include_directories : [inc_include, inc_src, inc_mesa, inc_mapi], + link_with : [libglapi_static], + dependencies : [idep_gtest, dep_thread], + ) + ) +endif diff --git a/lib/mesa/src/mapi/glapi/tests/check_table.cpp b/lib/mesa/src/mapi/glapi/tests/check_table.cpp index f23f00be5..761f2a24e 100644 --- a/lib/mesa/src/mapi/glapi/tests/check_table.cpp +++ b/lib/mesa/src/mapi/glapi/tests/check_table.cpp @@ -22,10 +22,10 @@ */ #include <gtest/gtest.h> -#include "../mesa/main/glheader.h" +#include "main/glheader.h" #include "glapi/glapi.h" -#include "glapi/glapitable.h" +#include "glapitable.h" struct name_offset { const char *name; @@ -1260,7 +1260,6 @@ const struct name_offset known_dispatch[] = { { "glTextureStorage1DEXT", _O(TextureStorage1DEXT) }, { "glTextureStorage2DEXT", _O(TextureStorage2DEXT) }, { "glTextureStorage3DEXT", _O(TextureStorage3DEXT) }, - { "glPolygonOffsetEXT", _O(PolygonOffsetEXT) }, { "glSampleMaskSGIS", _O(SampleMaskSGIS) }, { "glSamplePatternSGIS", _O(SamplePatternSGIS) }, { "glColorPointerEXT", _O(ColorPointerEXT) }, diff --git a/lib/mesa/src/mapi/meson.build b/lib/mesa/src/mapi/meson.build new file mode 100644 index 000000000..798586bfb --- /dev/null +++ b/lib/mesa/src/mapi/meson.build @@ -0,0 +1,39 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +files_mapi_util = files( + 'u_current.c', + 'u_current.h', + 'u_execmem.c', + 'u_execmem.h', +) + +mapi_abi_py = files('mapi_abi.py') + +subdir('glapi') +if with_shared_glapi + subdir('shared-glapi') +endif +if with_gles1 + subdir('es1api') +endif +if with_gles2 + subdir('es2api') +endif diff --git a/lib/mesa/src/mapi/shared-glapi/meson.build b/lib/mesa/src/mapi/shared-glapi/meson.build new file mode 100644 index 000000000..3f041471f --- /dev/null +++ b/lib/mesa/src/mapi/shared-glapi/meson.build @@ -0,0 +1,65 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +files_mapi_glapi = files( + '../entry.c', + '../mapi_glapi.c', + '../stub.c', + '../stub.h', + '../table.c', + '../table.h', +) + +shared_glapi_mapi_tmp_h = custom_target( + 'shared_glapi_mapi_tmp.h', + input : [mapi_abi_py, gl_and_es_api_files], + output : 'glapi_mapi_tmp.h', + command : [prog_python, '@INPUT0@', '--printer', 'shared-glapi', '@INPUT1@'], + depend_files : api_xml_files, + capture : true, +) + +libglapi = shared_library( + 'glapi', + [files_mapi_glapi, files_mapi_util, shared_glapi_mapi_tmp_h], + c_args : [ + c_msvc_compat_args, c_vis_args, '-DMAPI_MODE_GLAPI', + '-DMAPI_ABI_HEADER="@0@"'.format(shared_glapi_mapi_tmp_h.full_path()), + ], + link_args : [ld_args_gc_sections], + include_directories : [inc_src, inc_include, inc_mapi], + dependencies : [dep_thread, dep_selinux], + version : '0.0.0', + install : true, +) + +if with_any_opengl and with_tests + test( + 'shared-glapi-test', + executable( + ['shared-glapi-test', glapitable_h], + 'tests/check_table.cpp', + cpp_args : [cpp_msvc_compat_args], + include_directories : [inc_src, inc_include, inc_mapi], + link_with : [libglapi], + dependencies : [dep_thread, idep_gtest], + ) + ) +endif diff --git a/lib/mesa/src/mesa/drivers/common/meta_generate_mipmap.c b/lib/mesa/src/mesa/drivers/common/meta_generate_mipmap.c index 55093e955..99d093169 100644 --- a/lib/mesa/src/mesa/drivers/common/meta_generate_mipmap.c +++ b/lib/mesa/src/mesa/drivers/common/meta_generate_mipmap.c @@ -201,10 +201,10 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, /* We may have been called from glGenerateTextureMipmap with CurrentUnit * still set to 0, so we don't know when we can skip binding the texture. - * Assume that _mesa_BindTexture will be fast if we're rebinding the same + * Assume that _mesa_bind_texture will be fast if we're rebinding the same * texture. */ - _mesa_BindTexture(target, texObj->Name); + _mesa_bind_texture(ctx, target, texObj); if (mipmap->samp_obj == NULL) { mipmap->samp_obj = ctx->Driver.NewSamplerObject(ctx, 0xDEADBEEF); diff --git a/lib/mesa/src/mesa/drivers/dri/common/meson.build b/lib/mesa/src/mesa/drivers/dri/common/meson.build new file mode 100644 index 000000000..d9a9abdfb --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/common/meson.build @@ -0,0 +1,39 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +inc_dri_common = include_directories('.') + +libdricommon = static_library( + 'dricommon', + ['utils.c', 'utils.h', 'dri_util.c', 'dri_util.h', xmlpool_options_h], + include_directories : [inc_common, inc_util], + c_args : c_vis_args, + dependencies : dep_libdrm, + build_by_default : false, +) + +libmegadriver_stub = static_library( + 'megadriver_stub', + 'megadriver_stub.c', + include_directories : inc_common, + c_args : c_vis_args, + dependencies : dep_libdrm, + build_by_default : false, +) diff --git a/lib/mesa/src/mesa/drivers/dri/common/utils.c b/lib/mesa/src/mesa/drivers/dri/common/utils.c index e944754a4..5a66bcf8e 100644 --- a/lib/mesa/src/mesa/drivers/dri/common/utils.c +++ b/lib/mesa/src/mesa/drivers/dri/common/utils.c @@ -41,6 +41,20 @@ #include "utils.h" #include "dri_util.h" +/* WARNING: HACK: Local defines to avoid pulling glx.h. + * + * Any parts of this file that use the following defines are either partial or + * entirely broken wrt EGL. + * + * For example any getConfigAttrib() or indexConfigAttrib() query from EGL for + * SLOW or NON_CONFORMANT_CONFIG will not work as expected since the EGL tokens + * are different from the GLX ones. + */ +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DONT_CARE 0xFFFFFFFF + /** * Create the \c GL_RENDERER string for DRI drivers. * @@ -134,11 +148,12 @@ driGetRendererString( char * buffer, const char * hardware_name, * \param num_depth_stencil_bits Number of entries in both \c depth_bits and * \c stencil_bits. * \param db_modes Array of buffer swap modes. If an element has a - * value of \c GLX_NONE, then it represents a - * single-buffered mode. Other valid values are - * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and - * \c GLX_SWAP_UNDEFINED_OML. See the - * GLX_OML_swap_method extension spec for more details. + * value of \c __DRI_ATTRIB_SWAP_NONE, then it + * represents a single-buffered mode. Other valid + * values are \c __DRI_ATTRIB_SWAP_EXCHANGE, + * \c __DRI_ATTRIB_SWAP_COPY, and \c __DRI_ATTRIB_SWAP_UNDEFINED. + * They represent the respective GLX values as in + * the GLX_OML_swap_method extension spec. * \param num_db_modes Number of entries in \c db_modes. * \param msaa_samples Array of msaa sample count. 0 represents a visual * without a multisample buffer. @@ -147,7 +162,10 @@ driGetRendererString( char * buffer, const char * hardware_name, * \param color_depth_match Whether the color depth must match the zs depth * This forces 32-bit color to have 24-bit depth, and * 16-bit color to have 16-bit depth. - * + * \param mutable_render_buffer Enable __DRI_ATTRIB_MUTABLE_RENDER_BUFFER, + * which translates to + * EGL_MUTABLE_RENDER_BUFFER_BIT_KHR. + * * \returns * Pointer to any array of pointers to the \c __DRIconfig structures created * for the specified formats. If there is an error, \c NULL is returned. @@ -160,7 +178,8 @@ driCreateConfigs(mesa_format format, unsigned num_depth_stencil_bits, const GLenum * db_modes, unsigned num_db_modes, const uint8_t * msaa_samples, unsigned num_msaa_modes, - GLboolean enable_accum, GLboolean color_depth_match) + GLboolean enable_accum, GLboolean color_depth_match, + GLboolean mutable_render_buffer) { static const uint32_t masks_table[][4] = { /* MESA_FORMAT_B5G6R5_UNORM */ @@ -177,6 +196,10 @@ driCreateConfigs(mesa_format format, { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* MESA_FORMAT_R8G8B8X8_UNORM */ { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }, + /* MESA_FORMAT_R10G10B10X2_UNORM */ + { 0x000003FF, 0x000FFC00, 0x3FF00000, 0x00000000 }, + /* MESA_FORMAT_R10G10B10A2_UNORM */ + { 0x000003FF, 0x000FFC00, 0x3FF00000, 0xC0000000 }, }; const uint32_t * masks; @@ -204,6 +227,7 @@ driCreateConfigs(mesa_format format, masks = masks_table[2]; break; case MESA_FORMAT_R8G8B8A8_UNORM: + case MESA_FORMAT_R8G8B8A8_SRGB: masks = masks_table[5]; break; case MESA_FORMAT_R8G8B8X8_UNORM: @@ -215,6 +239,12 @@ driCreateConfigs(mesa_format format, case MESA_FORMAT_B10G10R10A2_UNORM: masks = masks_table[4]; break; + case MESA_FORMAT_R10G10B10X2_UNORM: + masks = masks_table[7]; + break; + case MESA_FORMAT_R10G10B10A2_UNORM: + masks = masks_table[8]; + break; default: fprintf(stderr, "[%s:%u] Unknown framebuffer type %s (%d).\n", __func__, __LINE__, @@ -314,6 +344,7 @@ driCreateConfigs(mesa_format format, modes->yInverted = GL_TRUE; modes->sRGBCapable = is_srgb; + modes->mutableRenderBuffer = mutable_render_buffer; } } } @@ -398,6 +429,7 @@ static const struct { unsigned int attrib, offset; } attribMap[] = { __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets), __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable), + __ATTRIB(__DRI_ATTRIB_MUTABLE_RENDER_BUFFER, mutableRenderBuffer), /* The struct field doesn't matter here, these are handled by the * switch in driGetConfigAttribIndex. We need them in the array diff --git a/lib/mesa/src/mesa/drivers/dri/common/utils.h b/lib/mesa/src/mesa/drivers/dri/common/utils.h index 7be0465c2..7c9719f9f 100644 --- a/lib/mesa/src/mesa/drivers/dri/common/utils.h +++ b/lib/mesa/src/mesa/drivers/dri/common/utils.h @@ -45,7 +45,8 @@ driCreateConfigs(mesa_format format, unsigned num_depth_stencil_bits, const GLenum * db_modes, unsigned num_db_modes, const uint8_t * msaa_samples, unsigned num_msaa_modes, - GLboolean enable_accum, GLboolean color_depth_match); + GLboolean enable_accum, GLboolean color_depth_match, + GLboolean mutable_render_buffer); __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b); diff --git a/lib/mesa/src/mesa/drivers/dri/i915/i830_context.c b/lib/mesa/src/mesa/drivers/dri/i915/i830_context.c index 299e54d50..ca0048306 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/i830_context.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/i830_context.c @@ -27,6 +27,7 @@ #include "i830_context.h" #include "main/api_exec.h" +#include "main/extensions.h" #include "main/imports.h" #include "main/version.h" #include "main/vtxfmt.h" @@ -124,6 +125,7 @@ i830CreateContext(int api, _tnl_allow_vertex_fog(ctx, 1); _tnl_allow_pixel_fog(ctx, 0); + _mesa_override_extensions(ctx); _mesa_compute_version(ctx); _mesa_initialize_dispatch_tables(ctx); diff --git a/lib/mesa/src/mesa/drivers/dri/i915/i830_state.c b/lib/mesa/src/mesa/drivers/dri/i915/i830_state.c index 7ce5ef7e4..c8f48fbfa 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/i830_state.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/i830_state.c @@ -573,16 +573,16 @@ i830Scissor(struct gl_context * ctx) } static void -i830LogicOp(struct gl_context * ctx, GLenum opcode) +i830LogicOp(struct gl_context * ctx, enum gl_logicop_mode opcode) { struct i830_context *i830 = i830_context(ctx); - int tmp = intel_translate_logic_op(opcode); DBG("%s\n", __func__); - + + assert((unsigned)opcode <= 15); I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK; - i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); + i830->state.Ctx[I830_CTXREG_STATE4] |= opcode; } diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_blit.c b/lib/mesa/src/mesa/drivers/dri/i915/intel_blit.c index 279db28b7..98cffaf24 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_blit.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_blit.c @@ -48,27 +48,9 @@ intel_miptree_set_alpha_to_one(struct intel_context *intel, struct intel_mipmap_tree *mt, int x, int y, int width, int height); -static GLuint translate_raster_op(GLenum logicop) +static GLuint translate_raster_op(enum gl_logicop_mode logicop) { - switch(logicop) { - case GL_CLEAR: return 0x00; - case GL_AND: return 0x88; - case GL_AND_REVERSE: return 0x44; - case GL_COPY: return 0xCC; - case GL_AND_INVERTED: return 0x22; - case GL_NOOP: return 0xAA; - case GL_XOR: return 0x66; - case GL_OR: return 0xEE; - case GL_NOR: return 0x11; - case GL_EQUIV: return 0x99; - case GL_INVERT: return 0x55; - case GL_OR_REVERSE: return 0xDD; - case GL_COPY_INVERTED: return 0x33; - case GL_OR_INVERTED: return 0xBB; - case GL_NAND: return 0x77; - case GL_SET: return 0xFF; - default: return 0; - } + return logicop | (logicop << 4); } static uint32_t @@ -90,144 +72,23 @@ br13_for_cpp(int cpp) } } -/** - * Implements a rectangular block transfer (blit) of pixels between two - * miptrees. - * - * Our blitter can operate on 1, 2, or 4-byte-per-pixel data, with generous, - * but limited, pitches and sizes allowed. - * - * The src/dst coordinates are relative to the given level/slice of the - * miptree. - * - * If @src_flip or @dst_flip is set, then the rectangle within that miptree - * will be inverted (including scanline order) when copying. This is common - * in GL when copying between window system and user-created - * renderbuffers/textures. - */ -bool -intel_miptree_blit(struct intel_context *intel, - struct intel_mipmap_tree *src_mt, - int src_level, int src_slice, - uint32_t src_x, uint32_t src_y, bool src_flip, - struct intel_mipmap_tree *dst_mt, - int dst_level, int dst_slice, - uint32_t dst_x, uint32_t dst_y, bool dst_flip, - uint32_t width, uint32_t height, - GLenum logicop) -{ - /* No sRGB decode or encode is done by the hardware blitter, which is - * consistent with what we want in the callers (glCopyTexSubImage(), - * glBlitFramebuffer(), texture validation, etc.). - */ - mesa_format src_format = _mesa_get_srgb_format_linear(src_mt->format); - mesa_format dst_format = _mesa_get_srgb_format_linear(dst_mt->format); - - /* The blitter doesn't support doing any format conversions. We do also - * support blitting ARGB8888 to XRGB8888 (trivial, the values dropped into - * the X channel don't matter), and XRGB8888 to ARGB8888 by setting the A - * channel to 1.0 at the end. - */ - if (src_format != dst_format && - ((src_format != MESA_FORMAT_B8G8R8A8_UNORM && - src_format != MESA_FORMAT_B8G8R8X8_UNORM) || - (dst_format != MESA_FORMAT_B8G8R8A8_UNORM && - dst_format != MESA_FORMAT_B8G8R8X8_UNORM))) { - perf_debug("%s: Can't use hardware blitter from %s to %s, " - "falling back.\n", __func__, - _mesa_get_format_name(src_format), - _mesa_get_format_name(dst_format)); - return false; - } - - /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics - * Data Size Limitations): - * - * The BLT engine is capable of transferring very large quantities of - * graphics data. Any graphics data read from and written to the - * destination is permitted to represent a number of pixels that - * occupies up to 65,536 scan lines and up to 32,768 bytes per scan line - * at the destination. The maximum number of pixels that may be - * represented per scan line’s worth of graphics data depends on the - * color depth. - * - * Furthermore, intelEmitCopyBlit (which is called below) uses a signed - * 16-bit integer to represent buffer pitch, so it can only handle buffer - * pitches < 32k. - * - * As a result of these two limitations, we can only use the blitter to do - * this copy when the region's pitch is less than 32k. - */ - if (src_mt->region->pitch > 32768 || - dst_mt->region->pitch > 32768) { - perf_debug("Falling back due to >32k pitch\n"); - return false; - } - - if (src_flip) - src_y = src_mt->level[src_level].height - src_y - height; - - if (dst_flip) - dst_y = dst_mt->level[dst_level].height - dst_y - height; - - int src_pitch = src_mt->region->pitch; - if (src_flip != dst_flip) - src_pitch = -src_pitch; - - uint32_t src_image_x, src_image_y; - intel_miptree_get_image_offset(src_mt, src_level, src_slice, - &src_image_x, &src_image_y); - src_x += src_image_x; - src_y += src_image_y; - - uint32_t dst_image_x, dst_image_y; - intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice, - &dst_image_x, &dst_image_y); - dst_x += dst_image_x; - dst_y += dst_image_y; - - if (!intelEmitCopyBlit(intel, - src_mt->cpp, - src_pitch, - src_mt->region->bo, src_mt->offset, - src_mt->region->tiling, - dst_mt->region->pitch, - dst_mt->region->bo, dst_mt->offset, - dst_mt->region->tiling, - src_x, src_y, - dst_x, dst_y, - width, height, - logicop)) { - return false; - } - - if (src_mt->format == MESA_FORMAT_B8G8R8X8_UNORM && - dst_mt->format == MESA_FORMAT_B8G8R8A8_UNORM) { - intel_miptree_set_alpha_to_one(intel, dst_mt, - dst_x, dst_y, - width, height); - } - - return true; -} - /* Copy BitBlt */ -bool -intelEmitCopyBlit(struct intel_context *intel, - GLuint cpp, - GLshort src_pitch, - drm_intel_bo *src_buffer, - GLuint src_offset, - uint32_t src_tiling, - GLshort dst_pitch, - drm_intel_bo *dst_buffer, - GLuint dst_offset, - uint32_t dst_tiling, - GLshort src_x, GLshort src_y, - GLshort dst_x, GLshort dst_y, - GLshort w, GLshort h, - GLenum logic_op) +static bool +emit_copy_blit(struct intel_context *intel, + GLuint cpp, + GLshort src_pitch, + drm_intel_bo *src_buffer, + GLuint src_offset, + uint32_t src_tiling, + GLshort dst_pitch, + drm_intel_bo *dst_buffer, + GLuint dst_offset, + uint32_t dst_tiling, + GLshort src_x, GLshort src_y, + GLshort dst_x, GLshort dst_y, + GLshort w, GLshort h, + enum gl_logicop_mode logic_op) { GLuint CMD, BR13, pass = 0; int dst_y2 = dst_y + h; @@ -338,6 +199,126 @@ intelEmitCopyBlit(struct intel_context *intel, return true; } +/** + * Implements a rectangular block transfer (blit) of pixels between two + * miptrees. + * + * Our blitter can operate on 1, 2, or 4-byte-per-pixel data, with generous, + * but limited, pitches and sizes allowed. + * + * The src/dst coordinates are relative to the given level/slice of the + * miptree. + * + * If @src_flip or @dst_flip is set, then the rectangle within that miptree + * will be inverted (including scanline order) when copying. This is common + * in GL when copying between window system and user-created + * renderbuffers/textures. + */ +bool +intel_miptree_blit(struct intel_context *intel, + struct intel_mipmap_tree *src_mt, + int src_level, int src_slice, + uint32_t src_x, uint32_t src_y, bool src_flip, + struct intel_mipmap_tree *dst_mt, + int dst_level, int dst_slice, + uint32_t dst_x, uint32_t dst_y, bool dst_flip, + uint32_t width, uint32_t height, + enum gl_logicop_mode logicop) +{ + /* No sRGB decode or encode is done by the hardware blitter, which is + * consistent with what we want in the callers (glCopyTexSubImage(), + * glBlitFramebuffer(), texture validation, etc.). + */ + mesa_format src_format = _mesa_get_srgb_format_linear(src_mt->format); + mesa_format dst_format = _mesa_get_srgb_format_linear(dst_mt->format); + + /* The blitter doesn't support doing any format conversions. We do also + * support blitting ARGB8888 to XRGB8888 (trivial, the values dropped into + * the X channel don't matter), and XRGB8888 to ARGB8888 by setting the A + * channel to 1.0 at the end. + */ + if (src_format != dst_format && + ((src_format != MESA_FORMAT_B8G8R8A8_UNORM && + src_format != MESA_FORMAT_B8G8R8X8_UNORM) || + (dst_format != MESA_FORMAT_B8G8R8A8_UNORM && + dst_format != MESA_FORMAT_B8G8R8X8_UNORM))) { + perf_debug("%s: Can't use hardware blitter from %s to %s, " + "falling back.\n", __func__, + _mesa_get_format_name(src_format), + _mesa_get_format_name(dst_format)); + return false; + } + + /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics + * Data Size Limitations): + * + * The BLT engine is capable of transferring very large quantities of + * graphics data. Any graphics data read from and written to the + * destination is permitted to represent a number of pixels that + * occupies up to 65,536 scan lines and up to 32,768 bytes per scan line + * at the destination. The maximum number of pixels that may be + * represented per scan line’s worth of graphics data depends on the + * color depth. + * + * Furthermore, emit_copy_blit (which is called below) uses a signed + * 16-bit integer to represent buffer pitch, so it can only handle buffer + * pitches < 32k. + * + * As a result of these two limitations, we can only use the blitter to do + * this copy when the region's pitch is less than 32k. + */ + if (src_mt->region->pitch > 32768 || + dst_mt->region->pitch > 32768) { + perf_debug("Falling back due to >32k pitch\n"); + return false; + } + + if (src_flip) + src_y = src_mt->level[src_level].height - src_y - height; + + if (dst_flip) + dst_y = dst_mt->level[dst_level].height - dst_y - height; + + int src_pitch = src_mt->region->pitch; + if (src_flip != dst_flip) + src_pitch = -src_pitch; + + uint32_t src_image_x, src_image_y; + intel_miptree_get_image_offset(src_mt, src_level, src_slice, + &src_image_x, &src_image_y); + src_x += src_image_x; + src_y += src_image_y; + + uint32_t dst_image_x, dst_image_y; + intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice, + &dst_image_x, &dst_image_y); + dst_x += dst_image_x; + dst_y += dst_image_y; + + if (!emit_copy_blit(intel, + src_mt->cpp, + src_pitch, + src_mt->region->bo, src_mt->offset, + src_mt->region->tiling, + dst_mt->region->pitch, + dst_mt->region->bo, dst_mt->offset, + dst_mt->region->tiling, + src_x, src_y, + dst_x, dst_y, + width, height, + logicop)) { + return false; + } + + if (src_mt->format == MESA_FORMAT_B8G8R8X8_UNORM && + dst_mt->format == MESA_FORMAT_B8G8R8A8_UNORM) { + intel_miptree_set_alpha_to_one(intel, dst_mt, + dst_x, dst_y, + width, height); + } + + return true; +} /** * Use blitting to clear the renderbuffers named by 'flags'. @@ -523,7 +504,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, uint32_t dst_tiling, GLshort x, GLshort y, GLshort w, GLshort h, - GLenum logic_op) + enum gl_logicop_mode logic_op) { int dwords = ALIGN(src_size, 8) / 4; uint32_t opcode, br13, blit_cmd; @@ -535,7 +516,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, return false; } - assert((logic_op >= GL_CLEAR) && (logic_op <= (GL_CLEAR + 0x0f))); + assert((unsigned)logic_op <= 0x0f); assert(dst_pitch > 0); if (w < 0 || h < 0) @@ -607,13 +588,13 @@ intel_emit_linear_blit(struct intel_context *intel, */ pitch = ROUND_DOWN_TO(MIN2(size, (1 << 15) - 1), 4); height = (pitch == 0) ? 1 : size / pitch; - ok = intelEmitCopyBlit(intel, 1, - pitch, src_bo, src_offset, I915_TILING_NONE, - pitch, dst_bo, dst_offset, I915_TILING_NONE, - 0, 0, /* src x/y */ - 0, 0, /* dst x/y */ - pitch, height, /* w, h */ - GL_COPY); + ok = emit_copy_blit(intel, 1, + pitch, src_bo, src_offset, I915_TILING_NONE, + pitch, dst_bo, dst_offset, I915_TILING_NONE, + 0, 0, /* src x/y */ + 0, 0, /* dst x/y */ + pitch, height, /* w, h */ + COLOR_LOGICOP_COPY); if (!ok) _mesa_problem(ctx, "Failed to linear blit %dx%d\n", pitch, height); @@ -623,13 +604,13 @@ intel_emit_linear_blit(struct intel_context *intel, assert (size < (1 << 15)); pitch = ALIGN(size, 4); if (size != 0) { - ok = intelEmitCopyBlit(intel, 1, - pitch, src_bo, src_offset, I915_TILING_NONE, - pitch, dst_bo, dst_offset, I915_TILING_NONE, - 0, 0, /* src x/y */ - 0, 0, /* dst x/y */ - size, 1, /* w, h */ - GL_COPY); + ok = emit_copy_blit(intel, 1, + pitch, src_bo, src_offset, I915_TILING_NONE, + pitch, dst_bo, dst_offset, I915_TILING_NONE, + 0, 0, /* src x/y */ + 0, 0, /* dst x/y */ + size, 1, /* w, h */ + COLOR_LOGICOP_COPY); if (!ok) _mesa_problem(ctx, "Failed to linear blit %dx%d\n", size, 1); } diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_blit.h b/lib/mesa/src/mesa/drivers/dri/i915/intel_blit.h index 1e76126aa..61de411b3 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_blit.h +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_blit.h @@ -35,22 +35,6 @@ extern void intelCopyBuffer(const __DRIdrawable * dpriv, extern GLbitfield intelClearWithBlit(struct gl_context * ctx, GLbitfield mask); -bool -intelEmitCopyBlit(struct intel_context *intel, - GLuint cpp, - GLshort src_pitch, - drm_intel_bo *src_buffer, - GLuint src_offset, - uint32_t src_tiling, - GLshort dst_pitch, - drm_intel_bo *dst_buffer, - GLuint dst_offset, - uint32_t dst_tiling, - GLshort srcx, GLshort srcy, - GLshort dstx, GLshort dsty, - GLshort w, GLshort h, - GLenum logicop ); - bool intel_miptree_blit(struct intel_context *intel, struct intel_mipmap_tree *src_mt, int src_level, int src_slice, @@ -59,7 +43,7 @@ bool intel_miptree_blit(struct intel_context *intel, int dst_level, int dst_slice, uint32_t dst_x, uint32_t dst_y, bool dst_flip, uint32_t width, uint32_t height, - GLenum logicop); + enum gl_logicop_mode logicop); bool intelEmitImmediateColorExpandBlit(struct intel_context *intel, @@ -72,7 +56,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, uint32_t dst_tiling, GLshort x, GLshort y, GLshort w, GLshort h, - GLenum logic_op); + enum gl_logicop_mode logic_op); void intel_emit_linear_blit(struct intel_context *intel, drm_intel_bo *dst_bo, unsigned int dst_offset, diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_buffers.c b/lib/mesa/src/mesa/drivers/dri/i915/intel_buffers.c index 386e03244..83d59edb6 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_buffers.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_buffers.c @@ -53,7 +53,7 @@ intel_check_front_buffer_rendering(struct intel_context *intel) } static void -intelDrawBuffer(struct gl_context * ctx, GLenum mode) +intelDrawBuffer(struct gl_context * ctx) { if (_mesa_is_front_buffer_drawing(ctx->DrawBuffer)) { struct intel_context *const intel = intel_context(ctx); diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_fbo.c b/lib/mesa/src/mesa/drivers/dri/i915/intel_fbo.c index 8750c601b..78e2c1e66 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_fbo.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_fbo.c @@ -86,7 +86,8 @@ intel_map_renderbuffer(struct gl_context *ctx, GLuint x, GLuint y, GLuint w, GLuint h, GLbitfield mode, GLubyte **out_map, - GLint *out_stride) + GLint *out_stride, + bool flip_y) { struct intel_context *intel = intel_context(ctx); struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb; @@ -94,6 +95,9 @@ intel_map_renderbuffer(struct gl_context *ctx, void *map; int stride; + /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */ + assert((rb->Name == 0) == flip_y); + if (srb->Buffer) { /* this is a malloc'd renderbuffer (accum buffer), not an irb */ GLint bpp = _mesa_get_format_bytes(rb->Format); @@ -287,7 +291,7 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, * intel_process_dri2_buffer(). */ static GLboolean -intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, +intel_alloc_window_storage(UNUSED struct gl_context *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { assert(rb->Name == 0); @@ -300,8 +304,10 @@ intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, /** Dummy function for gl_renderbuffer::AllocStorage() */ static GLboolean -intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, GLuint width, GLuint height) +intel_nop_alloc_storage(UNUSED struct gl_context *ctx, + UNUSED struct gl_renderbuffer *rb, + UNUSED GLenum internalFormat, + UNUSED GLuint width, UNUSED GLuint height) { _mesa_problem(ctx, "intel_op_alloc_storage should never be called."); return false; @@ -393,7 +399,8 @@ intel_new_renderbuffer(struct gl_context * ctx, GLuint name) */ static void intel_bind_framebuffer(struct gl_context * ctx, GLenum target, - struct gl_framebuffer *fb, struct gl_framebuffer *fbread) + UNUSED struct gl_framebuffer *fb, + UNUSED struct gl_framebuffer *fbread) { if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { intel_draw_buffer(ctx); @@ -419,8 +426,7 @@ intel_framebuffer_renderbuffer(struct gl_context * ctx, } static bool -intel_renderbuffer_update_wrapper(struct intel_context *intel, - struct intel_renderbuffer *irb, +intel_renderbuffer_update_wrapper(struct intel_renderbuffer *irb, struct gl_texture_image *image, uint32_t layer) { @@ -468,7 +474,6 @@ intel_render_texture(struct gl_context * ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att) { - struct intel_context *intel = intel_context(ctx); struct gl_renderbuffer *rb = att->Renderbuffer; struct intel_renderbuffer *irb = intel_renderbuffer(rb); struct gl_texture_image *image = rb->TexImage; @@ -495,7 +500,7 @@ intel_render_texture(struct gl_context * ctx, intel_miptree_check_level_layer(mt, att->TextureLevel, layer); - if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) { + if (!intel_renderbuffer_update_wrapper(irb, image, layer)) { _swrast_render_texture(ctx, fb, att); return; } @@ -641,7 +646,7 @@ intel_blit_framebuffer_with_blitter(struct gl_context *ctx, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) + GLbitfield mask) { struct intel_context *intel = intel_context(ctx); @@ -714,7 +719,7 @@ intel_blit_framebuffer_with_blitter(struct gl_context *ctx, dst_irb->mt, dst_irb->mt_level, dst_irb->mt_layer, dstX0, dstY0, dst_rb->Name == 0, - dstX1 - dstX0, dstY1 - dstY0, GL_COPY)) { + dstX1 - dstX0, dstY1 - dstY0, COLOR_LOGICOP_COPY)) { perf_debug("glBlitFramebuffer(): unknown blit failure. " "Falling back to software rendering.\n"); return mask; @@ -739,7 +744,7 @@ intel_blit_framebuffer(struct gl_context *ctx, mask = intel_blit_framebuffer_with_blitter(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - mask, filter); + mask); if (mask == 0x0) return; diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_pixel_bitmap.c b/lib/mesa/src/mesa/drivers/dri/i915/intel_pixel_bitmap.c index a41b6929c..8dee0bea9 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_pixel_bitmap.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_pixel_bitmap.c @@ -262,8 +262,8 @@ do_blit_bitmap( struct gl_context *ctx, int h = MIN2(DY, height - py); int w = MIN2(DX, width - px); GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8; - GLenum logic_op = ctx->Color.ColorLogicOpEnabled ? - ctx->Color.LogicOp : GL_COPY; + const enum gl_logicop_mode logic_op = ctx->Color.ColorLogicOpEnabled ? + ctx->Color._LogicOp : COLOR_LOGICOP_COPY; assert(sz <= sizeof(stipple)); memset(stipple, 0, sz); diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_pixel_read.c b/lib/mesa/src/mesa/drivers/dri/i915/intel_pixel_read.c index e6fa8f2dc..3560963c8 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_pixel_read.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_pixel_read.c @@ -141,7 +141,7 @@ do_blit_readpixels(struct gl_context * ctx, x, y, _mesa_is_winsys_fbo(ctx->ReadBuffer), pbo_mt, 0, 0, 0, 0, dst_flip, - width, height, GL_COPY)) { + width, height, COLOR_LOGICOP_COPY)) { intel_miptree_release(&pbo_mt); return false; } diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_render.c b/lib/mesa/src/mesa/drivers/dri/i915/intel_render.c index c1603565c..a39528262 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_render.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_render.c @@ -62,6 +62,8 @@ #define HAVE_TRI_FANS 1 #define HAVE_POLYGONS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 #define HAVE_ELTS 0 static const uint32_t hw_prim[GL_POLYGON + 1] = { diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_screen.h b/lib/mesa/src/mesa/drivers/dri/i915/intel_screen.h index a22888b39..ac70d3655 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_screen.h +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_screen.h @@ -117,7 +117,6 @@ struct intel_screen #define intel_check_front_buffer_rendering old_intel_check_front_buffer_rendering #define intelInitBufferFuncs old_intelInitBufferFuncs #define intelClearWithBlit old_intelClearWithBlit -#define intelEmitCopyBlit old_intelEmitCopyBlit #define intelEmitImmediateColorExpandBlit old_intelEmitImmediateColorExpandBlit #define intel_emit_linear_blit old_intel_emit_linear_blit #define intel_miptree_blit old_intel_miptree_blit @@ -139,7 +138,6 @@ struct intel_screen #define get_time old_get_time #define intel_translate_blend_factor old_intel_translate_blend_factor #define intel_translate_compare_func old_intel_translate_compare_func -#define intel_translate_logic_op old_intel_translate_logic_op #define intel_translate_shadow_compare_func old_intel_translate_shadow_compare_func #define intel_translate_stencil_op old_intel_translate_stencil_op #define intel_init_syncobj_functions old_intel_init_syncobj_functions diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_state.c b/lib/mesa/src/mesa/drivers/dri/i915/intel_state.c index 3de9d50a4..4f47013dd 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_state.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_state.c @@ -151,44 +151,3 @@ intel_translate_blend_factor(GLenum factor) fprintf(stderr, "Unknown value in %s: %x\n", __func__, factor); return BLENDFACT_ZERO; } - -int -intel_translate_logic_op(GLenum opcode) -{ - switch (opcode) { - case GL_CLEAR: - return LOGICOP_CLEAR; - case GL_AND: - return LOGICOP_AND; - case GL_AND_REVERSE: - return LOGICOP_AND_RVRSE; - case GL_COPY: - return LOGICOP_COPY; - case GL_COPY_INVERTED: - return LOGICOP_COPY_INV; - case GL_AND_INVERTED: - return LOGICOP_AND_INV; - case GL_NOOP: - return LOGICOP_NOOP; - case GL_XOR: - return LOGICOP_XOR; - case GL_OR: - return LOGICOP_OR; - case GL_OR_INVERTED: - return LOGICOP_OR_INV; - case GL_NOR: - return LOGICOP_NOR; - case GL_EQUIV: - return LOGICOP_EQUIV; - case GL_INVERT: - return LOGICOP_INV; - case GL_OR_REVERSE: - return LOGICOP_OR_RVRSE; - case GL_NAND: - return LOGICOP_NAND; - case GL_SET: - return LOGICOP_SET; - default: - return LOGICOP_SET; - } -} diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_tex_copy.c b/lib/mesa/src/mesa/drivers/dri/i915/intel_tex_copy.c index a5d00af3b..4b087b616 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_tex_copy.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_tex_copy.c @@ -70,7 +70,7 @@ intel_copy_texsubimage(struct intel_context *intel, intelImage->mt, intelImage->base.Base.Level, intelImage->base.Base.Face + slice, dstx, dsty, false, - width, height, GL_COPY)) { + width, height, COLOR_LOGICOP_COPY)) { return false; } diff --git a/lib/mesa/src/mesa/drivers/dri/i915/intel_tex_subimage.c b/lib/mesa/src/mesa/drivers/dri/i915/intel_tex_subimage.c index 4083d696b..b372e114f 100644 --- a/lib/mesa/src/mesa/drivers/dri/i915/intel_tex_subimage.c +++ b/lib/mesa/src/mesa/drivers/dri/i915/intel_tex_subimage.c @@ -111,7 +111,7 @@ intel_blit_texsubimage(struct gl_context * ctx, 0, 0, false, intelImage->mt, texImage->Level, texImage->Face, xoffset, yoffset, false, - width, height, GL_COPY); + width, height, COLOR_LOGICOP_COPY); assert(ret); intel_miptree_release(&temp_mt); diff --git a/lib/mesa/src/mesa/drivers/dri/i915/meson.build b/lib/mesa/src/mesa/drivers/dri/i915/meson.build new file mode 100644 index 000000000..1971419a6 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/i915/meson.build @@ -0,0 +1,97 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +files_i915 = files( + 'i830_context.c', + 'i830_context.h', + 'i830_reg.h', + 'i830_state.c', + 'i830_texblend.c', + 'i830_texstate.c', + 'i830_vtbl.c', + 'i915_context.c', + 'i915_context.h', + 'i915_debug_fp.c', + 'i915_debug.h', + 'i915_fragprog.c', + 'i915_program.c', + 'i915_program.h', + 'i915_reg.h', + 'i915_state.c', + 'i915_tex_layout.c', + 'i915_texstate.c', + 'i915_vtbl.c', + 'intel_batchbuffer.c', + 'intel_batchbuffer.h', + 'intel_blit.c', + 'intel_blit.h', + 'intel_buffer_objects.c', + 'intel_buffer_objects.h', + 'intel_buffers.c', + 'intel_buffers.h', + 'intel_chipset.h', + 'intel_clear.c', + 'intel_clear.h', + 'intel_context.c', + 'intel_context.h', + 'intel_extensions.c', + 'intel_extensions.h', + 'intel_fbo.c', + 'intel_fbo.h', + 'intel_mipmap_tree.c', + 'intel_mipmap_tree.h', + 'intel_pixel_bitmap.c', + 'intel_pixel.c', + 'intel_pixel_copy.c', + 'intel_pixel_draw.c', + 'intel_pixel.h', + 'intel_pixel_read.c', + 'intel_reg.h', + 'intel_regions.c', + 'intel_regions.h', + 'intel_render.c', + 'intel_screen.c', + 'intel_screen.h', + 'intel_state.c', + 'intel_syncobj.c', + 'intel_tex.c', + 'intel_tex_copy.c', + 'intel_tex.h', + 'intel_tex_image.c', + 'intel_tex_layout.c', + 'intel_tex_layout.h', + 'intel_tex_obj.h', + 'intel_tex_subimage.c', + 'intel_tex_validate.c', + 'intel_tris.c', + 'intel_tris.h', +) + +libi915 = static_library( + 'i915', + [files_i915, xmlpool_options_h], + include_directories : [inc_common, inc_dri_common, inc_util], + c_args : [c_vis_args, no_override_init_args], + cpp_args : [cpp_vis_args], + dependencies : [dep_libdrm, dep_libdrm_intel], +) + +dri_drivers += libi915 +dri_link += 'i915_dri.so' diff --git a/lib/mesa/src/mesa/drivers/dri/i965/brw_disk_cache.c b/lib/mesa/src/mesa/drivers/dri/i965/brw_disk_cache.c new file mode 100644 index 000000000..65fcab24b --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/i965/brw_disk_cache.c @@ -0,0 +1,403 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "compiler/blob.h" +#include "compiler/glsl/ir_uniform.h" +#include "compiler/glsl/shader_cache.h" +#include "main/mtypes.h" +#include "util/build_id.h" +#include "util/debug.h" +#include "util/disk_cache.h" +#include "util/macros.h" +#include "util/mesa-sha1.h" + +#include "compiler/brw_eu.h" +#include "common/gen_debug.h" + +#include "brw_context.h" +#include "brw_program.h" +#include "brw_cs.h" +#include "brw_gs.h" +#include "brw_state.h" +#include "brw_vs.h" +#include "brw_wm.h" + +static bool +debug_enabled_for_stage(gl_shader_stage stage) +{ + static const uint64_t stage_debug_flags[] = { + DEBUG_VS, DEBUG_TCS, DEBUG_TES, DEBUG_GS, DEBUG_WM, DEBUG_CS, + }; + assert((int)stage >= 0 && stage < ARRAY_SIZE(stage_debug_flags)); + return (INTEL_DEBUG & stage_debug_flags[stage]) != 0; +} + +static void +gen_shader_sha1(struct gl_program *prog, gl_shader_stage stage, + void *key, unsigned char *out_sha1) +{ + char sha1_buf[41]; + unsigned char sha1[20]; + char manifest[256]; + int offset = 0; + + _mesa_sha1_format(sha1_buf, prog->sh.data->sha1); + offset += snprintf(manifest, sizeof(manifest), "program: %s\n", sha1_buf); + + _mesa_sha1_compute(key, brw_prog_key_size(stage), sha1); + _mesa_sha1_format(sha1_buf, sha1); + offset += snprintf(manifest + offset, sizeof(manifest) - offset, + "%s_key: %s\n", _mesa_shader_stage_to_abbrev(stage), + sha1_buf); + + _mesa_sha1_compute(manifest, strlen(manifest), out_sha1); +} + +static bool +read_blob_program_data(struct blob_reader *binary, struct gl_program *prog, + gl_shader_stage stage, const uint8_t **program, + struct brw_stage_prog_data *prog_data) +{ + return + brw_read_blob_program_data(binary, prog, stage, program, prog_data) && + (binary->current == binary->end); +} + +static bool +read_and_upload(struct brw_context *brw, struct disk_cache *cache, + struct gl_program *prog, gl_shader_stage stage) +{ + unsigned char binary_sha1[20]; + + union brw_any_prog_key prog_key; + + switch (stage) { + case MESA_SHADER_VERTEX: + brw_vs_populate_key(brw, &prog_key.vs); + break; + case MESA_SHADER_TESS_CTRL: + brw_tcs_populate_key(brw, &prog_key.tcs); + break; + case MESA_SHADER_TESS_EVAL: + brw_tes_populate_key(brw, &prog_key.tes); + break; + case MESA_SHADER_GEOMETRY: + brw_gs_populate_key(brw, &prog_key.gs); + break; + case MESA_SHADER_FRAGMENT: + brw_wm_populate_key(brw, &prog_key.wm); + break; + case MESA_SHADER_COMPUTE: + brw_cs_populate_key(brw, &prog_key.cs); + break; + default: + unreachable("Unsupported stage!"); + } + + /* We don't care what instance of the program it is for the disk cache hash + * lookup, so set the id to 0 for the sha1 hashing. program_string_id will + * be set below. + */ + brw_prog_key_set_id(&prog_key, stage, 0); + + gen_shader_sha1(prog, stage, &prog_key, binary_sha1); + + size_t buffer_size; + uint8_t *buffer = disk_cache_get(cache, binary_sha1, &buffer_size); + if (buffer == NULL) { + if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) { + char sha1_buf[41]; + _mesa_sha1_format(sha1_buf, binary_sha1); + fprintf(stderr, "No cached %s binary found for: %s\n", + _mesa_shader_stage_to_abbrev(stage), sha1_buf); + } + return false; + } + + if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) { + char sha1_buf[41]; + _mesa_sha1_format(sha1_buf, binary_sha1); + fprintf(stderr, "attempting to populate bo cache with binary: %s\n", + sha1_buf); + } + + struct blob_reader binary; + blob_reader_init(&binary, buffer, buffer_size); + + const uint8_t *program; + struct brw_stage_prog_data *prog_data = + ralloc_size(NULL, sizeof(union brw_any_prog_data)); + if (!read_blob_program_data(&binary, prog, stage, &program, prog_data)) { + /* Something very bad has gone wrong discard the item from the cache and + * rebuild from source. + */ + if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) { + fprintf(stderr, "Error reading program from cache (invalid i965 " + "cache item)\n"); + } + + disk_cache_remove(cache, binary_sha1); + ralloc_free(prog_data); + free(buffer); + return false; + } + + enum brw_cache_id cache_id; + struct brw_stage_state *stage_state; + + switch (stage) { + case MESA_SHADER_VERTEX: + cache_id = BRW_CACHE_VS_PROG; + stage_state = &brw->vs.base; + break; + case MESA_SHADER_TESS_CTRL: + cache_id = BRW_CACHE_TCS_PROG; + stage_state = &brw->tcs.base; + break; + case MESA_SHADER_TESS_EVAL: + cache_id = BRW_CACHE_TES_PROG; + stage_state = &brw->tes.base; + break; + case MESA_SHADER_GEOMETRY: + cache_id = BRW_CACHE_GS_PROG; + stage_state = &brw->gs.base; + break; + case MESA_SHADER_FRAGMENT: + cache_id = BRW_CACHE_FS_PROG; + stage_state = &brw->wm.base; + break; + case MESA_SHADER_COMPUTE: + cache_id = BRW_CACHE_CS_PROG; + stage_state = &brw->cs.base; + break; + default: + unreachable("Unsupported stage!"); + } + + brw_prog_key_set_id(&prog_key, stage, brw_program(prog)->id); + + brw_alloc_stage_scratch(brw, stage_state, prog_data->total_scratch); + + if (unlikely(debug_enabled_for_stage(stage))) { + fprintf(stderr, "NIR for %s program %d loaded from disk shader cache:\n", + _mesa_shader_stage_to_abbrev(stage), brw_program(prog)->id); + brw_program_deserialize_driver_blob(&brw->ctx, prog, stage); + nir_shader *nir = prog->nir; + nir_print_shader(nir, stderr); + fprintf(stderr, "Native code for %s %s shader %s from disk cache:\n", + nir->info.label ? nir->info.label : "unnamed", + _mesa_shader_stage_to_string(nir->info.stage), nir->info.name); + brw_disassemble(&brw->screen->devinfo, program, 0, + prog_data->program_size, stderr); + } + + brw_upload_cache(&brw->cache, cache_id, &prog_key, brw_prog_key_size(stage), + program, prog_data->program_size, prog_data, + brw_prog_data_size(stage), &stage_state->prog_offset, + &stage_state->prog_data); + + prog->program_written_to_cache = true; + + ralloc_free(prog_data); + free(buffer); + + return true; +} + +bool +brw_disk_cache_upload_program(struct brw_context *brw, gl_shader_stage stage) +{ + struct disk_cache *cache = brw->ctx.Cache; + if (cache == NULL) + return false; + + struct gl_program *prog = brw->ctx._Shader->CurrentProgram[stage]; + if (prog == NULL) + return false; + + if (brw->ctx._Shader->Flags & GLSL_CACHE_FALLBACK) + goto fail; + + if (!read_and_upload(brw, cache, prog, stage)) + goto fail; + + if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) { + fprintf(stderr, "read gen program from cache\n"); + } + + return true; + +fail: + prog->program_written_to_cache = false; + if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) { + fprintf(stderr, "falling back to nir %s.\n", + _mesa_shader_stage_to_abbrev(prog->info.stage)); + } + + brw_program_deserialize_driver_blob(&brw->ctx, prog, stage); + + return false; +} + +static void +write_program_data(struct brw_context *brw, struct gl_program *prog, + void *key, struct brw_stage_prog_data *prog_data, + uint32_t prog_offset, struct disk_cache *cache, + gl_shader_stage stage) +{ + struct blob binary; + blob_init(&binary); + + const void *program_map = brw->cache.map + prog_offset; + /* TODO: Improve perf for non-LLC. It would be best to save it at program + * generation time when the program is in normal memory accessible with + * cache to the CPU. Another easier change would be to use + * _mesa_streaming_load_memcpy to read from the program mapped memory. */ + brw_write_blob_program_data(&binary, stage, program_map, prog_data); + + unsigned char sha1[20]; + char buf[41]; + gen_shader_sha1(prog, stage, key, sha1); + _mesa_sha1_format(buf, sha1); + if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) { + fprintf(stderr, "putting binary in cache: %s\n", buf); + } + + disk_cache_put(cache, sha1, binary.data, binary.size, NULL); + + prog->program_written_to_cache = true; + blob_finish(&binary); +} + +void +brw_disk_cache_write_render_programs(struct brw_context *brw) +{ + struct disk_cache *cache = brw->ctx.Cache; + if (cache == NULL) + return; + + struct gl_program *prog = + brw->ctx._Shader->CurrentProgram[MESA_SHADER_VERTEX]; + if (prog && !prog->program_written_to_cache) { + struct brw_vs_prog_key vs_key; + brw_vs_populate_key(brw, &vs_key); + vs_key.program_string_id = 0; + + write_program_data(brw, prog, &vs_key, brw->vs.base.prog_data, + brw->vs.base.prog_offset, cache, + MESA_SHADER_VERTEX); + } + + prog = brw->ctx._Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; + if (prog && !prog->program_written_to_cache) { + struct brw_tcs_prog_key tcs_key; + brw_tcs_populate_key(brw, &tcs_key); + tcs_key.program_string_id = 0; + + write_program_data(brw, prog, &tcs_key, brw->tcs.base.prog_data, + brw->tcs.base.prog_offset, cache, + MESA_SHADER_TESS_CTRL); + } + + prog = brw->ctx._Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; + if (prog && !prog->program_written_to_cache) { + struct brw_tes_prog_key tes_key; + brw_tes_populate_key(brw, &tes_key); + tes_key.program_string_id = 0; + + write_program_data(brw, prog, &tes_key, brw->tes.base.prog_data, + brw->tes.base.prog_offset, cache, + MESA_SHADER_TESS_EVAL); + } + + prog = brw->ctx._Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; + if (prog && !prog->program_written_to_cache) { + struct brw_gs_prog_key gs_key; + brw_gs_populate_key(brw, &gs_key); + gs_key.program_string_id = 0; + + write_program_data(brw, prog, &gs_key, brw->gs.base.prog_data, + brw->gs.base.prog_offset, cache, + MESA_SHADER_GEOMETRY); + } + + prog = brw->ctx._Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; + if (prog && !prog->program_written_to_cache) { + struct brw_wm_prog_key wm_key; + brw_wm_populate_key(brw, &wm_key); + wm_key.program_string_id = 0; + + write_program_data(brw, prog, &wm_key, brw->wm.base.prog_data, + brw->wm.base.prog_offset, cache, + MESA_SHADER_FRAGMENT); + } +} + +void +brw_disk_cache_write_compute_program(struct brw_context *brw) +{ + struct disk_cache *cache = brw->ctx.Cache; + if (cache == NULL) + return; + + struct gl_program *prog = + brw->ctx._Shader->CurrentProgram[MESA_SHADER_COMPUTE]; + if (prog && !prog->program_written_to_cache) { + struct brw_cs_prog_key cs_key; + brw_cs_populate_key(brw, &cs_key); + cs_key.program_string_id = 0; + + write_program_data(brw, prog, &cs_key, brw->cs.base.prog_data, + brw->cs.base.prog_offset, cache, + MESA_SHADER_COMPUTE); + } +} + +void +brw_disk_cache_init(struct intel_screen *screen) +{ +#ifdef ENABLE_SHADER_CACHE + if (INTEL_DEBUG & DEBUG_DISK_CACHE_DISABLE_MASK) + return; + + /* array length: print length + null char + 1 extra to verify it is unused */ + char renderer[11]; + MAYBE_UNUSED int len = snprintf(renderer, sizeof(renderer), "i965_%04x", + screen->deviceID); + assert(len == sizeof(renderer) - 2); + + const struct build_id_note *note = + build_id_find_nhdr_for_addr(brw_disk_cache_init); + assert(note && build_id_length(note) == 20 /* sha1 */); + + const uint8_t *id_sha1 = build_id_data(note); + assert(id_sha1); + + char timestamp[41]; + _mesa_sha1_format(timestamp, id_sha1); + + const uint64_t driver_flags = + brw_get_compiler_config_value(screen->compiler); + screen->disk_cache = disk_cache_create(renderer, timestamp, driver_flags); +#endif +} diff --git a/lib/mesa/src/mesa/drivers/dri/i965/brw_generate_mipmap.c b/lib/mesa/src/mesa/drivers/dri/i965/brw_generate_mipmap.c new file mode 100644 index 000000000..4125ae6e1 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/i965/brw_generate_mipmap.c @@ -0,0 +1,144 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "main/mipmap.h" +#include "main/teximage.h" +#include "brw_blorp.h" +#include "brw_context.h" +#include "intel_tex.h" +#include "drivers/common/meta.h" + +#define FILE_DEBUG_FLAG DEBUG_BLORP + + +/** + * The GenerateMipmap() driver hook. + */ +void +brw_generate_mipmap(struct gl_context *ctx, GLenum target, + struct gl_texture_object *tex_obj) +{ + struct brw_context *brw = brw_context(ctx); + struct gen_device_info *devinfo = &brw->screen->devinfo; + struct intel_texture_object *intel_obj = intel_texture_object(tex_obj); + const unsigned base_level = tex_obj->BaseLevel; + unsigned last_level, first_layer, last_layer; + + /* Blorp doesn't handle combined depth/stencil surfaces on Gen4-5 yet. */ + if (devinfo->gen <= 5 && + (tex_obj->Image[0][base_level]->_BaseFormat == GL_DEPTH_COMPONENT || + tex_obj->Image[0][base_level]->_BaseFormat == GL_DEPTH_STENCIL)) { + _mesa_meta_GenerateMipmap(ctx, target, tex_obj); + return; + } + + /* find expected last mipmap level to generate */ + last_level = _mesa_compute_num_levels(ctx, tex_obj, target) - 1; + + if (last_level == 0) + return; + + /* The texture isn't in a "complete" state yet so set the expected + * last_level here; we're not going through normal texture validation. + */ + intel_obj->_MaxLevel = last_level; + + if (!tex_obj->Immutable) { + _mesa_prepare_mipmap_levels(ctx, tex_obj, base_level, last_level); + + /* At this point, memory for all the texture levels has been + * allocated. However, the base level image may be in one resource + * while the subsequent/smaller levels may be in another resource. + * Finalizing the texture will copy the base images from the former + * resource to the latter. + * + * After this, we'll have all mipmap levels in one resource. + */ + intel_finalize_mipmap_tree(brw, tex_obj); + } + + struct intel_mipmap_tree *mt = intel_obj->mt; + if (!mt) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "mipmap generation"); + return; + } + + const mesa_format format = intel_obj->_Format; + + /* Fall back to the CPU for non-renderable cases. + * + * TODO: 3D textures require blending data from multiple slices, + * which means we need custom shaders. For now, fall back. + */ + if (!brw->mesa_format_supports_render[format] || target == GL_TEXTURE_3D) { + _mesa_generate_mipmap(ctx, target, tex_obj); + return; + } + + const struct isl_extent4d *base_size = &mt->surf.logical_level0_px; + + if (mt->target == GL_TEXTURE_CUBE_MAP) { + first_layer = _mesa_tex_target_to_face(target); + last_layer = first_layer; + } else { + first_layer = 0; + last_layer = base_size->array_len - 1; + } + + /* The GL_EXT_texture_sRGB_decode extension's issues section says: + * + * "10) How is mipmap generation of sRGB textures affected by the + * TEXTURE_SRGB_DECODE_EXT parameter? + * + * RESOLVED: When the TEXTURE_SRGB_DECODE parameter is DECODE_EXT + * for an sRGB texture, mipmap generation should decode sRGB texels + * to a linear RGB color space, perform downsampling, then encode + * back to an sRGB color space. (Issue 24 in the EXT_texture_sRGB + * specification provides a rationale for why.) When the parameter + * is SKIP_DECODE_EXT instead, mipmap generation skips the encode + * and decode steps during mipmap generation. By skipping the + * encode and decode steps, sRGB mipmap generation should match + * the mipmap generation for a non-sRGB texture." + */ + bool do_srgb = tex_obj->Sampler.sRGBDecode == GL_DECODE_EXT; + + for (unsigned dst_level = base_level + 1; + dst_level <= last_level; + dst_level++) { + + const unsigned src_level = dst_level - 1; + + for (unsigned layer = first_layer; layer <= last_layer; layer++) { + brw_blorp_blit_miptrees(brw, mt, src_level, layer, format, + SWIZZLE_XYZW, mt, dst_level, layer, format, + 0, 0, + minify(base_size->width, src_level), + minify(base_size->height, src_level), + 0, 0, + minify(base_size->width, dst_level), + minify(base_size->height, dst_level), + GL_LINEAR, false, false, + do_srgb, do_srgb); + } + } +} diff --git a/lib/mesa/src/mesa/drivers/dri/i965/brw_pipe_control.h b/lib/mesa/src/mesa/drivers/dri/i965/brw_pipe_control.h index 6e9a40487..4c58e1666 100644 --- a/lib/mesa/src/mesa/drivers/dri/i965/brw_pipe_control.h +++ b/lib/mesa/src/mesa/drivers/dri/i965/brw_pipe_control.h @@ -34,6 +34,7 @@ struct brw_bo; * additional flushing control. */ #define _3DSTATE_PIPE_CONTROL (CMD_3D | (3 << 27) | (2 << 24)) +#define PIPE_CONTROL_LRI_WRITE_IMMEDIATE (1 << 23) /* Gen7+ */ #define PIPE_CONTROL_CS_STALL (1 << 20) #define PIPE_CONTROL_GLOBAL_SNAPSHOT_COUNT_RESET (1 << 19) #define PIPE_CONTROL_TLB_INVALIDATE (1 << 18) @@ -85,5 +86,6 @@ void brw_emit_post_sync_nonzero_flush(struct brw_context *brw); void brw_emit_depth_stall_flushes(struct brw_context *brw); void gen7_emit_vs_workaround_flush(struct brw_context *brw); void gen7_emit_cs_stall_flush(struct brw_context *brw); +void gen10_emit_isp_disable(struct brw_context *brw); #endif diff --git a/lib/mesa/src/mesa/drivers/dri/i965/intel_buffers.c b/lib/mesa/src/mesa/drivers/dri/i965/intel_buffers.c index fd522cc4f..dae56e336 100644 --- a/lib/mesa/src/mesa/drivers/dri/i965/intel_buffers.c +++ b/lib/mesa/src/mesa/drivers/dri/i965/intel_buffers.c @@ -33,7 +33,7 @@ #include "main/renderbuffer.h" static void -intelDrawBuffer(struct gl_context * ctx, GLenum mode) +intelDrawBuffer(struct gl_context *ctx) { if (_mesa_is_front_buffer_drawing(ctx->DrawBuffer)) { struct brw_context *const brw = brw_context(ctx); diff --git a/lib/mesa/src/mesa/drivers/dri/meson.build b/lib/mesa/src/mesa/drivers/dri/meson.build new file mode 100644 index 000000000..d98c823f5 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/meson.build @@ -0,0 +1,84 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +subdir('common') + +dri_drivers = [] +dri_link = [] +if with_dri_swrast + subdir('swrast') +endif +if with_dri_i915 + subdir('i915') +endif +if with_dri_i965 + subdir('i965') +endif +if with_dri_r100 + subdir('radeon') +endif +if with_dri_r200 + subdir('r200') +endif +if with_dri_nouveau + subdir('nouveau') +endif + +if dri_drivers != [] + libmesa_dri_drivers = shared_library( + 'mesa_dri_drivers', + [], + link_whole : dri_drivers, + link_with : [ + libmegadriver_stub, libdricommon, libxmlconfig, libglapi, libmesa_util, + libmesa_classic, + ], + dependencies : [ + dep_selinux, dep_libdrm, dep_expat, dep_m, dep_thread, dep_dl, idep_nir, + ], + link_args : [ld_args_build_id, ld_args_bsymbolic, ld_args_gc_sections], + ) + + meson.add_install_script( + prog_python.path(), + join_paths(meson.source_root(), 'bin/install_megadrivers.py'), + libmesa_dri_drivers.full_path(), + dri_drivers_path, + dri_link, + ) +endif + +# This needs to be installed if any dri drivers (including gallium dri drivers) +# are built. +if with_dri + dri_req_private = [] + if dep_libdrm.found() + dri_req_private = ['libdrm >= ' + dep_libdrm.version()] + endif + + pkg.generate( + name : 'dri', + filebase : 'dri', + description : 'Direct Rendering Infrastructure', + version : meson.project_version(), + variables : ['dridriverdir=${prefix}/' + dri_drivers_path], + requires_private : dri_req_private, + ) +endif diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/Makefile.am b/lib/mesa/src/mesa/drivers/dri/nouveau/Makefile.am index 01e34a8e3..59fd7fce7 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/Makefile.am +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/Makefile.am @@ -26,7 +26,8 @@ include Makefile.sources EXTRA_DIST = \ nouveau_render_t.c \ nouveau_swtnl_t.c \ - nouveau_vbo_t.c + nouveau_vbo_t.c \ + meson.build AM_CFLAGS = \ -I$(top_srcdir)/include \ diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/meson.build b/lib/mesa/src/mesa/drivers/dri/nouveau/meson.build new file mode 100644 index 000000000..9ad6779d8 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/meson.build @@ -0,0 +1,92 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +files_nouveau_vieux = files( + 'nouveau_array.c', + 'nouveau_array.h', + 'nouveau_bufferobj.c', + 'nouveau_bufferobj.h', + 'nouveau_context.c', + 'nouveau_context.h', + 'nouveau_driver.c', + 'nouveau_driver.h', + 'nouveau_fbo.c', + 'nouveau_fbo.h', + 'nouveau_gldefs.h', + 'nouveau_local.h', + 'nouveau_render.h', + 'nouveau_scratch.c', + 'nouveau_scratch.h', + 'nouveau_screen.c', + 'nouveau_screen.h', + 'nouveau_span.c', + 'nouveau_state.c', + 'nouveau_state.h', + 'nouveau_surface.c', + 'nouveau_surface.h', + 'nouveau_texture.c', + 'nouveau_texture.h', + 'nouveau_util.h', + 'nv01_2d.xml.h', + 'nv04_3d.xml.h', + 'nv04_context.c', + 'nv04_context.h', + 'nv04_driver.h', + 'nv04_render.c', + 'nv04_state_fb.c', + 'nv04_state_frag.c', + 'nv04_state_raster.c', + 'nv04_state_tex.c', + 'nv04_surface.c', + 'nv10_3d.xml.h', + 'nv10_context.c', + 'nv10_driver.h', + 'nv10_render.c', + 'nv10_state_fb.c', + 'nv10_state_frag.c', + 'nv10_state_polygon.c', + 'nv10_state_raster.c', + 'nv10_state_tex.c', + 'nv10_state_tnl.c', + 'nv20_3d.xml.h', + 'nv20_context.c', + 'nv20_driver.h', + 'nv20_render.c', + 'nv20_state_fb.c', + 'nv20_state_frag.c', + 'nv20_state_polygon.c', + 'nv20_state_raster.c', + 'nv20_state_tex.c', + 'nv20_state_tnl.c', + 'nv_m2mf.xml.h', + 'nv_object.xml.h', +) + +libnouveau_vieux = static_library( + 'nouveau_vieux', + [files_nouveau_vieux, xmlpool_options_h], + include_directories : [inc_common, inc_dri_common, inc_util], + c_args : [c_vis_args], + cpp_args : [cpp_vis_args], + dependencies : [dep_libdrm, dep_libdrm_nouveau], +) + +dri_drivers += libnouveau_vieux +dri_link += 'nouveau_vieux_dri.so' diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_context.h b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_context.h index 6ab865c7b..dcb7bbb23 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -110,8 +110,7 @@ struct nouveau_context { GLboolean nouveau_context_create(gl_api api, const struct gl_config *visual, __DRIcontext *dri_ctx, - unsigned major_version, unsigned minor_version, - uint32_t flags, bool notify_reset, unsigned priority, + const struct __DriverContextConfig *ctx_config, unsigned *error, void *share_ctx); GLboolean diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.c index 998e751fc..1698df6ab 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -132,7 +132,13 @@ nouveau_clear(struct gl_context *ctx, GLbitfield buffers) else value = pack_rgba_clamp_f(s->format, color); - mask = pack_rgba_i(s->format, ctx->Color.ColorMask[0]); + const uint8_t colormask[4] = { + GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 0) ? 0xff : 0, + GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 1) ? 0xff : 0, + GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 2) ? 0xff : 0, + GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 3) ? 0xff : 0, + }; + mask = pack_rgba_i(s->format, colormask); if (mask) context_drv(ctx)->surface_fill( diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_fbo.c index c78d4baa1..77e7be112 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_fbo.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -133,13 +133,17 @@ nouveau_renderbuffer_map(struct gl_context *ctx, GLuint x, GLuint y, GLuint w, GLuint h, GLbitfield mode, GLubyte **out_map, - GLint *out_stride) + GLint *out_stride, + bool flip_y) { struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; GLubyte *map; int stride; int flags = 0; + /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */ + assert((rb->Name == 0) == flip_y); + if (mode & GL_MAP_READ_BIT) flags |= NOUVEAU_BO_RD; if (mode & GL_MAP_WRITE_BIT) diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_render.h b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_render.h index 0539c3775..4d45d5c2e 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_render.h +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_render.h @@ -27,7 +27,7 @@ #ifndef __NOUVEAU_RENDER_H__ #define __NOUVEAU_RENDER_H__ -#include "vbo/vbo_context.h" +#include "vbo/vbo.h" #include "nouveau_array.h" typedef void (*dispatch_t)(struct gl_context *, unsigned int, int, unsigned int); diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_util.h b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_util.h index 8087445b6..088a25637 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_util.h +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nouveau_util.h @@ -193,7 +193,7 @@ is_texture_source(int s) } static inline struct gl_texgen * -get_texgen_coord(struct gl_texture_unit *u, int i) +get_texgen_coord(struct gl_fixedfunc_texture_unit *u, int i) { return ((struct gl_texgen *[]) { &u->GenS, &u->GenT, &u->GenR, &u->GenQ }) [i]; diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nv04_context.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nv04_context.c index 3cc219bea..324595e24 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nv04_context.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nv04_context.c @@ -32,17 +32,18 @@ #include "nv04_driver.h" static GLboolean -texunit_needs_combiners(struct gl_texture_unit *u) +texunit_needs_combiners(struct gl_texture_unit *u, + struct gl_fixedfunc_texture_unit *f) { struct gl_texture_object *t = u->_Current; struct gl_texture_image *ti = t->Image[0][t->BaseLevel]; return ti->TexFormat == MESA_FORMAT_A_UNORM8 || ti->TexFormat == MESA_FORMAT_L_UNORM8 || - u->EnvMode == GL_COMBINE || - u->EnvMode == GL_COMBINE4_NV || - u->EnvMode == GL_BLEND || - u->EnvMode == GL_ADD; + f->EnvMode == GL_COMBINE || + f->EnvMode == GL_COMBINE4_NV || + f->EnvMode == GL_BLEND || + f->EnvMode == GL_ADD; } struct nouveau_object * @@ -54,13 +55,11 @@ nv04_context_engine(struct gl_context *ctx) struct nouveau_object *fahrenheit; if ((ctx->Texture.Unit[0]._Current && - texunit_needs_combiners(&ctx->Texture.Unit[0])) || + texunit_needs_combiners(&ctx->Texture.Unit[0], + &ctx->Texture.FixedFuncUnit[0])) || ctx->Texture.Unit[1]._Current || ctx->Stencil.Enabled || - !(ctx->Color.ColorMask[0][RCOMP] && - ctx->Color.ColorMask[0][GCOMP] && - ctx->Color.ColorMask[0][BCOMP] && - ctx->Color.ColorMask[0][ACOMP])) + GET_COLORMASK(ctx->Color.ColorMask, 0) != 0xf) fahrenheit = hw->eng3dm; else fahrenheit = hw->eng3d; diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nv04_state_frag.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nv04_state_frag.c index 248a7d2b5..26e2e91a6 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nv04_state_frag.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nv04_state_frag.c @@ -49,8 +49,8 @@ struct combiner_state { /* GL state */ GLenum mode; - GLenum *source; - GLenum *operand; + GLenum16 *source; + GLenum16 *operand; GLuint logscale; /* Derived HW state */ @@ -64,7 +64,7 @@ struct combiner_state { * context. */ #define INIT_COMBINER(chan, ctx, rc, i) do { \ struct gl_tex_env_combine_state *c = \ - ctx->Texture.Unit[i]._CurrentCombine; \ + ctx->Texture.FixedFuncUnit[i]._CurrentCombine; \ (rc)->ctx = ctx; \ (rc)->unit = i; \ (rc)->alpha = __INIT_COMBINER_ALPHA_##chan; \ @@ -287,7 +287,7 @@ nv04_emit_tex_env(struct gl_context *ctx, int emit) /* calculate non-multitex state */ nv04->blend &= ~NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP__MASK; if (ctx->Texture._MaxEnabledTexImageUnit != -1) - nv04->blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode); + nv04->blend |= get_texenv_mode(ctx->Texture.FixedFuncUnit[0].EnvMode); else nv04->blend |= get_texenv_mode(GL_MODULATE); @@ -295,5 +295,5 @@ nv04_emit_tex_env(struct gl_context *ctx, int emit) nv04->alpha[i] = rc_a.hw; nv04->color[i] = rc_c.hw; nv04->factor = pack_rgba_f(MESA_FORMAT_B8G8R8A8_UNORM, - ctx->Texture.Unit[0].EnvColor); + ctx->Texture.FixedFuncUnit[0].EnvColor); } diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_render.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_render.c index 701ba9a87..9b2cf229f 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_render.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_render.c @@ -72,19 +72,19 @@ static struct nouveau_attr_info nv10_vertex_attrs[VERT_ATTRIB_MAX] = { .imm_method = NV10_3D_VERTEX_FOG_1F, .imm_fields = 1, }, - [VERT_ATTRIB_GENERIC0] = { + [VERT_ATTRIB_MAT(0)] = { .emit = nv10_emit_material, }, - [VERT_ATTRIB_GENERIC2] = { + [VERT_ATTRIB_MAT(2)] = { .emit = nv10_emit_material, }, - [VERT_ATTRIB_GENERIC4] = { + [VERT_ATTRIB_MAT(4)] = { .emit = nv10_emit_material, }, - [VERT_ATTRIB_GENERIC6] = { + [VERT_ATTRIB_MAT(6)] = { .emit = nv10_emit_material, }, - [VERT_ATTRIB_GENERIC8] = { + [VERT_ATTRIB_MAT(8)] = { .emit = nv10_emit_material, }, }; diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_state_frag.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_state_frag.c index c6e4bb0d5..27400d3eb 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_state_frag.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_state_frag.c @@ -67,8 +67,8 @@ struct combiner_state { /* GL state */ GLenum mode; - GLenum *source; - GLenum *operand; + GLenum16 *source; + GLenum16 *operand; GLuint logscale; /* Derived HW state */ @@ -80,7 +80,7 @@ struct combiner_state { * context. */ #define INIT_COMBINER(chan, ctx, rc, i) do { \ struct gl_tex_env_combine_state *c = \ - ctx->Texture.Unit[i]._CurrentCombine; \ + ctx->Texture.FixedFuncUnit[i]._CurrentCombine; \ (rc)->ctx = ctx; \ (rc)->unit = i; \ (rc)->premodulate = c->_NumArgs##chan == 4; \ @@ -332,7 +332,7 @@ nv10_get_general_combiner(struct gl_context *ctx, int i, } *k = pack_rgba_f(MESA_FORMAT_B8G8R8A8_UNORM, - ctx->Texture.Unit[i].EnvColor); + ctx->Texture.FixedFuncUnit[i].EnvColor); *a_in = rc_a.in; *a_out = rc_a.out; *c_in = rc_c.in; diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_state_tex.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_state_tex.c index d85adfa9c..d741d4166 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_state_tex.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nv10_state_tex.c @@ -39,7 +39,8 @@ nv10_emit_tex_gen(struct gl_context *ctx, int emit) const int i = emit - NOUVEAU_STATE_TEX_GEN0; struct nouveau_context *nctx = to_nouveau_context(ctx); struct nouveau_pushbuf *push = context_push(ctx); - struct gl_texture_unit *unit = &ctx->Texture.Unit[i]; + struct gl_fixedfunc_texture_unit *unit = + &ctx->Texture.FixedFuncUnit[i]; int j; for (j = 0; j < 4; j++) { @@ -73,7 +74,7 @@ nv10_emit_tex_mat(struct gl_context *ctx, int emit) if (nctx->fallback == HWTNL && ((ctx->Texture._TexMatEnabled & 1 << i) || - ctx->Texture.Unit[i]._GenFlags)) { + ctx->Texture.FixedFuncUnit[i]._GenFlags)) { BEGIN_NV04(push, NV10_3D(TEX_MATRIX_ENABLE(i)), 1); PUSH_DATA (push, 1); diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_context.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_context.c index 0ab2db0b0..887aa5f48 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_context.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_context.c @@ -55,13 +55,13 @@ nv20_clear(struct gl_context *ctx, GLbitfield buffers) struct nouveau_surface *s = &to_nouveau_renderbuffer( fb->_ColorDrawBuffers[0])->surface; - if (ctx->Color.ColorMask[0][RCOMP]) + if (GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 0)) clear |= NV20_3D_CLEAR_BUFFERS_COLOR_R; - if (ctx->Color.ColorMask[0][GCOMP]) + if (GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 1)) clear |= NV20_3D_CLEAR_BUFFERS_COLOR_G; - if (ctx->Color.ColorMask[0][BCOMP]) + if (GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 2)) clear |= NV20_3D_CLEAR_BUFFERS_COLOR_B; - if (ctx->Color.ColorMask[0][ACOMP]) + if (GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 3)) clear |= NV20_3D_CLEAR_BUFFERS_COLOR_A; BEGIN_NV04(push, NV20_3D(CLEAR_VALUE), 1); diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_render.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_render.c index 2627bfa35..9a426ccec 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_render.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_render.c @@ -82,34 +82,34 @@ static struct nouveau_attr_info nv20_vertex_attrs[VERT_ATTRIB_MAX] = { .imm_method = NV20_3D_VERTEX_TX3_4F_S, .imm_fields = 4, }, - [VERT_ATTRIB_GENERIC0] = { + [VERT_ATTRIB_MAT(0)] = { .emit = nv20_emit_material, }, - [VERT_ATTRIB_GENERIC1] = { + [VERT_ATTRIB_MAT(1)] = { .emit = nv20_emit_material, }, - [VERT_ATTRIB_GENERIC2] = { + [VERT_ATTRIB_MAT(2)] = { .emit = nv20_emit_material, }, - [VERT_ATTRIB_GENERIC3] = { + [VERT_ATTRIB_MAT(3)] = { .emit = nv20_emit_material, }, - [VERT_ATTRIB_GENERIC4] = { + [VERT_ATTRIB_MAT(4)] = { .emit = nv20_emit_material, }, - [VERT_ATTRIB_GENERIC5] = { + [VERT_ATTRIB_MAT(5)] = { .emit = nv20_emit_material, }, - [VERT_ATTRIB_GENERIC6] = { + [VERT_ATTRIB_MAT(6)] = { .emit = nv20_emit_material, }, - [VERT_ATTRIB_GENERIC7] = { + [VERT_ATTRIB_MAT(7)] = { .emit = nv20_emit_material, }, - [VERT_ATTRIB_GENERIC8] = { + [VERT_ATTRIB_MAT(8)] = { .emit = nv20_emit_material, }, - [VERT_ATTRIB_GENERIC9] = { + [VERT_ATTRIB_MAT(9)] = { .emit = nv20_emit_material, }, }; diff --git a/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_state_raster.c b/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_state_raster.c index 4856053aa..c24c5bbae 100644 --- a/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_state_raster.c +++ b/lib/mesa/src/mesa/drivers/dri/nouveau/nv20_state_raster.c @@ -38,5 +38,5 @@ nv20_emit_logic_opcode(struct gl_context *ctx, int emit) BEGIN_NV04(push, NV20_3D(COLOR_LOGIC_OP_ENABLE), 2); PUSH_DATAb(push, ctx->Color.ColorLogicOpEnabled); - PUSH_DATA (push, nvgl_logicop_func(ctx->Color.LogicOp)); + PUSH_DATA (push, ctx->Color.LogicOp); } diff --git a/lib/mesa/src/mesa/drivers/dri/r200/Makefile.am b/lib/mesa/src/mesa/drivers/dri/r200/Makefile.am index 110c02ed2..3d15c0199 100644 --- a/lib/mesa/src/mesa/drivers/dri/r200/Makefile.am +++ b/lib/mesa/src/mesa/drivers/dri/r200/Makefile.am @@ -24,7 +24,8 @@ include Makefile.sources EXTRA_DIST = \ - r200_maos_arrays.c + r200_maos_arrays.c \ + meson.build AM_CFLAGS = \ -DRADEON_R200 \ diff --git a/lib/mesa/src/mesa/drivers/dri/r200/meson.build b/lib/mesa/src/mesa/drivers/dri/r200/meson.build new file mode 100644 index 000000000..8389b4f63 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/meson.build @@ -0,0 +1,91 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +files_r200 = files( + 'radeon_buffer_objects.c', + 'radeon_buffer_objects.h', + 'radeon_cmdbuf.h', + 'radeon_common.c', + 'radeon_common.h', + 'radeon_common_context.c', + 'radeon_common_context.h', + 'radeon_debug.c', + 'radeon_debug.h', + 'radeon_dma.c', + 'radeon_dma.h', + 'radeon_fbo.c', + 'radeon_fog.c', + 'radeon_fog.h', + 'radeon_mipmap_tree.c', + 'radeon_mipmap_tree.h', + 'radeon_pixel_read.c', + 'radeon_queryobj.c', + 'radeon_queryobj.h', + 'radeon_span.c', + 'radeon_span.h', + 'radeon_tex_copy.c', + 'radeon_texture.c', + 'radeon_texture.h', + 'radeon_tile.c', + 'radeon_tile.h', + 'r200_blit.c', + 'r200_blit.h', + 'r200_cmdbuf.c', + 'r200_context.c', + 'r200_context.h', + 'r200_fragshader.c', + 'r200_ioctl.c', + 'r200_ioctl.h', + 'r200_maos.c', + 'r200_maos.h', + 'r200_reg.h', + 'r200_sanity.c', + 'r200_sanity.h', + 'r200_state.c', + 'r200_state.h', + 'r200_state_init.c', + 'r200_swtcl.c', + 'r200_swtcl.h', + 'r200_tcl.c', + 'r200_tcl.h', + 'r200_tex.c', + 'r200_tex.h', + 'r200_texstate.c', + 'r200_vertprog.c', + 'r200_vertprog.h', + 'radeon_chipset.h', + 'radeon_screen.c', + 'radeon_screen.h', + 'server/radeon_reg.h', +) + +libr200 = static_library( + 'r200', + [files_r200, xmlpool_options_h], + include_directories : [ + inc_common, inc_dri_common, inc_util, include_directories('server'), + ], + c_args : [c_vis_args, '-DRADEON_R200'], + cpp_args : [cpp_vis_args], + dependencies : [dep_libdrm, dep_libdrm_radeon], +) + +dri_drivers += libr200 +dri_link += 'r200_dri.so' diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.h index fedaf5063..a39b9360e 100644 --- a/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.h +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.h @@ -21,7 +21,7 @@ void radeon_clear_tris(struct gl_context *ctx, GLbitfield mask); void radeon_window_moved(radeonContextPtr radeon); void radeon_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb); -void radeonDrawBuffer( struct gl_context *ctx, GLenum mode ); +void radeonDrawBuffer(struct gl_context *ctx); void radeonReadBuffer( struct gl_context *ctx, GLenum mode ); void radeon_viewport(struct gl_context *ctx); void radeon_fbo_init(struct radeon_context *radeon); @@ -37,7 +37,6 @@ radeonReadPixels(struct gl_context * ctx, GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, GLvoid * pixels); -void radeon_check_front_buffer_rendering(struct gl_context *ctx); static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb) { struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb; diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.c index 383a5df67..91f86a96b 100644 --- a/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.c +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.c @@ -75,7 +75,7 @@ void _radeon_debug_add_indent(void) if (radeon->debug.indent_depth < length - 1) { radeon->debug.indent[radeon->debug.indent_depth] = '\t'; ++radeon->debug.indent_depth; - }; + } } void _radeon_debug_remove_indent(void) diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.h index e70e334ab..af1b9454e 100644 --- a/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.h +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.h @@ -47,6 +47,68 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_reg.h" #include "util/xmlconfig.h" +#define DRI_CONF_COLOR_REDUCTION_ROUND 0 +#define DRI_CONF_COLOR_REDUCTION_DITHER 1 +#define DRI_CONF_COLOR_REDUCTION(def) \ +DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Initial color reduction method") \ + DRI_CONF_ENUM(0,"Round colors") \ + DRI_CONF_ENUM(1,"Dither colors") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_DITHER_XERRORDIFF 0 +#define DRI_CONF_DITHER_XERRORDIFFRESET 1 +#define DRI_CONF_DITHER_ORDERED 2 +#define DRI_CONF_DITHER_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Color dithering method") \ + DRI_CONF_ENUM(0,"Horizontal error diffusion") \ + DRI_CONF_ENUM(1,"Horizontal error diffusion, reset error at line start") \ + DRI_CONF_ENUM(2,"Ordered 2D color dithering") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_ROUND_TRUNC 0 +#define DRI_CONF_ROUND_ROUND 1 +#define DRI_CONF_ROUND_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Color rounding method") \ + DRI_CONF_ENUM(0,"Round color components downward") \ + DRI_CONF_ENUM(1,"Round to nearest color") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_FTHROTTLE_BUSY 0 +#define DRI_CONF_FTHROTTLE_USLEEPS 1 +#define DRI_CONF_FTHROTTLE_IRQS 2 +#define DRI_CONF_FTHROTTLE_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Method to limit rendering latency") \ + DRI_CONF_ENUM(0,"Busy waiting for the graphics hardware") \ + DRI_CONF_ENUM(1,"Sleep for brief intervals while waiting for the graphics hardware") \ + DRI_CONF_ENUM(2,"Let the graphics hardware emit a software interrupt and sleep") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_TEXTURE_DEPTH_FB 0 +#define DRI_CONF_TEXTURE_DEPTH_32 1 +#define DRI_CONF_TEXTURE_DEPTH_16 2 +#define DRI_CONF_TEXTURE_DEPTH_FORCE_16 3 +#define DRI_CONF_TEXTURE_DEPTH(def) \ +DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,"Texture color depth") \ + DRI_CONF_ENUM(0,"Prefer frame buffer color depth") \ + DRI_CONF_ENUM(1,"Prefer 32 bits per texel") \ + DRI_CONF_ENUM(2,"Prefer 16 bits per texel") \ + DRI_CONF_ENUM(3,"Force 16 bits per texel") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_TCL_SW 0 +#define DRI_CONF_TCL_PIPELINED 1 +#define DRI_CONF_TCL_VTXFMT 2 +#define DRI_CONF_TCL_CODEGEN 3 typedef struct { drm_handle_t handle; /* Handle to the DRM region */ @@ -126,7 +188,6 @@ struct __DRIimageRec { #define radeon_prepare_render r200_radeon_prepare_render #define radeonUnbindContext r200_radeonUnbindContext #define radeon_update_renderbuffers r200_radeon_update_renderbuffers -#define radeon_check_front_buffer_rendering r200_radeon_check_front_buffer_rendering #define radeonCountStateEmitSize r200_radeonCountStateEmitSize #define radeon_draw_buffer r200_radeon_draw_buffer #define radeonDrawBuffer r200_radeonDrawBuffer diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.c index 42f62a0cb..fa5b2d98f 100644 --- a/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.c +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.c @@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/texformat.h" #include "main/renderbuffer.h" #include "main/samplerobj.h" +#include "main/framebuffer.h" #include "swrast/swrast.h" #include "swrast/s_renderbuffer.h" @@ -52,7 +53,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static void -radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb) +radeon_renderbuffer_map(struct gl_context *ctx, + struct gl_renderbuffer *rb, + bool flip_y) { struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); GLubyte *map; @@ -63,7 +66,7 @@ radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb) ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &map, &stride); + &map, &stride, flip_y); rrb->base.Map = map; rrb->base.RowStride = stride; @@ -95,9 +98,11 @@ radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) /* check for render to textures */ for (i = 0; i < BUFFER_COUNT; i++) - radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer); + radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer, + fb->FlipY); - radeon_check_front_buffer_rendering(ctx); + if (_mesa_is_front_buffer_drawing(fb)) + RADEON_CONTEXT(ctx)->front_buffer_dirty = true; } static void @@ -113,7 +118,8 @@ radeon_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) for (i = 0; i < BUFFER_COUNT; i++) radeon_renderbuffer_unmap(ctx, fb->Attachment[i].Renderbuffer); - radeon_check_front_buffer_rendering(ctx); + if (_mesa_is_front_buffer_drawing(fb)) + RADEON_CONTEXT(ctx)->front_buffer_dirty = true; } static void radeonSpanRenderStart(struct gl_context * ctx) diff --git a/lib/mesa/src/mesa/drivers/dri/radeon/Makefile.am b/lib/mesa/src/mesa/drivers/dri/radeon/Makefile.am index aa898645c..9d43d2627 100644 --- a/lib/mesa/src/mesa/drivers/dri/radeon/Makefile.am +++ b/lib/mesa/src/mesa/drivers/dri/radeon/Makefile.am @@ -25,7 +25,8 @@ include Makefile.sources EXTRA_DIST = \ radeon_maos_verts.c \ - radeon_maos_arrays.c + radeon_maos_arrays.c \ + meson.build AM_CFLAGS = \ -DRADEON_R100 \ diff --git a/lib/mesa/src/mesa/drivers/dri/radeon/meson.build b/lib/mesa/src/mesa/drivers/dri/radeon/meson.build new file mode 100644 index 000000000..bed608258 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/radeon/meson.build @@ -0,0 +1,87 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +files_r100 = files( + 'radeon_buffer_objects.c', + 'radeon_buffer_objects.h', + 'radeon_cmdbuf.h', + 'radeon_common.c', + 'radeon_common_context.c', + 'radeon_common_context.h', + 'radeon_common.h', + 'radeon_debug.c', + 'radeon_debug.h', + 'radeon_dma.c', + 'radeon_dma.h', + 'radeon_fbo.c', + 'radeon_fog.c', + 'radeon_fog.h', + 'radeon_mipmap_tree.c', + 'radeon_mipmap_tree.h', + 'radeon_pixel_read.c', + 'radeon_queryobj.c', + 'radeon_queryobj.h', + 'radeon_span.c', + 'radeon_span.h', + 'radeon_tex_copy.c', + 'radeon_texture.c', + 'radeon_texture.h', + 'radeon_tile.c', + 'radeon_tile.h', + 'radeon_blit.c', + 'radeon_blit.h', + 'radeon_context.c', + 'radeon_context.h', + 'radeon_chipset.h', + 'radeon_ioctl.c', + 'radeon_ioctl.h', + 'radeon_maos.c', + 'radeon_maos.h', + 'radeon_maos_vbtmp.h', + 'radeon_sanity.c', + 'radeon_sanity.h', + 'radeon_screen.c', + 'radeon_screen.h', + 'radeon_state.c', + 'radeon_state.h', + 'radeon_state_init.c', + 'radeon_swtcl.c', + 'radeon_swtcl.h', + 'radeon_tcl.c', + 'radeon_tcl.h', + 'radeon_tex.c', + 'radeon_tex.h', + 'radeon_texstate.c', + 'server/radeon_reg.h', +) + +libr100 = static_library( + 'r100', + [files_r100, xmlpool_options_h], + include_directories : [ + inc_common, inc_dri_common, inc_util, include_directories('server'), + ], + c_args : [c_vis_args, '-DRADEON_R100'], + cpp_args : [cpp_vis_args], + dependencies : [dep_libdrm, dep_libdrm_radeon], +) + +dri_drivers += libr100 +dri_link += 'radeon_dri.so' diff --git a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_common.h b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_common.h index fedaf5063..a39b9360e 100644 --- a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_common.h @@ -21,7 +21,7 @@ void radeon_clear_tris(struct gl_context *ctx, GLbitfield mask); void radeon_window_moved(radeonContextPtr radeon); void radeon_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb); -void radeonDrawBuffer( struct gl_context *ctx, GLenum mode ); +void radeonDrawBuffer(struct gl_context *ctx); void radeonReadBuffer( struct gl_context *ctx, GLenum mode ); void radeon_viewport(struct gl_context *ctx); void radeon_fbo_init(struct radeon_context *radeon); @@ -37,7 +37,6 @@ radeonReadPixels(struct gl_context * ctx, GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, GLvoid * pixels); -void radeon_check_front_buffer_rendering(struct gl_context *ctx); static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb) { struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb; diff --git a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_context.h b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_context.h index 4124f50db..94917cf30 100644 --- a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_context.h @@ -452,11 +452,8 @@ R100_CONTEXT(struct gl_context *ctx) extern GLboolean r100CreateContext( gl_api api, const struct gl_config *glVisual, __DRIcontext *driContextPriv, - unsigned major_version, - unsigned minor_version, - uint32_t flags, - bool notify_reset, - unsigned priority, + const struct __DriverContextConfig * + ctx_config, unsigned *error, void *sharedContextPrivate); diff --git a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_debug.c b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_debug.c index 383a5df67..91f86a96b 100644 --- a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_debug.c +++ b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_debug.c @@ -75,7 +75,7 @@ void _radeon_debug_add_indent(void) if (radeon->debug.indent_depth < length - 1) { radeon->debug.indent[radeon->debug.indent_depth] = '\t'; ++radeon->debug.indent_depth; - }; + } } void _radeon_debug_remove_indent(void) diff --git a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_maos_verts.c index 9a7785062..c9c91f864 100644 --- a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_maos_verts.c +++ b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_maos_verts.c @@ -352,7 +352,7 @@ void radeonEmitArrays( struct gl_context *ctx, GLuint inputs ) req |= RADEON_Q_BIT(unit); vtx |= RADEON_Q_BIT(unit); } - if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) ) + if ( (ctx->Texture.FixedFuncUnit[unit].TexGenEnabled & (R_BIT | Q_BIT)) ) vtx |= RADEON_Q_BIT(unit); else if ((VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) && (!ctx->Texture.Unit[unit]._Current || diff --git a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_screen.h b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_screen.h index e70e334ab..af1b9454e 100644 --- a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_screen.h +++ b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_screen.h @@ -47,6 +47,68 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_reg.h" #include "util/xmlconfig.h" +#define DRI_CONF_COLOR_REDUCTION_ROUND 0 +#define DRI_CONF_COLOR_REDUCTION_DITHER 1 +#define DRI_CONF_COLOR_REDUCTION(def) \ +DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Initial color reduction method") \ + DRI_CONF_ENUM(0,"Round colors") \ + DRI_CONF_ENUM(1,"Dither colors") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_DITHER_XERRORDIFF 0 +#define DRI_CONF_DITHER_XERRORDIFFRESET 1 +#define DRI_CONF_DITHER_ORDERED 2 +#define DRI_CONF_DITHER_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Color dithering method") \ + DRI_CONF_ENUM(0,"Horizontal error diffusion") \ + DRI_CONF_ENUM(1,"Horizontal error diffusion, reset error at line start") \ + DRI_CONF_ENUM(2,"Ordered 2D color dithering") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_ROUND_TRUNC 0 +#define DRI_CONF_ROUND_ROUND 1 +#define DRI_CONF_ROUND_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Color rounding method") \ + DRI_CONF_ENUM(0,"Round color components downward") \ + DRI_CONF_ENUM(1,"Round to nearest color") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_FTHROTTLE_BUSY 0 +#define DRI_CONF_FTHROTTLE_USLEEPS 1 +#define DRI_CONF_FTHROTTLE_IRQS 2 +#define DRI_CONF_FTHROTTLE_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Method to limit rendering latency") \ + DRI_CONF_ENUM(0,"Busy waiting for the graphics hardware") \ + DRI_CONF_ENUM(1,"Sleep for brief intervals while waiting for the graphics hardware") \ + DRI_CONF_ENUM(2,"Let the graphics hardware emit a software interrupt and sleep") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_TEXTURE_DEPTH_FB 0 +#define DRI_CONF_TEXTURE_DEPTH_32 1 +#define DRI_CONF_TEXTURE_DEPTH_16 2 +#define DRI_CONF_TEXTURE_DEPTH_FORCE_16 3 +#define DRI_CONF_TEXTURE_DEPTH(def) \ +DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,"Texture color depth") \ + DRI_CONF_ENUM(0,"Prefer frame buffer color depth") \ + DRI_CONF_ENUM(1,"Prefer 32 bits per texel") \ + DRI_CONF_ENUM(2,"Prefer 16 bits per texel") \ + DRI_CONF_ENUM(3,"Force 16 bits per texel") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_TCL_SW 0 +#define DRI_CONF_TCL_PIPELINED 1 +#define DRI_CONF_TCL_VTXFMT 2 +#define DRI_CONF_TCL_CODEGEN 3 typedef struct { drm_handle_t handle; /* Handle to the DRM region */ @@ -126,7 +188,6 @@ struct __DRIimageRec { #define radeon_prepare_render r200_radeon_prepare_render #define radeonUnbindContext r200_radeonUnbindContext #define radeon_update_renderbuffers r200_radeon_update_renderbuffers -#define radeon_check_front_buffer_rendering r200_radeon_check_front_buffer_rendering #define radeonCountStateEmitSize r200_radeonCountStateEmitSize #define radeon_draw_buffer r200_radeon_draw_buffer #define radeonDrawBuffer r200_radeonDrawBuffer diff --git a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_span.c b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_span.c index 42f62a0cb..fa5b2d98f 100644 --- a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_span.c @@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/texformat.h" #include "main/renderbuffer.h" #include "main/samplerobj.h" +#include "main/framebuffer.h" #include "swrast/swrast.h" #include "swrast/s_renderbuffer.h" @@ -52,7 +53,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static void -radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb) +radeon_renderbuffer_map(struct gl_context *ctx, + struct gl_renderbuffer *rb, + bool flip_y) { struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); GLubyte *map; @@ -63,7 +66,7 @@ radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb) ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &map, &stride); + &map, &stride, flip_y); rrb->base.Map = map; rrb->base.RowStride = stride; @@ -95,9 +98,11 @@ radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) /* check for render to textures */ for (i = 0; i < BUFFER_COUNT; i++) - radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer); + radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer, + fb->FlipY); - radeon_check_front_buffer_rendering(ctx); + if (_mesa_is_front_buffer_drawing(fb)) + RADEON_CONTEXT(ctx)->front_buffer_dirty = true; } static void @@ -113,7 +118,8 @@ radeon_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) for (i = 0; i < BUFFER_COUNT; i++) radeon_renderbuffer_unmap(ctx, fb->Attachment[i].Renderbuffer); - radeon_check_front_buffer_rendering(ctx); + if (_mesa_is_front_buffer_drawing(fb)) + RADEON_CONTEXT(ctx)->front_buffer_dirty = true; } static void radeonSpanRenderStart(struct gl_context * ctx) diff --git a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_state_init.c b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_state_init.c index 99c535a49..6a8cf606d 100644 --- a/lib/mesa/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/lib/mesa/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -27,6 +27,7 @@ * Keith Whitwell <keithw@vmware.com> */ +#include "main/errors.h" #include "main/glheader.h" #include "main/imports.h" #include "main/api_arrayelt.h" @@ -440,7 +441,7 @@ static void cube_emit_cs(struct gl_context *ctx, struct radeon_state_atom *atom) case 2: base_reg = RADEON_PP_CUBIC_OFFSET_T2_0; break; default: case 0: base_reg = RADEON_PP_CUBIC_OFFSET_T0_0; break; - }; + } BEGIN_BATCH(dwords); OUT_BATCH_TABLE(atom->cmd, 2); lvl = &t->mt->levels[0]; diff --git a/lib/mesa/src/mesa/drivers/dri/swrast/Makefile.am b/lib/mesa/src/mesa/drivers/dri/swrast/Makefile.am index 7e1ea59e9..110c05605 100644 --- a/lib/mesa/src/mesa/drivers/dri/swrast/Makefile.am +++ b/lib/mesa/src/mesa/drivers/dri/swrast/Makefile.am @@ -38,3 +38,5 @@ AM_CFLAGS = \ noinst_LTLIBRARIES = libswrast_dri.la libswrast_dri_la_SOURCES = $(SWRAST_C_FILES) + +EXTRA_DIST = meson.build diff --git a/lib/mesa/src/mesa/drivers/dri/swrast/meson.build b/lib/mesa/src/mesa/drivers/dri/swrast/meson.build new file mode 100644 index 000000000..5ceb1e33e --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/swrast/meson.build @@ -0,0 +1,30 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libswrast_dri = static_library( + 'swrast_dri', + files('swrast.c', 'swrast_priv.h'), + c_args : [c_vis_args], + include_directories : [inc_common, inc_dri_common], + dependencies : dep_libdrm, +) + +dri_drivers += libswrast_dri +dri_link += 'swrast_dri.so' diff --git a/lib/mesa/src/mesa/drivers/osmesa/Makefile.am b/lib/mesa/src/mesa/drivers/osmesa/Makefile.am index 2c8d4668b..f78169959 100644 --- a/lib/mesa/src/mesa/drivers/osmesa/Makefile.am +++ b/lib/mesa/src/mesa/drivers/osmesa/Makefile.am @@ -21,7 +21,7 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -EXTRA_DIST = osmesa.def SConscript +EXTRA_DIST = osmesa.def SConscript meson.build AM_CPPFLAGS = \ -I$(top_srcdir)/include \ @@ -30,6 +30,8 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/gallium/auxiliary \ -I$(top_builddir)/src/mapi \ -I$(top_srcdir)/src/mapi \ + -I$(top_builddir)/src/mapi/glapi \ + -I$(top_srcdir)/src/mapi/glapi \ -I$(top_srcdir)/src/mesa/ \ $(DEFINES) AM_CFLAGS = $(PTHREAD_CFLAGS) \ diff --git a/lib/mesa/src/mesa/drivers/osmesa/SConscript b/lib/mesa/src/mesa/drivers/osmesa/SConscript index 728031446..b08a79eb8 100644 --- a/lib/mesa/src/mesa/drivers/osmesa/SConscript +++ b/lib/mesa/src/mesa/drivers/osmesa/SConscript @@ -7,6 +7,7 @@ env.Prepend(CPPPATH = [ '#src/mapi', '#src/mesa', Dir('../../../mapi'), # src/mapi build path for python-generated GL API files/headers + Dir('../../../mapi/glapi'), # src/mapi/glapi build path ]) env.Prepend(LIBS = [ @@ -14,6 +15,8 @@ env.Prepend(LIBS = [ glapi, compiler, mesa, + spirv, + nir, glsl, ]) @@ -25,10 +28,8 @@ if env['platform'] == 'windows': env.AppendUnique(CPPDEFINES = [ '_GDI32_', # prevent wgl* being declared __declspec(dllimport) 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers + '_GLAPI_NO_EXPORTS', # prevent _glapi_* from being declared __declspec(dllimport) ]) - if not env['gles']: - # prevent _glapi_* from being declared __declspec(dllimport) - env.Append(CPPDEFINES = ['_GLAPI_NO_EXPORTS']) sources += ['osmesa.def'] diff --git a/lib/mesa/src/mesa/drivers/osmesa/meson.build b/lib/mesa/src/mesa/drivers/osmesa/meson.build new file mode 100644 index 000000000..a406bb3c2 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/osmesa/meson.build @@ -0,0 +1,48 @@ +# Copyright © 2017 Dylan Baker + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +osmesa_link_with = [] + +if with_shared_glapi + osmesa_link_with += libglapi +endif + +libosmesa = shared_library( + osmesa_lib_name, + ['osmesa.c', glapitable_h, glapitemp_h], + c_args : c_vis_args, + cpp_args : cpp_vis_args, + link_args : ld_args_gc_sections, + include_directories : [ + inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, + ], + link_with : [libmesa_classic, libglapi_static, osmesa_link_with], + dependencies : [dep_thread, dep_selinux], + version : '8.0.0', + install : true, +) + +pkg.generate( + name : 'osmesa', + description : 'Mesa Off-screen Rendering Library', + version : '8.0.0', + libraries : libosmesa, + libraries_private : gl_priv_libs, +) diff --git a/lib/mesa/src/mesa/drivers/x11/SConscript b/lib/mesa/src/mesa/drivers/x11/SConscript index 59c8df4b3..b097dcc59 100644 --- a/lib/mesa/src/mesa/drivers/x11/SConscript +++ b/lib/mesa/src/mesa/drivers/x11/SConscript @@ -21,6 +21,8 @@ env.Prepend(LIBS = [ compiler, glsl, mesa, + spirv, + nir, ]) sources = [ diff --git a/lib/mesa/src/mesa/drivers/x11/meson.build b/lib/mesa/src/mesa/drivers/x11/meson.build new file mode 100644 index 000000000..cb092d25d --- /dev/null +++ b/lib/mesa/src/mesa/drivers/x11/meson.build @@ -0,0 +1,39 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +gl_link_with = [] +if with_shared_glapi + gl_link_with += libglapi +endif + +libgl = shared_library( + 'GL', + files( + 'fakeglx.c', 'glxapi.c', 'xfonts.c', 'xm_api.c', 'xm_buffer.c', 'xm_dd.c', + 'xm_line.c', 'xm_tri.c', + ), + include_directories : [ + inc_include, inc_src, inc_mesa, inc_mapi, inc_gallium, inc_gallium_aux + ], + link_with : [libmesa_classic, libglapi_static, libmesa_util, gl_link_with], + dependencies : [dep_x11, dep_xext, dep_xcb, dep_thread], + version : '1.6.0', + install : true, +) diff --git a/lib/mesa/src/mesa/drivers/x11/xm_buffer.c b/lib/mesa/src/mesa/drivers/x11/xm_buffer.c index 4d52169d7..d945d8af5 100644 --- a/lib/mesa/src/mesa/drivers/x11/xm_buffer.c +++ b/lib/mesa/src/mesa/drivers/x11/xm_buffer.c @@ -31,6 +31,7 @@ #include "glxheader.h" #include "xmesaP.h" +#include "main/errors.h" #include "main/imports.h" #include "main/formats.h" #include "main/framebuffer.h" @@ -422,7 +423,8 @@ xmesa_MapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint x, GLuint y, GLuint w, GLuint h, GLbitfield mode, - GLubyte **mapOut, GLint *rowStrideOut) + GLubyte **mapOut, GLint *rowStrideOut, + bool flip_y) { struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); @@ -505,7 +507,7 @@ xmesa_MapRenderbuffer(struct gl_context *ctx, /* otherwise, this is an ordinary malloc-based renderbuffer */ _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode, - mapOut, rowStrideOut); + mapOut, rowStrideOut, false); } diff --git a/lib/mesa/src/mesa/gl.pc.in b/lib/mesa/src/mesa/gl.pc.in index 181724b97..680f74277 100644 --- a/lib/mesa/src/mesa/gl.pc.in +++ b/lib/mesa/src/mesa/gl.pc.in @@ -7,7 +7,7 @@ Name: gl Description: Mesa OpenGL library Requires.private: @GL_PC_REQ_PRIV@ Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -l@GL_LIB@ +Libs: -L${libdir} -l@GL_PKGCONF_LIB@ Libs.private: @GL_PC_LIB_PRIV@ Cflags: -I${includedir} @GL_PC_CFLAGS@ glx_tls: @GLX_TLS@ diff --git a/lib/mesa/src/mesa/main/barrier.h b/lib/mesa/src/mesa/main/barrier.h index 53ecf863f..acc15c677 100644 --- a/lib/mesa/src/mesa/main/barrier.h +++ b/lib/mesa/src/mesa/main/barrier.h @@ -53,4 +53,7 @@ _mesa_MemoryBarrierByRegion(GLbitfield barriers); void GLAPIENTRY _mesa_BlendBarrier(void); +void GLAPIENTRY +_mesa_FramebufferFetchBarrierEXT(void); + #endif /* BARRIER_H */ diff --git a/lib/mesa/src/mesa/main/colormac.h b/lib/mesa/src/mesa/main/colormac.h index 33ca5af07..8cd305cb3 100644 --- a/lib/mesa/src/mesa/main/colormac.h +++ b/lib/mesa/src/mesa/main/colormac.h @@ -35,7 +35,6 @@ #include "config.h" #include "macros.h" -#include "mtypes.h" /** diff --git a/lib/mesa/src/mesa/main/colortab.c b/lib/mesa/src/mesa/main/colortab.c index a8edb03dd..e8df73a0b 100644 --- a/lib/mesa/src/mesa/main/colortab.c +++ b/lib/mesa/src/mesa/main/colortab.c @@ -35,7 +35,6 @@ #include "state.h" #include "teximage.h" #include "texstate.h" -#include "main/dispatch.h" void GLAPIENTRY diff --git a/lib/mesa/src/mesa/main/conservativeraster.c b/lib/mesa/src/mesa/main/conservativeraster.c new file mode 100644 index 000000000..9068a00b4 --- /dev/null +++ b/lib/mesa/src/mesa/main/conservativeraster.c @@ -0,0 +1,128 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2018 Rhys Perry + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * \file conservativeraster.c + * glConservativeRasterParameteriNV and glConservativeRasterParameterfNV functions + */ + +#include "conservativeraster.h" +#include "context.h" +#include "enums.h" + +static ALWAYS_INLINE void +conservative_raster_parameter(GLenum pname, GLfloat param, + bool no_error, const char *func) +{ + GET_CURRENT_CONTEXT(ctx); + + if (!no_error && !ctx->Extensions.NV_conservative_raster_dilate && + !ctx->Extensions.NV_conservative_raster_pre_snap_triangles) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s not supported", func); + return; + } + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "%s(%s, %g)\n", + func, _mesa_enum_to_string(pname), param); + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (pname) { + case GL_CONSERVATIVE_RASTER_DILATE_NV: + if (!no_error && !ctx->Extensions.NV_conservative_raster_dilate) + goto invalid_pname_enum; + + if (!no_error && param<0.0) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(param=%g)", func, param); + return; + } + ctx->ConservativeRasterDilate = + CLAMP(param, + ctx->Const.ConservativeRasterDilateRange[0], + ctx->Const.ConservativeRasterDilateRange[1]); + break; + case GL_CONSERVATIVE_RASTER_MODE_NV: + if (!no_error && !ctx->Extensions.NV_conservative_raster_pre_snap_triangles) + goto invalid_pname_enum; + + if (!no_error && param != GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV && + param != GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(pname=%s)", func, _mesa_enum_to_string(param)); + return; + } + ctx->ConservativeRasterMode = param; + break; + default: + goto invalid_pname_enum; + break; + } + + FLUSH_VERTICES(ctx, 0); + ctx->NewDriverState |= + ctx->DriverFlags.NewNvConservativeRasterizationParams; + + return; +invalid_pname_enum: + if (!no_error) + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", + func, _mesa_enum_to_string(pname)); +} + +void GLAPIENTRY +_mesa_ConservativeRasterParameteriNV_no_error(GLenum pname, GLint param) +{ + conservative_raster_parameter(pname, param, true, + "glConservativeRasterParameteriNV"); +} + +void GLAPIENTRY +_mesa_ConservativeRasterParameteriNV(GLenum pname, GLint param) +{ + conservative_raster_parameter(pname, param, false, + "glConservativeRasterParameteriNV"); +} + +void GLAPIENTRY +_mesa_ConservativeRasterParameterfNV_no_error(GLenum pname, GLfloat param) +{ + conservative_raster_parameter(pname, param, true, + "glConservativeRasterParameterfNV"); +} + +void GLAPIENTRY +_mesa_ConservativeRasterParameterfNV(GLenum pname, GLfloat param) +{ + conservative_raster_parameter(pname, param, false, + "glConservativeRasterParameterfNV"); +} + +void +_mesa_init_conservative_raster(struct gl_context *ctx) +{ + ctx->ConservativeRasterDilate = 0.0; + ctx->ConservativeRasterMode = GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV; +} diff --git a/lib/mesa/src/mesa/main/conservativeraster.h b/lib/mesa/src/mesa/main/conservativeraster.h new file mode 100644 index 000000000..1865cfc2a --- /dev/null +++ b/lib/mesa/src/mesa/main/conservativeraster.h @@ -0,0 +1,48 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2018 Rhys Perry + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef CONSERVATIVERASTER_H +#define CONSERVATIVERASTER_H + +#include "glheader.h" + +struct gl_context; + +extern void GLAPIENTRY +_mesa_ConservativeRasterParameteriNV_no_error(GLenum pname, GLint param); + +extern void GLAPIENTRY +_mesa_ConservativeRasterParameteriNV(GLenum pname, GLint param); + +extern void GLAPIENTRY +_mesa_ConservativeRasterParameterfNV_no_error(GLenum pname, GLfloat param); + +extern void GLAPIENTRY +_mesa_ConservativeRasterParameterfNV(GLenum pname, GLfloat param); + +extern void +_mesa_init_conservative_raster(struct gl_context *ctx); + +#endif diff --git a/lib/mesa/src/mesa/main/convolve.c b/lib/mesa/src/mesa/main/convolve.c index 83d590f4a..e2c355c4f 100644 --- a/lib/mesa/src/mesa/main/convolve.c +++ b/lib/mesa/src/mesa/main/convolve.c @@ -34,7 +34,6 @@ #include "glheader.h" #include "context.h" #include "convolve.h" -#include "main/dispatch.h" void GLAPIENTRY diff --git a/lib/mesa/src/mesa/main/debug_output.h b/lib/mesa/src/mesa/main/debug_output.h index 9d8be4f22..8a5eedc21 100644 --- a/lib/mesa/src/mesa/main/debug_output.h +++ b/lib/mesa/src/mesa/main/debug_output.h @@ -29,15 +29,15 @@ #include <stdio.h> #include <stdarg.h> -#include "compiler.h" #include "glheader.h" -#include "mtypes.h" +#include "menums.h" #ifdef __cplusplus extern "C" { #endif +struct gl_context; void _mesa_init_debug_output(struct gl_context *ctx); diff --git a/lib/mesa/src/mesa/main/dlist.h b/lib/mesa/src/mesa/main/dlist.h index 22b696f50..1ac17d5bb 100644 --- a/lib/mesa/src/mesa/main/dlist.h +++ b/lib/mesa/src/mesa/main/dlist.h @@ -33,8 +33,8 @@ #define DLIST_H #include <stdio.h> -#include "main/mtypes.h" +struct gl_context; /** * Describes the location and size of a glBitmap image in a texture atlas. diff --git a/lib/mesa/src/mesa/main/draw.c b/lib/mesa/src/mesa/main/draw.c new file mode 100644 index 000000000..cceadf261 --- /dev/null +++ b/lib/mesa/src/mesa/main/draw.c @@ -0,0 +1,2262 @@ +/************************************************************************** + * + * Copyright 2003 VMware, Inc. + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <stdio.h> +#include "arrayobj.h" +#include "glheader.h" +#include "c99_alloca.h" +#include "context.h" +#include "state.h" +#include "draw.h" +#include "draw_validate.h" +#include "dispatch.h" +#include "varray.h" +#include "bufferobj.h" +#include "enums.h" +#include "macros.h" +#include "transformfeedback.h" + +typedef struct { + GLuint count; + GLuint primCount; + GLuint first; + GLuint baseInstance; +} DrawArraysIndirectCommand; + +typedef struct { + GLuint count; + GLuint primCount; + GLuint firstIndex; + GLint baseVertex; + GLuint baseInstance; +} DrawElementsIndirectCommand; + + +/** + * Check that element 'j' of the array has reasonable data. + * Map VBO if needed. + * For debugging purposes; not normally used. + */ +static void +check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao, + GLuint attrib, GLuint j) +{ + const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; + if (array->Enabled) { + const struct gl_vertex_buffer_binding *binding = + &vao->BufferBinding[array->BufferBindingIndex]; + struct gl_buffer_object *bo = binding->BufferObj; + const void *data = array->Ptr; + if (_mesa_is_bufferobj(bo)) { + if (!bo->Mappings[MAP_INTERNAL].Pointer) { + /* need to map now */ + bo->Mappings[MAP_INTERNAL].Pointer = + ctx->Driver.MapBufferRange(ctx, 0, bo->Size, + GL_MAP_READ_BIT, bo, MAP_INTERNAL); + } + data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding), + bo->Mappings[MAP_INTERNAL].Pointer); + } + switch (array->Type) { + case GL_FLOAT: + { + GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j); + GLint k; + for (k = 0; k < array->Size; k++) { + if (IS_INF_OR_NAN(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) { + printf("Bad array data:\n"); + printf(" Element[%u].%u = %f\n", j, k, f[k]); + printf(" Array %u at %p\n", attrib, (void *) array); + printf(" Type 0x%x, Size %d, Stride %d\n", + array->Type, array->Size, binding->Stride); + printf(" Address/offset %p in Buffer Object %u\n", + array->Ptr, bo->Name); + f[k] = 1.0F; /* XXX replace the bad value! */ + } + /*assert(!IS_INF_OR_NAN(f[k])); */ + } + } + break; + default: + ; + } + } +} + + +/** + * Unmap the buffer object referenced by given array, if mapped. + */ +static void +unmap_array_buffer(struct gl_context *ctx, struct gl_vertex_array_object *vao, + GLuint attrib) +{ + const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; + if (array->Enabled) { + const struct gl_vertex_buffer_binding *binding = + &vao->BufferBinding[array->BufferBindingIndex]; + struct gl_buffer_object *bo = binding->BufferObj; + if (_mesa_is_bufferobj(bo) && _mesa_bufferobj_mapped(bo, MAP_INTERNAL)) { + ctx->Driver.UnmapBuffer(ctx, bo, MAP_INTERNAL); + } + } +} + + +static inline int +sizeof_ib_type(GLenum type) +{ + switch (type) { + case GL_UNSIGNED_INT: + return sizeof(GLuint); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + default: + assert(!"unsupported index data type"); + /* In case assert is turned off */ + return 0; + } +} + +/** + * Examine the array's data for NaNs, etc. + * For debug purposes; not normally used. + */ +static void +check_draw_elements_data(struct gl_context *ctx, GLsizei count, + GLenum elemType, const void *elements, + GLint basevertex) +{ + struct gl_vertex_array_object *vao = ctx->Array.VAO; + const void *elemMap; + GLint i; + GLuint k; + + if (_mesa_is_bufferobj(vao->IndexBufferObj)) { + elemMap = ctx->Driver.MapBufferRange(ctx, 0, + vao->IndexBufferObj->Size, + GL_MAP_READ_BIT, + vao->IndexBufferObj, MAP_INTERNAL); + elements = ADD_POINTERS(elements, elemMap); + } + + for (i = 0; i < count; i++) { + GLuint j; + + /* j = element[i] */ + switch (elemType) { + case GL_UNSIGNED_BYTE: + j = ((const GLubyte *) elements)[i]; + break; + case GL_UNSIGNED_SHORT: + j = ((const GLushort *) elements)[i]; + break; + case GL_UNSIGNED_INT: + j = ((const GLuint *) elements)[i]; + break; + default: + unreachable("Unexpected index buffer type"); + } + + /* check element j of each enabled array */ + for (k = 0; k < VERT_ATTRIB_MAX; k++) { + check_array_data(ctx, vao, k, j); + } + } + + if (_mesa_is_bufferobj(vao->IndexBufferObj)) { + ctx->Driver.UnmapBuffer(ctx, vao->IndexBufferObj, MAP_INTERNAL); + } + + for (k = 0; k < VERT_ATTRIB_MAX; k++) { + unmap_array_buffer(ctx, vao, k); + } +} + + +/** + * Check array data, looking for NaNs, etc. + */ +static void +check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count) +{ + /* TO DO */ +} + + +/** + * Check if we should skip the draw call even after validation was successful. + */ +static bool +skip_validated_draw(struct gl_context *ctx) +{ + switch (ctx->API) { + case API_OPENGLES2: + /* For ES2, we can draw if we have a vertex program/shader). */ + return ctx->VertexProgram._Current == NULL; + + case API_OPENGLES: + /* For OpenGL ES, only draw if we have vertex positions + */ + if (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled) + return true; + break; + + case API_OPENGL_CORE: + /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec + * says: + * + * "If there is no active program for the vertex or fragment shader + * stages, the results of vertex and/or fragment processing will be + * undefined. However, this is not an error." + * + * The fragment shader is not tested here because other state (e.g., + * GL_RASTERIZER_DISCARD) affects whether or not we actually care. + */ + return ctx->VertexProgram._Current == NULL; + + case API_OPENGL_COMPAT: + if (ctx->VertexProgram._Current != NULL) { + /* Draw regardless of whether or not we have any vertex arrays. + * (Ex: could draw a point using a constant vertex pos) + */ + return false; + } else { + /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic + * array [0]). + */ + return (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled && + !ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled); + } + break; + + default: + unreachable("Invalid API value in check_valid_to_render()"); + } + + return false; +} + + +/** + * Print info/data for glDrawArrays(), for debugging. + */ +static void +print_draw_arrays(struct gl_context *ctx, + GLenum mode, GLint start, GLsizei count) +{ + const struct gl_vertex_array_object *vao = ctx->Array.VAO; + + printf("_mesa_exec_DrawArrays(mode 0x%x, start %d, count %d):\n", + mode, start, count); + + unsigned i; + for (i = 0; i < VERT_ATTRIB_MAX; ++i) { + const struct gl_array_attributes *array = &vao->VertexAttrib[i]; + if (!array->Enabled) + continue; + + const struct gl_vertex_buffer_binding *binding = + &vao->BufferBinding[array->BufferBindingIndex]; + struct gl_buffer_object *bufObj = binding->BufferObj; + + printf("attr %s: size %d stride %d enabled %d " + "ptr %p Bufobj %u\n", + gl_vert_attrib_name((gl_vert_attrib) i), + array->Size, binding->Stride, array->Enabled, + array->Ptr, bufObj->Name); + + if (_mesa_is_bufferobj(bufObj)) { + GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, + GL_MAP_READ_BIT, bufObj, + MAP_INTERNAL); + int offset = (int) (GLintptr) + _mesa_vertex_attrib_address(array, binding); + + unsigned multiplier; + switch (array->Type) { + case GL_DOUBLE: + case GL_INT64_ARB: + case GL_UNSIGNED_INT64_ARB: + multiplier = 2; + break; + default: + multiplier = 1; + } + + float *f = (float *) (p + offset); + int *k = (int *) f; + int i = 0; + int n = (count - 1) * (binding->Stride / (4 * multiplier)) + + array->Size; + if (n > 32) + n = 32; + printf(" Data at offset %d:\n", offset); + do { + if (multiplier == 2) + printf(" double[%d] = 0x%016llx %lf\n", i, + ((unsigned long long *) k)[i], ((double *) f)[i]); + else + printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); + i++; + } while (i < n); + ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL); + } + } +} + + +/** + * Return a filter mask for the net enabled vao arrays. + * This is to mask out arrays that would otherwise supersed required current + * values for the fixed function shaders for example. + */ +static GLbitfield +enabled_filter(const struct gl_context *ctx) +{ + switch (ctx->VertexProgram._VPMode) { + case VP_MODE_FF: + /* When no vertex program is active (or the vertex program is generated + * from fixed-function state). We put the material values into the + * generic slots. Since the vao has no material arrays, mute these + * slots from the enabled arrays so that the current material values + * are pulled instead of the vao arrays. + */ + return VERT_BIT_FF_ALL; + + case VP_MODE_SHADER: + /* There are no shaders in OpenGL ES 1.x, so this code path should be + * impossible to reach. The meta code is careful to not use shaders in + * ES1. + */ + assert(ctx->API != API_OPENGLES); + + /* Other parts of the code assume that inputs[VERT_ATTRIB_POS] through + * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL. However, in OpenGL + * ES 2.0+ or OpenGL core profile, none of these arrays should ever + * be enabled. + */ + if (ctx->API != API_OPENGL_COMPAT) + return VERT_BIT_GENERIC_ALL; + + return VERT_BIT_ALL; + + default: + assert(0); + return 0; + } +} + + +/** + * Helper function called by the other DrawArrays() functions below. + * This is where we handle primitive restart for drawing non-indexed + * arrays. If primitive restart is enabled, it typically means + * splitting one DrawArrays() into two. + */ +static void +_mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, + GLsizei count, GLuint numInstances, GLuint baseInstance, + GLuint drawID) +{ + struct _mesa_prim prim; + + if (skip_validated_draw(ctx)) + return; + + /* OpenGL 4.5 says that primitive restart is ignored with non-indexed + * draws. + */ + memset(&prim, 0, sizeof(prim)); + prim.begin = 1; + prim.end = 1; + prim.mode = mode; + prim.num_instances = numInstances; + prim.base_instance = baseInstance; + prim.draw_id = drawID; + prim.is_indirect = 0; + prim.start = start; + prim.count = count; + + ctx->Driver.Draw(ctx, &prim, 1, NULL, + GL_TRUE, start, start + count - 1, NULL, 0, NULL); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } +} + + +/** + * Execute a glRectf() function. + */ +static void GLAPIENTRY +_mesa_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + CALL_Begin(GET_DISPATCH(), (GL_QUADS)); + CALL_Vertex2f(GET_DISPATCH(), (x1, y1)); + CALL_Vertex2f(GET_DISPATCH(), (x2, y1)); + CALL_Vertex2f(GET_DISPATCH(), (x2, y2)); + CALL_Vertex2f(GET_DISPATCH(), (x1, y2)); + CALL_End(GET_DISPATCH(), ()); +} + + +static void GLAPIENTRY +_mesa_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + GLfloat u, du; + GLenum prim; + + switch (mode) { + case GL_POINT: + prim = GL_POINTS; + break; + case GL_LINE: + prim = GL_LINE_STRIP; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)"); + return; + } + + /* No effect if vertex maps disabled. + */ + if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) + return; + + du = ctx->Eval.MapGrid1du; + u = ctx->Eval.MapGrid1u1 + i1 * du; + + CALL_Begin(GET_DISPATCH(), (prim)); + for (i = i1; i <= i2; i++, u += du) { + CALL_EvalCoord1f(GET_DISPATCH(), (u)); + } + CALL_End(GET_DISPATCH(), ()); +} + + +static void GLAPIENTRY +_mesa_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat u, du, v, dv, v1, u1; + GLint i, j; + + switch (mode) { + case GL_POINT: + case GL_LINE: + case GL_FILL: + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)"); + return; + } + + /* No effect if vertex maps disabled. + */ + if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) + return; + + du = ctx->Eval.MapGrid2du; + dv = ctx->Eval.MapGrid2dv; + v1 = ctx->Eval.MapGrid2v1 + j1 * dv; + u1 = ctx->Eval.MapGrid2u1 + i1 * du; + + switch (mode) { + case GL_POINT: + CALL_Begin(GET_DISPATCH(), (GL_POINTS)); + for (v = v1, j = j1; j <= j2; j++, v += dv) { + for (u = u1, i = i1; i <= i2; i++, u += du) { + CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); + } + } + CALL_End(GET_DISPATCH(), ()); + break; + case GL_LINE: + for (v = v1, j = j1; j <= j2; j++, v += dv) { + CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); + for (u = u1, i = i1; i <= i2; i++, u += du) { + CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); + } + CALL_End(GET_DISPATCH(), ()); + } + for (u = u1, i = i1; i <= i2; i++, u += du) { + CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); + for (v = v1, j = j1; j <= j2; j++, v += dv) { + CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); + } + CALL_End(GET_DISPATCH(), ()); + } + break; + case GL_FILL: + for (v = v1, j = j1; j < j2; j++, v += dv) { + CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP)); + for (u = u1, i = i1; i <= i2; i++, u += du) { + CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); + CALL_EvalCoord2f(GET_DISPATCH(), (u, v + dv)); + } + CALL_End(GET_DISPATCH(), ()); + } + break; + } +} + + +/** + * Called from glDrawArrays when in immediate mode (not display list mode). + */ +static void GLAPIENTRY +_mesa_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n", + _mesa_enum_to_string(mode), start, count); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawArrays(ctx, mode, count)) + return; + } + + if (0) + check_draw_arrays_data(ctx, start, count); + + _mesa_draw_arrays(ctx, mode, start, count, 1, 0, 0); + + if (0) + print_draw_arrays(ctx, mode, start, count); +} + + +/** + * Called from glDrawArraysInstanced when in immediate mode (not + * display list mode). + */ +static void GLAPIENTRY +_mesa_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count, + GLsizei numInstances) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n", + _mesa_enum_to_string(mode), start, count, numInstances); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, + numInstances)) + return; + } + + if (0) + check_draw_arrays_data(ctx, start, count); + + _mesa_draw_arrays(ctx, mode, start, count, numInstances, 0, 0); + + if (0) + print_draw_arrays(ctx, mode, start, count); +} + + +/** + * Called from glDrawArraysInstancedBaseInstance when in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, + GLsizei count, GLsizei numInstances, + GLuint baseInstance) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, + "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n", + _mesa_enum_to_string(mode), first, count, + numInstances, baseInstance); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count, + numInstances)) + return; + } + + if (0) + check_draw_arrays_data(ctx, first, count); + + _mesa_draw_arrays(ctx, mode, first, count, numInstances, baseInstance, 0); + + if (0) + print_draw_arrays(ctx, mode, first, count); +} + + +/** + * Called from glMultiDrawArrays when in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_MultiDrawArrays(GLenum mode, const GLint *first, + const GLsizei *count, GLsizei primcount) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, + "glMultiDrawArrays(%s, %p, %p, %d)\n", + _mesa_enum_to_string(mode), first, count, primcount); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount)) + return; + } + + for (i = 0; i < primcount; i++) { + if (count[i] > 0) { + if (0) + check_draw_arrays_data(ctx, first[i], count[i]); + + /* The GL_ARB_shader_draw_parameters spec adds the following after the + * pseudo-code describing glMultiDrawArrays: + * + * "The index of the draw (<i> in the above pseudo-code) may be + * read by a vertex shader as <gl_DrawIDARB>, as described in + * Section 11.1.3.9." + */ + _mesa_draw_arrays(ctx, mode, first[i], count[i], 1, 0, i); + + if (0) + print_draw_arrays(ctx, mode, first[i], count[i]); + } + } +} + + + +/** + * Map GL_ELEMENT_ARRAY_BUFFER and print contents. + * For debugging. + */ +#if 0 +static void +dump_element_buffer(struct gl_context *ctx, GLenum type) +{ + const GLvoid *map = + ctx->Driver.MapBufferRange(ctx, 0, + ctx->Array.VAO->IndexBufferObj->Size, + GL_MAP_READ_BIT, + ctx->Array.VAO->IndexBufferObj, + MAP_INTERNAL); + switch (type) { + case GL_UNSIGNED_BYTE: + { + const GLubyte *us = (const GLubyte *) map; + GLint i; + for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size; i++) { + printf("%02x ", us[i]); + if (i % 32 == 31) + printf("\n"); + } + printf("\n"); + } + break; + case GL_UNSIGNED_SHORT: + { + const GLushort *us = (const GLushort *) map; + GLint i; + for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 2; i++) { + printf("%04x ", us[i]); + if (i % 16 == 15) + printf("\n"); + } + printf("\n"); + } + break; + case GL_UNSIGNED_INT: + { + const GLuint *us = (const GLuint *) map; + GLint i; + for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 4; i++) { + printf("%08x ", us[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + } + break; + default: + ; + } + + ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj, MAP_INTERNAL); +} +#endif + + +static bool +skip_draw_elements(struct gl_context *ctx, GLsizei count, + const GLvoid *indices) +{ + if (count == 0) + return true; + + /* Not using a VBO for indices, so avoid NULL pointer derefs later. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL) + return true; + + if (skip_validated_draw(ctx)) + return true; + + return false; +} + + +/** + * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. + * Do the rendering for a glDrawElements or glDrawRangeElements call after + * we've validated buffer bounds, etc. + */ +static void +_mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, + GLboolean index_bounds_valid, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid * indices, + GLint basevertex, GLuint numInstances, + GLuint baseInstance) +{ + struct _mesa_index_buffer ib; + struct _mesa_prim prim; + + if (!index_bounds_valid) { + assert(start == 0u); + assert(end == ~0u); + } + + if (skip_draw_elements(ctx, count, indices)) + return; + + ib.count = count; + ib.index_size = sizeof_ib_type(type); + ib.obj = ctx->Array.VAO->IndexBufferObj; + ib.ptr = indices; + + prim.begin = 1; + prim.end = 1; + prim.pad = 0; + prim.mode = mode; + prim.start = 0; + prim.count = count; + prim.indexed = 1; + prim.is_indirect = 0; + prim.basevertex = basevertex; + prim.num_instances = numInstances; + prim.base_instance = baseInstance; + prim.draw_id = 0; + + /* Need to give special consideration to rendering a range of + * indices starting somewhere above zero. Typically the + * application is issuing multiple DrawRangeElements() to draw + * successive primitives layed out linearly in the vertex arrays. + * Unless the vertex arrays are all in a VBO (or locked as with + * CVA), the OpenGL semantics imply that we need to re-read or + * re-upload the vertex data on each draw call. + * + * In the case of hardware tnl, we want to avoid starting the + * upload at zero, as it will mean every draw call uploads an + * increasing amount of not-used vertex data. Worse - in the + * software tnl module, all those vertices might be transformed and + * lit but never rendered. + * + * If we just upload or transform the vertices in start..end, + * however, the indices will be incorrect. + * + * At this level, we don't know exactly what the requirements of + * the backend are going to be, though it will likely boil down to + * either: + * + * 1) Do nothing, everything is in a VBO and is processed once + * only. + * + * 2) Adjust the indices and vertex arrays so that start becomes + * zero. + * + * Rather than doing anything here, I'll provide a helper function + * for the latter case elsewhere. + */ + + ctx->Driver.Draw(ctx, &prim, 1, &ib, + index_bounds_valid, start, end, NULL, 0, NULL); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } +} + + +/** + * Called by glDrawRangeElementsBaseVertex() in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid * indices, GLint basevertex) +{ + static GLuint warnCount = 0; + GLboolean index_bounds_valid = GL_TRUE; + + /* This is only useful to catch invalid values in the "end" parameter + * like ~0. + */ + GLuint max_element = 2 * 1000 * 1000 * 1000; /* just a big number */ + + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, + "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n", + _mesa_enum_to_string(mode), start, end, count, + _mesa_enum_to_string(type), indices, basevertex); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawRangeElements(ctx, mode, start, end, count, + type, indices)) + return; + } + + if ((int) end + basevertex < 0 || start + basevertex >= max_element) { + /* The application requested we draw using a range of indices that's + * outside the bounds of the current VBO. This is invalid and appears + * to give undefined results. The safest thing to do is to simply + * ignore the range, in case the application botched their range tracking + * but did provide valid indices. Also issue a warning indicating that + * the application is broken. + */ + if (warnCount++ < 10) { + _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, " + "basevertex %d, count %d, type 0x%x, indices=%p):\n" + "\trange is outside VBO bounds (max=%u); ignoring.\n" + "\tThis should be fixed in the application.", + start, end, basevertex, count, type, indices, + max_element - 1); + } + index_bounds_valid = GL_FALSE; + } + + /* NOTE: It's important that 'end' is a reasonable value. + * in _tnl_draw_prims(), we use end to determine how many vertices + * to transform. If it's too large, we can unnecessarily split prims + * or we can read/write out of memory in several different places! + */ + + /* Catch/fix some potential user errors */ + if (type == GL_UNSIGNED_BYTE) { + start = MIN2(start, 0xff); + end = MIN2(end, 0xff); + } + else if (type == GL_UNSIGNED_SHORT) { + start = MIN2(start, 0xffff); + end = MIN2(end, 0xffff); + } + + if (0) { + printf("glDraw[Range]Elements{,BaseVertex}" + "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, " + "base %d\n", + start, end, type, count, + ctx->Array.VAO->IndexBufferObj->Name, basevertex); + } + + if ((int) start + basevertex < 0 || end + basevertex >= max_element) + index_bounds_valid = GL_FALSE; + +#if 0 + check_draw_elements_data(ctx, count, type, indices, basevertex); +#else + (void) check_draw_elements_data; +#endif + + if (!index_bounds_valid) { + start = 0; + end = ~0; + } + + _mesa_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end, + count, type, indices, basevertex, 1, 0); +} + + +/** + * Called by glDrawRangeElements() in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, const GLvoid * indices) +{ + if (MESA_VERBOSE & VERBOSE_DRAW) { + GET_CURRENT_CONTEXT(ctx); + _mesa_debug(ctx, + "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n", + _mesa_enum_to_string(mode), start, end, count, + _mesa_enum_to_string(type), indices); + } + + _mesa_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, + indices, 0); +} + + +/** + * Called by glDrawElements() in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid * indices) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", + _mesa_enum_to_string(mode), count, + _mesa_enum_to_string(type), indices); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices)) + return; + } + + _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, + count, type, indices, 0, 1, 0); +} + + +/** + * Called by glDrawElementsBaseVertex() in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, + const GLvoid * indices, GLint basevertex) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", + _mesa_enum_to_string(mode), count, + _mesa_enum_to_string(type), indices); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices)) + return; + } + + _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, + count, type, indices, basevertex, 1, 0); +} + + +/** + * Called by glDrawElementsInstanced() in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, + const GLvoid * indices, GLsizei numInstances) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", + _mesa_enum_to_string(mode), count, + _mesa_enum_to_string(type), indices); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, + indices, numInstances)) + return; + } + + _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, + count, type, indices, 0, numInstances, 0); +} + + +/** + * Called by glDrawElementsInstancedBaseVertex() in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, + GLenum type, const GLvoid * indices, + GLsizei numInstances, + GLint basevertex) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, + "glDrawElementsInstancedBaseVertex" + "(%s, %d, %s, %p, %d; %d)\n", + _mesa_enum_to_string(mode), count, + _mesa_enum_to_string(type), indices, + numInstances, basevertex); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, + indices, numInstances)) + return; + } + + _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, + count, type, indices, + basevertex, numInstances, 0); +} + + +/** + * Called by glDrawElementsInstancedBaseInstance() in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei numInstances, + GLuint baseInstance) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, + "glDrawElementsInstancedBaseInstance" + "(%s, %d, %s, %p, %d, %d)\n", + _mesa_enum_to_string(mode), count, + _mesa_enum_to_string(type), indices, + numInstances, baseInstance); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, + indices, numInstances)) + return; + } + + _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, + count, type, indices, 0, numInstances, + baseInstance); +} + + +/** + * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode. + */ +static void GLAPIENTRY +_mesa_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei numInstances, + GLint basevertex, + GLuint baseInstance) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, + "glDrawElementsInstancedBaseVertexBaseInstance" + "(%s, %d, %s, %p, %d, %d, %d)\n", + _mesa_enum_to_string(mode), count, + _mesa_enum_to_string(type), indices, + numInstances, basevertex, baseInstance); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, + indices, numInstances)) + return; + } + + _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, + count, type, indices, basevertex, + numInstances, baseInstance); +} + + +/** + * Inner support for both _mesa_MultiDrawElements() and + * _mesa_MultiDrawRangeElements(). + * This does the actual rendering after we've checked array indexes, etc. + */ +static void +_mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, + const GLsizei *count, GLenum type, + const GLvoid * const *indices, + GLsizei primcount, const GLint *basevertex) +{ + struct _mesa_index_buffer ib; + struct _mesa_prim *prim; + unsigned int index_type_size = sizeof_ib_type(type); + uintptr_t min_index_ptr, max_index_ptr; + GLboolean fallback = GL_FALSE; + int i; + + if (primcount == 0) + return; + + prim = calloc(primcount, sizeof(*prim)); + if (prim == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements"); + return; + } + + min_index_ptr = (uintptr_t) indices[0]; + max_index_ptr = 0; + for (i = 0; i < primcount; i++) { + min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]); + max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] + + index_type_size * count[i]); + } + + /* Check if we can handle this thing as a bunch of index offsets from the + * same index pointer. If we can't, then we have to fall back to doing + * a draw_prims per primitive. + * Check that the difference between each prim's indexes is a multiple of + * the index/element size. + */ + if (index_type_size != 1) { + for (i = 0; i < primcount; i++) { + if ((((uintptr_t) indices[i] - min_index_ptr) % index_type_size) != + 0) { + fallback = GL_TRUE; + break; + } + } + } + + /* Draw primitives individually if one count is zero, so we can easily skip + * that primitive. + */ + for (i = 0; i < primcount; i++) { + if (count[i] == 0) { + fallback = GL_TRUE; + break; + } + } + + /* If the index buffer isn't in a VBO, then treating the application's + * subranges of the index buffer as one large index buffer may lead to + * us reading unmapped memory. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) + fallback = GL_TRUE; + + if (!fallback) { + ib.count = (max_index_ptr - min_index_ptr) / index_type_size; + ib.index_size = sizeof_ib_type(type); + ib.obj = ctx->Array.VAO->IndexBufferObj; + ib.ptr = (void *) min_index_ptr; + + for (i = 0; i < primcount; i++) { + prim[i].begin = (i == 0); + prim[i].end = (i == primcount - 1); + prim[i].pad = 0; + prim[i].mode = mode; + prim[i].start = + ((uintptr_t) indices[i] - min_index_ptr) / index_type_size; + prim[i].count = count[i]; + prim[i].indexed = 1; + prim[i].num_instances = 1; + prim[i].base_instance = 0; + prim[i].draw_id = i; + prim[i].is_indirect = 0; + if (basevertex != NULL) + prim[i].basevertex = basevertex[i]; + else + prim[i].basevertex = 0; + } + + ctx->Driver.Draw(ctx, prim, primcount, &ib, + false, 0, ~0, NULL, 0, NULL); + } + else { + /* render one prim at a time */ + for (i = 0; i < primcount; i++) { + if (count[i] == 0) + continue; + ib.count = count[i]; + ib.index_size = sizeof_ib_type(type); + ib.obj = ctx->Array.VAO->IndexBufferObj; + ib.ptr = indices[i]; + + prim[0].begin = 1; + prim[0].end = 1; + prim[0].pad = 0; + prim[0].mode = mode; + prim[0].start = 0; + prim[0].count = count[i]; + prim[0].indexed = 1; + prim[0].num_instances = 1; + prim[0].base_instance = 0; + prim[0].draw_id = i; + prim[0].is_indirect = 0; + if (basevertex != NULL) + prim[0].basevertex = basevertex[i]; + else + prim[0].basevertex = 0; + + ctx->Driver.Draw(ctx, prim, 1, &ib, false, 0, ~0, NULL, 0, NULL); + } + } + + free(prim); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } +} + + +static void GLAPIENTRY +_mesa_exec_MultiDrawElements(GLenum mode, + const GLsizei *count, GLenum type, + const GLvoid * const *indices, GLsizei primcount) +{ + GET_CURRENT_CONTEXT(ctx); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, + primcount)) + return; + + if (skip_validated_draw(ctx)) + return; + + _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount, + NULL); +} + + +static void GLAPIENTRY +_mesa_exec_MultiDrawElementsBaseVertex(GLenum mode, + const GLsizei *count, GLenum type, + const GLvoid * const *indices, + GLsizei primcount, + const GLsizei *basevertex) +{ + GET_CURRENT_CONTEXT(ctx); + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, + primcount)) + return; + } + + if (skip_validated_draw(ctx)) + return; + + _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount, + basevertex); +} + + +/** + * Draw a GL primitive using a vertex count obtained from transform feedback. + * \param mode the type of GL primitive to draw + * \param obj the transform feedback object to use + * \param stream index of the transform feedback stream from which to + * get the primitive count. + * \param numInstances number of instances to draw + */ +static void +_mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode, + struct gl_transform_feedback_object *obj, + GLuint stream, GLuint numInstances) +{ + struct _mesa_prim prim; + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream, + numInstances)) { + return; + } + } + + if (ctx->Driver.GetTransformFeedbackVertexCount && + (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount || + !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) { + GLsizei n = + ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream); + _mesa_draw_arrays(ctx, mode, 0, n, numInstances, 0, 0); + return; + } + + if (skip_validated_draw(ctx)) + return; + + /* init most fields to zero */ + memset(&prim, 0, sizeof(prim)); + prim.begin = 1; + prim.end = 1; + prim.mode = mode; + prim.num_instances = numInstances; + prim.base_instance = 0; + prim.is_indirect = 0; + + /* Maybe we should do some primitive splitting for primitive restart + * (like in DrawArrays), but we have no way to know how many vertices + * will be rendered. */ + + ctx->Driver.Draw(ctx, &prim, 1, NULL, GL_FALSE, 0, ~0, obj, stream, NULL); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } +} + + +/** + * Like DrawArrays, but take the count from a transform feedback object. + * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. + * \param name the transform feedback object + * User still has to setup of the vertex attribute info with + * glVertexPointer, glColorPointer, etc. + * Part of GL_ARB_transform_feedback2. + */ +static void GLAPIENTRY +_mesa_exec_DrawTransformFeedback(GLenum mode, GLuint name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_transform_feedback_object *obj = + _mesa_lookup_transform_feedback_object(ctx, name); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n", + _mesa_enum_to_string(mode), name); + + _mesa_draw_transform_feedback(ctx, mode, obj, 0, 1); +} + + +static void GLAPIENTRY +_mesa_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_transform_feedback_object *obj = + _mesa_lookup_transform_feedback_object(ctx, name); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n", + _mesa_enum_to_string(mode), name, stream); + + _mesa_draw_transform_feedback(ctx, mode, obj, stream, 1); +} + + +static void GLAPIENTRY +_mesa_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, + GLsizei primcount) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_transform_feedback_object *obj = + _mesa_lookup_transform_feedback_object(ctx, name); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n", + _mesa_enum_to_string(mode), name); + + _mesa_draw_transform_feedback(ctx, mode, obj, 0, primcount); +} + + +static void GLAPIENTRY +_mesa_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, + GLuint stream, + GLsizei primcount) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_transform_feedback_object *obj = + _mesa_lookup_transform_feedback_object(ctx, name); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced" + "(%s, %u, %u, %i)\n", + _mesa_enum_to_string(mode), name, stream, primcount); + + _mesa_draw_transform_feedback(ctx, mode, obj, stream, primcount); +} + + +static void +_mesa_validated_drawarraysindirect(struct gl_context *ctx, + GLenum mode, const GLvoid *indirect) +{ + ctx->Driver.DrawIndirect(ctx, mode, + ctx->DrawIndirectBuffer, (GLsizeiptr) indirect, + 1 /* draw_count */ , 16 /* stride */ , + NULL, 0, NULL); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) + _mesa_flush(ctx); +} + + +static void +_mesa_validated_multidrawarraysindirect(struct gl_context *ctx, + GLenum mode, + const GLvoid *indirect, + GLsizei primcount, GLsizei stride) +{ + GLsizeiptr offset = (GLsizeiptr) indirect; + + if (primcount == 0) + return; + + ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, offset, + primcount, stride, NULL, 0, NULL); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) + _mesa_flush(ctx); +} + + +static void +_mesa_validated_drawelementsindirect(struct gl_context *ctx, + GLenum mode, GLenum type, + const GLvoid *indirect) +{ + struct _mesa_index_buffer ib; + + ib.count = 0; /* unknown */ + ib.index_size = sizeof_ib_type(type); + ib.obj = ctx->Array.VAO->IndexBufferObj; + ib.ptr = NULL; + + ctx->Driver.DrawIndirect(ctx, mode, + ctx->DrawIndirectBuffer, (GLsizeiptr) indirect, + 1 /* draw_count */ , 20 /* stride */ , + NULL, 0, &ib); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) + _mesa_flush(ctx); +} + + +static void +_mesa_validated_multidrawelementsindirect(struct gl_context *ctx, + GLenum mode, GLenum type, + const GLvoid *indirect, + GLsizei primcount, GLsizei stride) +{ + struct _mesa_index_buffer ib; + GLsizeiptr offset = (GLsizeiptr) indirect; + + if (primcount == 0) + return; + + /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ + + ib.count = 0; /* unknown */ + ib.index_size = sizeof_ib_type(type); + ib.obj = ctx->Array.VAO->IndexBufferObj; + ib.ptr = NULL; + + ctx->Driver.DrawIndirect(ctx, mode, + ctx->DrawIndirectBuffer, offset, + primcount, stride, NULL, 0, &ib); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) + _mesa_flush(ctx); +} + + +/** + * Like [Multi]DrawArrays/Elements, but they take most arguments from + * a buffer object. + */ +static void GLAPIENTRY +_mesa_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n", + _mesa_enum_to_string(mode), indirect); + + /* From the ARB_draw_indirect spec: + * + * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the + * compatibility profile, this indicates that DrawArraysIndirect and + * DrawElementsIndirect are to source their arguments directly from the + * pointer passed as their <indirect> parameters." + */ + if (ctx->API == API_OPENGL_COMPAT && + !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { + DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) indirect; + + _mesa_exec_DrawArraysInstancedBaseInstance(mode, cmd->first, cmd->count, + cmd->primCount, + cmd->baseInstance); + return; + } + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect)) + return; + } + + if (skip_validated_draw(ctx)) + return; + + _mesa_validated_drawarraysindirect(ctx, mode, indirect); +} + + +static void GLAPIENTRY +_mesa_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawElementsIndirect(%s, %s, %p)\n", + _mesa_enum_to_string(mode), + _mesa_enum_to_string(type), indirect); + + /* From the ARB_draw_indirect spec: + * + * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the + * compatibility profile, this indicates that DrawArraysIndirect and + * DrawElementsIndirect are to source their arguments directly from the + * pointer passed as their <indirect> parameters." + */ + if (ctx->API == API_OPENGL_COMPAT && + !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { + /* + * Unlike regular DrawElementsInstancedBaseVertex commands, the indices + * may not come from a client array and must come from an index buffer. + * If no element array buffer is bound, an INVALID_OPERATION error is + * generated. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawElementsIndirect(no buffer bound " + "to GL_ELEMENT_ARRAY_BUFFER)"); + } else { + DrawElementsIndirectCommand *cmd = + (DrawElementsIndirectCommand *) indirect; + + /* Convert offset to pointer */ + void *offset = (void *) + ((cmd->firstIndex * _mesa_sizeof_type(type)) & 0xffffffffUL); + + _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance(mode, cmd->count, + type, offset, + cmd->primCount, + cmd->baseVertex, + cmd->baseInstance); + } + + return; + } + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect)) + return; + } + + if (skip_validated_draw(ctx)) + return; + + _mesa_validated_drawelementsindirect(ctx, mode, type, indirect); +} + + +static void GLAPIENTRY +_mesa_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, + GLsizei primcount, GLsizei stride) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glMultiDrawArraysIndirect(%s, %p, %i, %i)\n", + _mesa_enum_to_string(mode), indirect, primcount, stride); + + /* If <stride> is zero, the array elements are treated as tightly packed. */ + if (stride == 0) + stride = sizeof(DrawArraysIndirectCommand); + + /* From the ARB_draw_indirect spec: + * + * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the + * compatibility profile, this indicates that DrawArraysIndirect and + * DrawElementsIndirect are to source their arguments directly from the + * pointer passed as their <indirect> parameters." + */ + if (ctx->API == API_OPENGL_COMPAT && + !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { + + if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, + "glMultiDrawArraysIndirect")) + return; + + const ubyte *ptr = (const ubyte *) indirect; + for (unsigned i = 0; i < primcount; i++) { + DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr; + _mesa_exec_DrawArraysInstancedBaseInstance(mode, cmd->first, + cmd->count, cmd->primCount, + cmd->baseInstance); + + if (stride == 0) { + ptr += sizeof(DrawArraysIndirectCommand); + } else { + ptr += stride; + } + } + + return; + } + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect, + primcount, stride)) + return; + } + + if (skip_validated_draw(ctx)) + return; + + _mesa_validated_multidrawarraysindirect(ctx, mode, indirect, + primcount, stride); +} + + +static void GLAPIENTRY +_mesa_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type, + const GLvoid *indirect, + GLsizei primcount, GLsizei stride) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glMultiDrawElementsIndirect(%s, %s, %p, %i, %i)\n", + _mesa_enum_to_string(mode), + _mesa_enum_to_string(type), indirect, primcount, stride); + + /* If <stride> is zero, the array elements are treated as tightly packed. */ + if (stride == 0) + stride = sizeof(DrawElementsIndirectCommand); + + + /* From the ARB_draw_indirect spec: + * + * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the + * compatibility profile, this indicates that DrawArraysIndirect and + * DrawElementsIndirect are to source their arguments directly from the + * pointer passed as their <indirect> parameters." + */ + if (ctx->API == API_OPENGL_COMPAT && + !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { + /* + * Unlike regular DrawElementsInstancedBaseVertex commands, the indices + * may not come from a client array and must come from an index buffer. + * If no element array buffer is bound, an INVALID_OPERATION error is + * generated. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glMultiDrawElementsIndirect(no buffer bound " + "to GL_ELEMENT_ARRAY_BUFFER)"); + + return; + } + + if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, + "glMultiDrawArraysIndirect")) + return; + + const ubyte *ptr = (const ubyte *) indirect; + for (unsigned i = 0; i < primcount; i++) { + _mesa_exec_DrawElementsIndirect(mode, type, ptr); + + if (stride == 0) { + ptr += sizeof(DrawElementsIndirectCommand); + } else { + ptr += stride; + } + } + + return; + } + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect, + primcount, stride)) + return; + } + + if (skip_validated_draw(ctx)) + return; + + _mesa_validated_multidrawelementsindirect(ctx, mode, type, indirect, + primcount, stride); +} + + +static void +_mesa_validated_multidrawarraysindirectcount(struct gl_context *ctx, + GLenum mode, + GLintptr indirect, + GLintptr drawcount_offset, + GLsizei maxdrawcount, + GLsizei stride) +{ + GLsizeiptr offset = indirect; + + if (maxdrawcount == 0) + return; + + ctx->Driver.DrawIndirect(ctx, mode, + ctx->DrawIndirectBuffer, offset, + maxdrawcount, stride, + ctx->ParameterBuffer, drawcount_offset, NULL); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) + _mesa_flush(ctx); +} + + +static void +_mesa_validated_multidrawelementsindirectcount(struct gl_context *ctx, + GLenum mode, GLenum type, + GLintptr indirect, + GLintptr drawcount_offset, + GLsizei maxdrawcount, + GLsizei stride) +{ + struct _mesa_index_buffer ib; + GLsizeiptr offset = (GLsizeiptr) indirect; + + if (maxdrawcount == 0) + return; + + /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ + + ib.count = 0; /* unknown */ + ib.index_size = sizeof_ib_type(type); + ib.obj = ctx->Array.VAO->IndexBufferObj; + ib.ptr = NULL; + + ctx->Driver.DrawIndirect(ctx, mode, + ctx->DrawIndirectBuffer, offset, + maxdrawcount, stride, + ctx->ParameterBuffer, drawcount_offset, &ib); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) + _mesa_flush(ctx); +} + + +static void GLAPIENTRY +_mesa_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect, + GLintptr drawcount_offset, + GLsizei maxdrawcount, GLsizei stride) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glMultiDrawArraysIndirectCountARB" + "(%s, %lx, %lx, %i, %i)\n", + _mesa_enum_to_string(mode), + (unsigned long) indirect, (unsigned long) drawcount_offset, + maxdrawcount, stride); + + /* If <stride> is zero, the array elements are treated as tightly packed. */ + if (stride == 0) + stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */ + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode, + indirect, + drawcount_offset, + maxdrawcount, stride)) + return; + } + + if (skip_validated_draw(ctx)) + return; + + _mesa_validated_multidrawarraysindirectcount(ctx, mode, indirect, + drawcount_offset, + maxdrawcount, stride); +} + + +static void GLAPIENTRY +_mesa_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type, + GLintptr indirect, + GLintptr drawcount_offset, + GLsizei maxdrawcount, GLsizei stride) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glMultiDrawElementsIndirectCountARB" + "(%s, %s, %lx, %lx, %i, %i)\n", + _mesa_enum_to_string(mode), _mesa_enum_to_string(type), + (unsigned long) indirect, (unsigned long) drawcount_offset, + maxdrawcount, stride); + + /* If <stride> is zero, the array elements are treated as tightly packed. */ + if (stride == 0) + stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */ + + FLUSH_FOR_DRAW(ctx); + + _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); + + if (_mesa_is_no_error_enabled(ctx)) { + if (ctx->NewState) + _mesa_update_state(ctx); + } else { + if (!_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type, + indirect, + drawcount_offset, + maxdrawcount, stride)) + return; + } + + if (skip_validated_draw(ctx)) + return; + + _mesa_validated_multidrawelementsindirectcount(ctx, mode, type, indirect, + drawcount_offset, maxdrawcount, + stride); +} + + +/** + * Initialize the dispatch table with the VBO functions for drawing. + */ +void +_mesa_initialize_exec_dispatch(const struct gl_context *ctx, + struct _glapi_table *exec) +{ + SET_DrawArrays(exec, _mesa_exec_DrawArrays); + SET_DrawElements(exec, _mesa_exec_DrawElements); + + if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { + SET_DrawRangeElements(exec, _mesa_exec_DrawRangeElements); + } + + SET_MultiDrawArrays(exec, _mesa_exec_MultiDrawArrays); + SET_MultiDrawElementsEXT(exec, _mesa_exec_MultiDrawElements); + + if (ctx->API == API_OPENGL_COMPAT) { + SET_Rectf(exec, _mesa_exec_Rectf); + SET_EvalMesh1(exec, _mesa_exec_EvalMesh1); + SET_EvalMesh2(exec, _mesa_exec_EvalMesh2); + } + + if (ctx->API != API_OPENGLES && + ctx->Extensions.ARB_draw_elements_base_vertex) { + SET_DrawElementsBaseVertex(exec, _mesa_exec_DrawElementsBaseVertex); + SET_MultiDrawElementsBaseVertex(exec, + _mesa_exec_MultiDrawElementsBaseVertex); + + if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { + SET_DrawRangeElementsBaseVertex(exec, + _mesa_exec_DrawRangeElementsBaseVertex); + SET_DrawElementsInstancedBaseVertex(exec, + _mesa_exec_DrawElementsInstancedBaseVertex); + } + } + + if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { + SET_DrawArraysInstancedBaseInstance(exec, + _mesa_exec_DrawArraysInstancedBaseInstance); + SET_DrawElementsInstancedBaseInstance(exec, + _mesa_exec_DrawElementsInstancedBaseInstance); + SET_DrawElementsInstancedBaseVertexBaseInstance(exec, + _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance); + } + + if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) { + SET_DrawArraysIndirect(exec, _mesa_exec_DrawArraysIndirect); + SET_DrawElementsIndirect(exec, _mesa_exec_DrawElementsIndirect); + } + + if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { + SET_DrawArraysInstancedARB(exec, _mesa_exec_DrawArraysInstanced); + SET_DrawElementsInstancedARB(exec, _mesa_exec_DrawElementsInstanced); + } + + if (_mesa_is_desktop_gl(ctx)) { + SET_DrawTransformFeedback(exec, _mesa_exec_DrawTransformFeedback); + SET_DrawTransformFeedbackStream(exec, + _mesa_exec_DrawTransformFeedbackStream); + SET_DrawTransformFeedbackInstanced(exec, + _mesa_exec_DrawTransformFeedbackInstanced); + SET_DrawTransformFeedbackStreamInstanced(exec, + _mesa_exec_DrawTransformFeedbackStreamInstanced); + SET_MultiDrawArraysIndirect(exec, _mesa_exec_MultiDrawArraysIndirect); + SET_MultiDrawElementsIndirect(exec, _mesa_exec_MultiDrawElementsIndirect); + SET_MultiDrawArraysIndirectCountARB(exec, + _mesa_exec_MultiDrawArraysIndirectCount); + SET_MultiDrawElementsIndirectCountARB(exec, + _mesa_exec_MultiDrawElementsIndirectCount); + } +} + + + +/** + * The following functions are only used for OpenGL ES 1/2 support. + * And some aren't even supported (yet) in ES 1/2. + */ + + +void GLAPIENTRY +_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count) +{ + _mesa_exec_DrawArrays(mode, first, count); +} + + +void GLAPIENTRY +_mesa_DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, + GLsizei primcount) +{ + _mesa_exec_DrawArraysInstanced(mode, first, count, primcount); +} + + +void GLAPIENTRY +_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + _mesa_exec_DrawElements(mode, count, type, indices); +} + + +void GLAPIENTRY +_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLint basevertex) +{ + _mesa_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex); +} + + +void GLAPIENTRY +_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, + GLenum type, const GLvoid * indices) +{ + _mesa_exec_DrawRangeElements(mode, start, end, count, type, indices); +} + + +void GLAPIENTRY +_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices, GLint basevertex) +{ + _mesa_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, + indices, basevertex); +} + + +void GLAPIENTRY +_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, + const GLvoid ** indices, GLsizei primcount) +{ + _mesa_exec_MultiDrawElements(mode, count, type, indices, primcount); +} + + +void GLAPIENTRY +_mesa_MultiDrawElementsBaseVertex(GLenum mode, + const GLsizei *count, GLenum type, + const GLvoid **indices, GLsizei primcount, + const GLint *basevertex) +{ + _mesa_exec_MultiDrawElementsBaseVertex(mode, count, type, indices, + primcount, basevertex); +} + + +void GLAPIENTRY +_mesa_DrawTransformFeedback(GLenum mode, GLuint name) +{ + _mesa_exec_DrawTransformFeedback(mode, name); +} + + +/* GL_IBM_multimode_draw_arrays */ +void GLAPIENTRY +_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, + const GLsizei * count, + GLsizei primcount, GLint modestride ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + + FLUSH_VERTICES(ctx, 0); + + for ( i = 0 ; i < primcount ; i++ ) { + if ( count[i] > 0 ) { + GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); + CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] )); + } + } +} + + +/* GL_IBM_multimode_draw_arrays */ +void GLAPIENTRY +_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, + GLenum type, const GLvoid * const * indices, + GLsizei primcount, GLint modestride ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + + FLUSH_VERTICES(ctx, 0); + + /* XXX not sure about ARB_vertex_buffer_object handling here */ + + for ( i = 0 ; i < primcount ; i++ ) { + if ( count[i] > 0 ) { + GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); + CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type, + indices[i] )); + } + } +} + + +/* + * Helper function for _mesa_draw_indirect below that additionally takes a zero + * initialized array of _mesa_prim scratch space memory as the last argument. + */ +static void +draw_indirect(struct gl_context *ctx, GLuint mode, + struct gl_buffer_object *indirect_data, + GLsizeiptr indirect_offset, unsigned draw_count, + unsigned stride, + struct gl_buffer_object *indirect_draw_count_buffer, + GLsizeiptr indirect_draw_count_offset, + const struct _mesa_index_buffer *ib, + struct _mesa_prim *prim) +{ + prim[0].begin = 1; + prim[draw_count - 1].end = 1; + for (unsigned i = 0; i < draw_count; ++i, indirect_offset += stride) { + prim[i].mode = mode; + prim[i].indexed = !!ib; + prim[i].indirect_offset = indirect_offset; + prim[i].is_indirect = 1; + prim[i].draw_id = i; + } + + /* This should always be true at this time */ + assert(indirect_data == ctx->DrawIndirectBuffer); + + ctx->Driver.Draw(ctx, prim, draw_count, ib, false, 0u, ~0u, + NULL, 0, indirect_data); +} + + +/* + * Function to be put into dd_function_table::DrawIndirect as fallback. + * Calls into dd_function_table::Draw past adapting call arguments. + * See dd_function_table::DrawIndirect for call argument documentation. + */ +void +_mesa_draw_indirect(struct gl_context *ctx, GLuint mode, + struct gl_buffer_object *indirect_data, + GLsizeiptr indirect_offset, unsigned draw_count, + unsigned stride, + struct gl_buffer_object *indirect_draw_count_buffer, + GLsizeiptr indirect_draw_count_offset, + const struct _mesa_index_buffer *ib) +{ + /* Use alloca for the prim space if we are somehow in bounds. */ + if (draw_count*sizeof(struct _mesa_prim) < 1024) { + struct _mesa_prim *space = alloca(draw_count*sizeof(struct _mesa_prim)); + memset(space, 0, draw_count*sizeof(struct _mesa_prim)); + + draw_indirect(ctx, mode, indirect_data, indirect_offset, draw_count, + stride, indirect_draw_count_buffer, + indirect_draw_count_offset, ib, space); + } else { + struct _mesa_prim *space = calloc(draw_count, sizeof(struct _mesa_prim)); + if (space == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDraw%sIndirect%s", + (draw_count > 1) ? "Multi" : "", + ib ? "Elements" : "Arrays", + indirect_data ? "CountARB" : ""); + return; + } + + draw_indirect(ctx, mode, indirect_data, indirect_offset, draw_count, + stride, indirect_draw_count_buffer, + indirect_draw_count_offset, ib, space); + + free(space); + } +} diff --git a/lib/mesa/src/mesa/main/draw.h b/lib/mesa/src/mesa/main/draw.h new file mode 100644 index 000000000..76d54f482 --- /dev/null +++ b/lib/mesa/src/mesa/main/draw.h @@ -0,0 +1,159 @@ +/* + * mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \brief Array type draw functions, the main workhorse of any OpenGL API + * \author Keith Whitwell + */ + + +#ifndef DRAW_H +#define DRAW_H + +#include <stdbool.h> +#include "main/glheader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gl_context; + +struct _mesa_prim +{ + GLuint mode:8; /**< GL_POINTS, GL_LINES, GL_QUAD_STRIP, etc */ + GLuint indexed:1; + GLuint begin:1; + GLuint end:1; + GLuint is_indirect:1; + GLuint pad:20; + + GLuint start; + GLuint count; + GLint basevertex; + GLuint num_instances; + GLuint base_instance; + GLuint draw_id; + + GLsizeiptr indirect_offset; +}; + +/* Would like to call this a "vbo_index_buffer", but this would be + * confusing as the indices are not neccessarily yet in a non-null + * buffer object. + */ +struct _mesa_index_buffer +{ + GLuint count; + unsigned index_size; + struct gl_buffer_object *obj; + const void *ptr; +}; + + +void +_mesa_initialize_exec_dispatch(const struct gl_context *ctx, + struct _glapi_table *exec); + + +void +_mesa_draw_indirect(struct gl_context *ctx, GLuint mode, + struct gl_buffer_object *indirect_data, + GLsizeiptr indirect_offset, unsigned draw_count, + unsigned stride, + struct gl_buffer_object *indirect_draw_count_buffer, + GLsizeiptr indirect_draw_count_offset, + const struct _mesa_index_buffer *ib); + + +void GLAPIENTRY +_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count); + + +void GLAPIENTRY +_mesa_DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, + GLsizei primcount); + + +void GLAPIENTRY +_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices); + + +void GLAPIENTRY +_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, + GLenum type, const GLvoid *indices); + + +void GLAPIENTRY +_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLint basevertex); + + +void GLAPIENTRY +_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices, + GLint basevertex); + + +void GLAPIENTRY +_mesa_DrawTransformFeedback(GLenum mode, GLuint name); + + + +void GLAPIENTRY +_mesa_MultiDrawArrays(GLenum mode, const GLint *first, + const GLsizei *count, GLsizei primcount); + + +void GLAPIENTRY +_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, + const GLvoid **indices, GLsizei primcount); + + +void GLAPIENTRY +_mesa_MultiDrawElementsBaseVertex(GLenum mode, + const GLsizei *count, GLenum type, + const GLvoid **indices, GLsizei primcount, + const GLint *basevertex); + + +void GLAPIENTRY +_mesa_MultiModeDrawArraysIBM(const GLenum * mode, const GLint * first, + const GLsizei * count, + GLsizei primcount, GLint modestride); + + +void GLAPIENTRY +_mesa_MultiModeDrawElementsIBM(const GLenum * mode, const GLsizei * count, + GLenum type, const GLvoid * const * indices, + GLsizei primcount, GLint modestride); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/lib/mesa/src/mesa/main/draw_validate.c b/lib/mesa/src/mesa/main/draw_validate.c new file mode 100644 index 000000000..29304bd51 --- /dev/null +++ b/lib/mesa/src/mesa/main/draw_validate.c @@ -0,0 +1,1417 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdbool.h> +#include "glheader.h" +#include "draw_validate.h" +#include "arrayobj.h" +#include "bufferobj.h" +#include "context.h" +#include "imports.h" +#include "mtypes.h" +#include "pipelineobj.h" +#include "enums.h" +#include "state.h" +#include "transformfeedback.h" +#include "uniforms.h" +#include "program/prog_print.h" + + +static bool +check_blend_func_error(struct gl_context *ctx) +{ + /* The ARB_blend_func_extended spec's ERRORS section says: + * + * "The error INVALID_OPERATION is generated by Begin or any procedure + * that implicitly calls Begin if any draw buffer has a blend function + * requiring the second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, + * SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that + * has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active + * color attachements." + */ + for (unsigned i = ctx->Const.MaxDualSourceDrawBuffers; + i < ctx->DrawBuffer->_NumColorDrawBuffers; + i++) { + if (ctx->Color.Blend[i]._UsesDualSrc) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "dual source blend on illegal attachment"); + return false; + } + } + + if (ctx->Color.BlendEnabled && ctx->Color._AdvancedBlendMode) { + /* The KHR_blend_equation_advanced spec says: + * + * "If any non-NONE draw buffer uses a blend equation found in table + * X.1 or X.2, the error INVALID_OPERATION is generated by Begin or + * any operation that implicitly calls Begin (such as DrawElements) + * if: + * + * * the draw buffer for color output zero selects multiple color + * buffers (e.g., FRONT_AND_BACK in the default framebuffer); or + * + * * the draw buffer for any other color output is not NONE." + */ + if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "advanced blending is active and draw buffer for color " + "output zero selects multiple color buffers"); + return false; + } + + for (unsigned i = 1; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "advanced blending is active with multiple color " + "draw buffers"); + return false; + } + } + + /* The KHR_blend_equation_advanced spec says: + * + * "Advanced blending equations require the use of a fragment shader + * with a matching "blend_support" layout qualifier. If the current + * blend equation is found in table X.1 or X.2, and the active + * fragment shader does not include the layout qualifier matching + * the blend equation or "blend_support_all_equations", the error + * INVALID_OPERATION is generated [...]" + */ + const struct gl_program *prog = ctx->FragmentProgram._Current; + const GLbitfield blend_support = !prog ? 0 : prog->sh.fs.BlendSupport; + + if ((blend_support & ctx->Color._AdvancedBlendMode) == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "fragment shader does not allow advanced blending mode " + "(%s)", + _mesa_enum_to_string(ctx->Color.Blend[0].EquationRGB)); + } + } + + return true; +} + + +/** + * Prior to drawing anything with glBegin, glDrawArrays, etc. this function + * is called to see if it's valid to render. This involves checking that + * the current shader is valid and the framebuffer is complete. + * It also check the current pipeline object is valid if any. + * If an error is detected it'll be recorded here. + * \return GL_TRUE if OK to render, GL_FALSE if not + */ +GLboolean +_mesa_valid_to_render(struct gl_context *ctx, const char *where) +{ + /* This depends on having up to date derived state (shaders) */ + if (ctx->NewState) + _mesa_update_state(ctx); + + if (ctx->API == API_OPENGL_COMPAT) { + /* Any shader stages that are not supplied by the GLSL shader and have + * assembly shaders enabled must now be validated. + */ + if (!ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] && + ctx->VertexProgram.Enabled && + !_mesa_arb_vertex_program_enabled(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(vertex program not valid)", where); + return GL_FALSE; + } + + if (!ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]) { + if (ctx->FragmentProgram.Enabled && + !_mesa_arb_fragment_program_enabled(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(fragment program not valid)", where); + return GL_FALSE; + } + + /* If drawing to integer-valued color buffers, there must be an + * active fragment shader (GL_EXT_texture_integer). + */ + if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerBuffers) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(integer format but no fragment shader)", where); + return GL_FALSE; + } + } + } + + /* A pipeline object is bound */ + if (ctx->_Shader->Name && !ctx->_Shader->Validated) { + if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glValidateProgramPipeline failed to validate the " + "pipeline"); + return GL_FALSE; + } + } + + /* If a program is active and SSO not in use, check if validation of + * samplers succeeded for the active program. */ + if (ctx->_Shader->ActiveProgram && ctx->_Shader != ctx->Pipeline.Current) { + char errMsg[100]; + if (!_mesa_sampler_uniforms_are_valid(ctx->_Shader->ActiveProgram, + errMsg, 100)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s", errMsg); + return GL_FALSE; + } + } + + if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, + "%s(incomplete framebuffer)", where); + return GL_FALSE; + } + + if (!check_blend_func_error(ctx)) { + return GL_FALSE; + } + + /* From the GL_NV_fill_rectangle spec: + * + * "An INVALID_OPERATION error is generated by Begin or any Draw command if + * only one of the front and back polygon mode is FILL_RECTANGLE_NV." + */ + if ((ctx->Polygon.FrontMode == GL_FILL_RECTANGLE_NV) != + (ctx->Polygon.BackMode == GL_FILL_RECTANGLE_NV)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "GL_FILL_RECTANGLE_NV must be used as both front/back " + "polygon mode or neither"); + return GL_FALSE; + } + +#ifdef DEBUG + if (ctx->_Shader->Flags & GLSL_LOG) { + struct gl_program **prog = ctx->_Shader->CurrentProgram; + + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (prog[i] == NULL || prog[i]->_Used) + continue; + + /* This is the first time this shader is being used. + * Append shader's constants/uniforms to log file. + * + * Only log data for the program target that matches the shader + * target. It's possible to have a program bound to the vertex + * shader target that also supplied a fragment shader. If that + * program isn't also bound to the fragment shader target we don't + * want to log its fragment data. + */ + _mesa_append_uniforms_to_file(prog[i]); + } + + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (prog[i] != NULL) + prog[i]->_Used = GL_TRUE; + } + } +#endif + + return GL_TRUE; +} + + +/** + * Check if OK to draw arrays/elements. + */ +static bool +check_valid_to_render(struct gl_context *ctx, const char *function) +{ + if (!_mesa_valid_to_render(ctx, function)) { + return false; + } + + /* Section 6.3.2 from the GL 4.5: + * "Any GL command which attempts to read from, write to, or change + * the state of a buffer object may generate an INVALID_OPERATION error if + * all or part of the buffer object is mapped ... However, only commands + * which explicitly describe this error are required to do so. If an error + * is not generated, such commands will have undefined results and may + * result in GL interruption or termination." + * + * Only some buffer API functions require INVALID_OPERATION with mapped + * buffers. No other functions list such an error, thus it's not required + * to report INVALID_OPERATION for draw calls with mapped buffers. + */ + if (!ctx->Const.AllowMappedBuffersDuringExecution && + !_mesa_all_buffers_are_unmapped(ctx->Array.VAO)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(vertex buffers are mapped)", function); + return false; + } + + /* Section 11.2 (Tessellation) of the ES 3.2 spec says: + * + * "An INVALID_OPERATION error is generated by any command that + * transfers vertices to the GL if the current program state has + * one but not both of a tessellation control shader and tessellation + * evaluation shader." + * + * The OpenGL spec argues that this is allowed because a tess ctrl shader + * without a tess eval shader can be used with transform feedback. + * However, glBeginTransformFeedback doesn't allow GL_PATCHES and + * therefore doesn't allow tessellation. + * + * Further investigation showed that this is indeed a spec bug and + * a tess ctrl shader without a tess eval shader shouldn't have been + * allowed, because there is no API in GL 4.0 that can make use this + * to produce something useful. + * + * Also, all vendors except one don't support a tess ctrl shader without + * a tess eval shader anyway. + */ + if (ctx->TessCtrlProgram._Current && !ctx->TessEvalProgram._Current) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(tess eval shader is missing)", function); + return false; + } + + switch (ctx->API) { + case API_OPENGLES2: + /* Section 11.2 (Tessellation) of the ES 3.2 spec says: + * + * "An INVALID_OPERATION error is generated by any command that + * transfers vertices to the GL if the current program state has + * one but not both of a tessellation control shader and tessellation + * evaluation shader." + */ + if (_mesa_is_gles3(ctx) && + ctx->TessEvalProgram._Current && !ctx->TessCtrlProgram._Current) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(tess ctrl shader is missing)", function); + return false; + } + break; + + case API_OPENGL_CORE: + /* Section 10.4 (Drawing Commands Using Vertex Arrays) of the OpenGL 4.5 + * Core Profile spec says: + * + * "An INVALID_OPERATION error is generated if no vertex array + * object is bound (see section 10.3.1)." + */ + if (ctx->Array.VAO == ctx->Array.DefaultVAO) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no VAO bound)", function); + return false; + } + break; + + case API_OPENGLES: + case API_OPENGL_COMPAT: + break; + + default: + unreachable("Invalid API value in check_valid_to_render()"); + } + + return true; +} + + +/** + * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(), + * etc? The set of legal values depends on whether geometry shaders/programs + * are supported. + * Note: This may be called during display list compilation. + */ +bool +_mesa_is_valid_prim_mode(const struct gl_context *ctx, GLenum mode) +{ + /* The overwhelmingly common case is (mode <= GL_TRIANGLE_FAN). Test that + * first and exit. You would think that a switch-statement would be the + * right approach, but at least GCC 4.7.2 generates some pretty dire code + * for the common case. + */ + if (likely(mode <= GL_TRIANGLE_FAN)) + return true; + + if (mode <= GL_POLYGON) + return (ctx->API == API_OPENGL_COMPAT); + + if (mode <= GL_TRIANGLE_STRIP_ADJACENCY) + return _mesa_has_geometry_shaders(ctx); + + if (mode == GL_PATCHES) + return _mesa_has_tessellation(ctx); + + return false; +} + + +/** + * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(), + * etc? Also, do additional checking related to transformation feedback. + * Note: this function cannot be called during glNewList(GL_COMPILE) because + * this code depends on current transform feedback state. + * Also, do additional checking related to tessellation shaders. + */ +GLboolean +_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name) +{ + bool valid_enum = _mesa_is_valid_prim_mode(ctx, mode); + + if (!valid_enum) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode); + return GL_FALSE; + } + + /* From the OpenGL 4.5 specification, section 11.3.1: + * + * The error INVALID_OPERATION is generated if Begin, or any command that + * implicitly calls Begin, is called when a geometry shader is active and: + * + * * the input primitive type of the current geometry shader is + * POINTS and <mode> is not POINTS, + * + * * the input primitive type of the current geometry shader is + * LINES and <mode> is not LINES, LINE_STRIP, or LINE_LOOP, + * + * * the input primitive type of the current geometry shader is + * TRIANGLES and <mode> is not TRIANGLES, TRIANGLE_STRIP or + * TRIANGLE_FAN, + * + * * the input primitive type of the current geometry shader is + * LINES_ADJACENCY_ARB and <mode> is not LINES_ADJACENCY_ARB or + * LINE_STRIP_ADJACENCY_ARB, or + * + * * the input primitive type of the current geometry shader is + * TRIANGLES_ADJACENCY_ARB and <mode> is not + * TRIANGLES_ADJACENCY_ARB or TRIANGLE_STRIP_ADJACENCY_ARB. + * + * The GL spec doesn't mention any interaction with tessellation, which + * is clearly a spec bug. The same rule should apply, but instead of + * the draw primitive mode, the tessellation evaluation shader primitive + * mode should be used for the checking. + */ + if (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]) { + const GLenum geom_mode = + ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]-> + info.gs.input_primitive; + struct gl_program *tes = + ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; + GLenum mode_before_gs = mode; + + if (tes) { + if (tes->info.tess.point_mode) + mode_before_gs = GL_POINTS; + else if (tes->info.tess.primitive_mode == GL_ISOLINES) + mode_before_gs = GL_LINES; + else + /* the GL_QUADS mode generates triangles too */ + mode_before_gs = GL_TRIANGLES; + } + + switch (mode_before_gs) { + case GL_POINTS: + valid_enum = (geom_mode == GL_POINTS); + break; + case GL_LINES: + case GL_LINE_LOOP: + case GL_LINE_STRIP: + valid_enum = (geom_mode == GL_LINES); + break; + case GL_TRIANGLES: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + valid_enum = (geom_mode == GL_TRIANGLES); + break; + case GL_QUADS: + case GL_QUAD_STRIP: + case GL_POLYGON: + valid_enum = false; + break; + case GL_LINES_ADJACENCY: + case GL_LINE_STRIP_ADJACENCY: + valid_enum = (geom_mode == GL_LINES_ADJACENCY); + break; + case GL_TRIANGLES_ADJACENCY: + case GL_TRIANGLE_STRIP_ADJACENCY: + valid_enum = (geom_mode == GL_TRIANGLES_ADJACENCY); + break; + default: + valid_enum = false; + break; + } + if (!valid_enum) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(mode=%s vs geometry shader input %s)", + name, + _mesa_lookup_prim_by_nr(mode_before_gs), + _mesa_lookup_prim_by_nr(geom_mode)); + return GL_FALSE; + } + } + + /* From the OpenGL 4.0 (Core Profile) spec (section 2.12): + * + * "Tessellation operates only on patch primitives. If tessellation is + * active, any command that transfers vertices to the GL will + * generate an INVALID_OPERATION error if the primitive mode is not + * PATCHES. + * Patch primitives are not supported by pipeline stages below the + * tessellation evaluation shader. If there is no active program + * object or the active program object does not contain a tessellation + * evaluation shader, the error INVALID_OPERATION is generated by any + * command that transfers vertices to the GL if the primitive mode is + * PATCHES." + * + */ + if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL] || + ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]) { + if (mode != GL_PATCHES) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "only GL_PATCHES valid with tessellation"); + return GL_FALSE; + } + } + else { + if (mode == GL_PATCHES) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "GL_PATCHES only valid with tessellation"); + return GL_FALSE; + } + } + + /* From the GL_EXT_transform_feedback spec: + * + * "The error INVALID_OPERATION is generated if Begin, or any command + * that performs an explicit Begin, is called when: + * + * * a geometry shader is not active and <mode> does not match the + * allowed begin modes for the current transform feedback state as + * given by table X.1. + * + * * a geometry shader is active and the output primitive type of the + * geometry shader does not match the allowed begin modes for the + * current transform feedback state as given by table X.1. + * + */ + if (_mesa_is_xfb_active_and_unpaused(ctx)) { + GLboolean pass = GL_TRUE; + + if(ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]) { + switch (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]-> + info.gs.output_primitive) { + case GL_POINTS: + pass = ctx->TransformFeedback.Mode == GL_POINTS; + break; + case GL_LINE_STRIP: + pass = ctx->TransformFeedback.Mode == GL_LINES; + break; + case GL_TRIANGLE_STRIP: + pass = ctx->TransformFeedback.Mode == GL_TRIANGLES; + break; + default: + pass = GL_FALSE; + } + } + else if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]) { + struct gl_program *tes = + ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; + if (tes->info.tess.point_mode) + pass = ctx->TransformFeedback.Mode == GL_POINTS; + else if (tes->info.tess.primitive_mode == GL_ISOLINES) + pass = ctx->TransformFeedback.Mode == GL_LINES; + else + pass = ctx->TransformFeedback.Mode == GL_TRIANGLES; + } + else { + switch (mode) { + case GL_POINTS: + pass = ctx->TransformFeedback.Mode == GL_POINTS; + break; + case GL_LINES: + case GL_LINE_STRIP: + case GL_LINE_LOOP: + pass = ctx->TransformFeedback.Mode == GL_LINES; + break; + default: + pass = ctx->TransformFeedback.Mode == GL_TRIANGLES; + break; + } + } + if (!pass) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(mode=%s vs transform feedback %s)", + name, + _mesa_lookup_prim_by_nr(mode), + _mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode)); + return GL_FALSE; + } + } + + /* From GL_INTEL_conservative_rasterization spec: + * + * The conservative rasterization option applies only to polygons with + * PolygonMode state set to FILL. Draw requests for polygons with different + * PolygonMode setting or for other primitive types (points/lines) generate + * INVALID_OPERATION error. + */ + if (ctx->IntelConservativeRasterization) { + GLboolean pass = GL_TRUE; + + switch (mode) { + case GL_POINTS: + case GL_LINES: + case GL_LINE_LOOP: + case GL_LINE_STRIP: + case GL_LINES_ADJACENCY: + case GL_LINE_STRIP_ADJACENCY: + pass = GL_FALSE; + break; + case GL_TRIANGLES: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + case GL_QUADS: + case GL_QUAD_STRIP: + case GL_POLYGON: + case GL_TRIANGLES_ADJACENCY: + case GL_TRIANGLE_STRIP_ADJACENCY: + if (ctx->Polygon.FrontMode != GL_FILL || + ctx->Polygon.BackMode != GL_FILL) + pass = GL_FALSE; + break; + default: + pass = GL_FALSE; + } + if (!pass) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "mode=%s invalid with GL_INTEL_conservative_rasterization", + _mesa_lookup_prim_by_nr(mode)); + return GL_FALSE; + } + } + + return GL_TRUE; +} + +/** + * Verify that the element type is valid. + * + * Generates \c GL_INVALID_ENUM and returns \c false if it is not. + */ +static bool +valid_elements_type(struct gl_context *ctx, GLenum type, const char *name) +{ + switch (type) { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + return true; + + default: + _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", name, + _mesa_enum_to_string(type)); + return false; + } +} + +static bool +validate_DrawElements_common(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, + const char *caller) +{ + /* Section 2.14.2 (Transform Feedback Primitive Capture) of the OpenGL ES + * 3.1 spec says: + * + * The error INVALID_OPERATION is also generated by DrawElements, + * DrawElementsInstanced, and DrawRangeElements while transform feedback + * is active and not paused, regardless of mode. + * + * The OES_geometry_shader_spec says: + * + * Issues: + * + * ... + * + * (13) Does this extension change how transform feedback operates + * compared to unextended OpenGL ES 3.0 or 3.1? + * + * RESOLVED: Yes... Since we no longer require being able to predict how + * much geometry will be generated, we also lift the restriction that + * only DrawArray* commands are supported and also support the + * DrawElements* commands for transform feedback. + * + * This should also be reflected in the body of the spec, but that appears + * to have been overlooked. The body of the spec only explicitly allows + * the indirect versions. + */ + if (_mesa_is_gles3(ctx) && + !_mesa_has_OES_geometry_shader(ctx) && + _mesa_is_xfb_active_and_unpaused(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(transform feedback active)", caller); + return false; + } + + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(count)", caller); + return false; + } + + if (!_mesa_valid_prim_mode(ctx, mode, caller)) { + return false; + } + + if (!valid_elements_type(ctx, type, caller)) + return false; + + if (!check_valid_to_render(ctx, caller)) + return false; + + return true; +} + +/** + * Error checking for glDrawElements(). Includes parameter checking + * and VBO bounds checking. + * \return GL_TRUE if OK to render, GL_FALSE if error found + */ +GLboolean +_mesa_validate_DrawElements(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + return validate_DrawElements_common(ctx, mode, count, type, indices, + "glDrawElements"); +} + + +/** + * Error checking for glMultiDrawElements(). Includes parameter checking + * and VBO bounds checking. + * \return GL_TRUE if OK to render, GL_FALSE if error found + */ +GLboolean +_mesa_validate_MultiDrawElements(struct gl_context *ctx, + GLenum mode, const GLsizei *count, + GLenum type, const GLvoid * const *indices, + GLsizei primcount) +{ + GLsizei i; + + /* + * Section 2.3.1 (Errors) of the OpenGL 4.5 (Core Profile) spec says: + * + * "If a negative number is provided where an argument of type sizei or + * sizeiptr is specified, an INVALID_VALUE error is generated." + * + * and in the same section: + * + * "In other cases, there are no side effects unless otherwise noted; + * the command which generates the error is ignored so that it has no + * effect on GL state or framebuffer contents." + * + * Hence, check both primcount and all the count[i]. + */ + if (primcount < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glMultiDrawElements(primcount=%d)", primcount); + return GL_FALSE; + } + + for (i = 0; i < primcount; i++) { + if (count[i] < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glMultiDrawElements(count)" ); + return GL_FALSE; + } + } + + if (!_mesa_valid_prim_mode(ctx, mode, "glMultiDrawElements")) { + return GL_FALSE; + } + + if (!valid_elements_type(ctx, type, "glMultiDrawElements")) + return GL_FALSE; + + if (!check_valid_to_render(ctx, "glMultiDrawElements")) + return GL_FALSE; + + /* Not using a VBO for indices, so avoid NULL pointer derefs later. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { + for (i = 0; i < primcount; i++) { + if (!indices[i]) + return GL_FALSE; + } + } + + return GL_TRUE; +} + + +/** + * Error checking for glDrawRangeElements(). Includes parameter checking + * and VBO bounds checking. + * \return GL_TRUE if OK to render, GL_FALSE if error found + */ +GLboolean +_mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices) +{ + if (end < start) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(end<start)"); + return GL_FALSE; + } + + return validate_DrawElements_common(ctx, mode, count, type, indices, + "glDrawRangeElements"); +} + + +static bool +need_xfb_remaining_prims_check(const struct gl_context *ctx) +{ + /* From the GLES3 specification, section 2.14.2 (Transform Feedback + * Primitive Capture): + * + * The error INVALID_OPERATION is generated by DrawArrays and + * DrawArraysInstanced if recording the vertices of a primitive to the + * buffer objects being used for transform feedback purposes would result + * in either exceeding the limits of any buffer object’s size, or in + * exceeding the end position offset + size − 1, as set by + * BindBufferRange. + * + * This is in contrast to the behaviour of desktop GL, where the extra + * primitives are silently dropped from the transform feedback buffer. + * + * This text is removed in ES 3.2, presumably because it's not really + * implementable with geometry and tessellation shaders. In fact, + * the OES_geometry_shader spec says: + * + * "(13) Does this extension change how transform feedback operates + * compared to unextended OpenGL ES 3.0 or 3.1? + * + * RESOLVED: Yes. Because dynamic geometry amplification in a geometry + * shader can make it difficult if not impossible to predict the amount + * of geometry that may be generated in advance of executing the shader, + * the draw-time error for transform feedback buffer overflow conditions + * is removed and replaced with the GL behavior (primitives are not + * written and the corresponding counter is not updated)..." + */ + return _mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx) && + !_mesa_has_OES_geometry_shader(ctx) && + !_mesa_has_OES_tessellation_shader(ctx); +} + + +/** + * Figure out the number of transform feedback primitives that will be output + * considering the drawing mode, number of vertices, and instance count, + * assuming that no geometry shading is done and primitive restart is not + * used. + * + * This is used by driver back-ends in implementing the PRIMITIVES_GENERATED + * and TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN queries. It is also used to + * pre-validate draw calls in GLES3 (where draw calls only succeed if there is + * enough room in the transform feedback buffer for the result). + */ +static size_t +count_tessellated_primitives(GLenum mode, GLuint count, GLuint num_instances) +{ + size_t num_primitives; + switch (mode) { + case GL_POINTS: + num_primitives = count; + break; + case GL_LINE_STRIP: + num_primitives = count >= 2 ? count - 1 : 0; + break; + case GL_LINE_LOOP: + num_primitives = count >= 2 ? count : 0; + break; + case GL_LINES: + num_primitives = count / 2; + break; + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + case GL_POLYGON: + num_primitives = count >= 3 ? count - 2 : 0; + break; + case GL_TRIANGLES: + num_primitives = count / 3; + break; + case GL_QUAD_STRIP: + num_primitives = count >= 4 ? ((count / 2) - 1) * 2 : 0; + break; + case GL_QUADS: + num_primitives = (count / 4) * 2; + break; + case GL_LINES_ADJACENCY: + num_primitives = count / 4; + break; + case GL_LINE_STRIP_ADJACENCY: + num_primitives = count >= 4 ? count - 3 : 0; + break; + case GL_TRIANGLES_ADJACENCY: + num_primitives = count / 6; + break; + case GL_TRIANGLE_STRIP_ADJACENCY: + num_primitives = count >= 6 ? (count - 4) / 2 : 0; + break; + default: + assert(!"Unexpected primitive type in count_tessellated_primitives"); + num_primitives = 0; + break; + } + return num_primitives * num_instances; +} + + +static bool +validate_draw_arrays(struct gl_context *ctx, const char *func, + GLenum mode, GLsizei count, GLsizei numInstances) +{ + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(count)", func); + return false; + } + + if (!_mesa_valid_prim_mode(ctx, mode, func)) + return false; + + if (!check_valid_to_render(ctx, func)) + return false; + + if (need_xfb_remaining_prims_check(ctx)) { + struct gl_transform_feedback_object *xfb_obj + = ctx->TransformFeedback.CurrentObject; + size_t prim_count = count_tessellated_primitives(mode, count, numInstances); + if (xfb_obj->GlesRemainingPrims < prim_count) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(exceeds transform feedback size)", func); + return false; + } + xfb_obj->GlesRemainingPrims -= prim_count; + } + + if (count == 0) + return false; + + return true; +} + +/** + * Called from the tnl module to error check the function parameters and + * verify that we really can draw something. + * \return GL_TRUE if OK to render, GL_FALSE if error found + */ +GLboolean +_mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count) +{ + return validate_draw_arrays(ctx, "glDrawArrays", mode, count, 1); +} + + +GLboolean +_mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint first, + GLsizei count, GLsizei numInstances) +{ + if (first < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glDrawArraysInstanced(start=%d)", first); + return GL_FALSE; + } + + if (numInstances <= 0) { + if (numInstances < 0) + _mesa_error(ctx, GL_INVALID_VALUE, + "glDrawArraysInstanced(numInstances=%d)", numInstances); + return GL_FALSE; + } + + return validate_draw_arrays(ctx, "glDrawArraysInstanced", mode, count, 1); +} + + +/** + * Called to error check the function parameters. + * + * Note that glMultiDrawArrays is not part of GLES, so there's limited scope + * for sharing code with the validation of glDrawArrays. + */ +bool +_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode, + const GLsizei *count, GLsizei primcount) +{ + int i; + + if (!_mesa_valid_prim_mode(ctx, mode, "glMultiDrawArrays")) + return false; + + if (!check_valid_to_render(ctx, "glMultiDrawArrays")) + return false; + + if (primcount < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawArrays(primcount=%d)", + primcount); + return false; + } + + for (i = 0; i < primcount; ++i) { + if (count[i] < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawArrays(count[%d]=%d)", + i, count[i]); + return false; + } + } + + if (need_xfb_remaining_prims_check(ctx)) { + struct gl_transform_feedback_object *xfb_obj + = ctx->TransformFeedback.CurrentObject; + size_t xfb_prim_count = 0; + + for (i = 0; i < primcount; ++i) + xfb_prim_count += count_tessellated_primitives(mode, count[i], 1); + + if (xfb_obj->GlesRemainingPrims < xfb_prim_count) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glMultiDrawArrays(exceeds transform feedback size)"); + return false; + } + xfb_obj->GlesRemainingPrims -= xfb_prim_count; + } + + return true; +} + + +GLboolean +_mesa_validate_DrawElementsInstanced(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLsizei numInstances) +{ + if (numInstances < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glDrawElementsInstanced(numInstances=%d)", numInstances); + return GL_FALSE; + } + + return validate_DrawElements_common(ctx, mode, count, type, indices, + "glDrawElementsInstanced") + && (numInstances > 0); +} + + +GLboolean +_mesa_validate_DrawTransformFeedback(struct gl_context *ctx, + GLenum mode, + struct gl_transform_feedback_object *obj, + GLuint stream, + GLsizei numInstances) +{ + if (!_mesa_valid_prim_mode(ctx, mode, "glDrawTransformFeedback*(mode)")) { + return GL_FALSE; + } + + if (!obj) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTransformFeedback*(name)"); + return GL_FALSE; + } + + /* From the GL 4.5 specification, page 429: + * "An INVALID_VALUE error is generated if id is not the name of a + * transform feedback object." + */ + if (!obj->EverBound) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTransformFeedback*(name)"); + return GL_FALSE; + } + + if (stream >= ctx->Const.MaxVertexStreams) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glDrawTransformFeedbackStream*(index>=MaxVertexStream)"); + return GL_FALSE; + } + + if (!obj->EndedAnytime) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback*"); + return GL_FALSE; + } + + if (numInstances <= 0) { + if (numInstances < 0) + _mesa_error(ctx, GL_INVALID_VALUE, + "glDrawTransformFeedback*Instanced(numInstances=%d)", + numInstances); + return GL_FALSE; + } + + if (!check_valid_to_render(ctx, "glDrawTransformFeedback*")) { + return GL_FALSE; + } + + return GL_TRUE; +} + +static GLboolean +valid_draw_indirect(struct gl_context *ctx, + GLenum mode, const GLvoid *indirect, + GLsizei size, const char *name) +{ + const uint64_t end = (uint64_t) (uintptr_t) indirect + size; + + /* OpenGL ES 3.1 spec. section 10.5: + * + * "DrawArraysIndirect requires that all data sourced for the + * command, including the DrawArraysIndirectCommand + * structure, be in buffer objects, and may not be called when + * the default vertex array object is bound." + */ + if (ctx->API != API_OPENGL_COMPAT && + ctx->Array.VAO == ctx->Array.DefaultVAO) { + _mesa_error(ctx, GL_INVALID_OPERATION, "(no VAO bound)"); + return GL_FALSE; + } + + /* From OpenGL ES 3.1 spec. section 10.5: + * "An INVALID_OPERATION error is generated if zero is bound to + * VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER or to any enabled + * vertex array." + * + * Here we check that for each enabled vertex array we have a vertex + * buffer bound. + */ + if (_mesa_is_gles31(ctx) && + ctx->Array.VAO->_Enabled & ~ctx->Array.VAO->VertexAttribBufferMask) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(No VBO bound)", name); + return GL_FALSE; + } + + if (!_mesa_valid_prim_mode(ctx, mode, name)) + return GL_FALSE; + + /* OpenGL ES 3.1 specification, section 10.5: + * + * "An INVALID_OPERATION error is generated if + * transform feedback is active and not paused." + * + * The OES_geometry_shader spec says: + * + * On p. 250 in the errors section for the DrawArraysIndirect command, + * and on p. 254 in the errors section for the DrawElementsIndirect + * command, delete the errors which state: + * + * "An INVALID_OPERATION error is generated if transform feedback is + * active and not paused." + * + * (thus allowing transform feedback to work with indirect draw commands). + */ + if (_mesa_is_gles31(ctx) && !ctx->Extensions.OES_geometry_shader && + _mesa_is_xfb_active_and_unpaused(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(TransformFeedback is active and not paused)", name); + } + + /* From OpenGL version 4.4. section 10.5 + * and OpenGL ES 3.1, section 10.6: + * + * "An INVALID_VALUE error is generated if indirect is not a + * multiple of the size, in basic machine units, of uint." + */ + if ((GLsizeiptr)indirect & (sizeof(GLuint) - 1)) { + _mesa_error(ctx, GL_INVALID_VALUE, + "%s(indirect is not aligned)", name); + return GL_FALSE; + } + + if (!_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s: no buffer bound to DRAW_INDIRECT_BUFFER", name); + return GL_FALSE; + } + + if (_mesa_check_disallowed_mapping(ctx->DrawIndirectBuffer)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(DRAW_INDIRECT_BUFFER is mapped)", name); + return GL_FALSE; + } + + /* From the ARB_draw_indirect specification: + * "An INVALID_OPERATION error is generated if the commands source data + * beyond the end of the buffer object [...]" + */ + if (ctx->DrawIndirectBuffer->Size < end) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(DRAW_INDIRECT_BUFFER too small)", name); + return GL_FALSE; + } + + if (!check_valid_to_render(ctx, name)) + return GL_FALSE; + + return GL_TRUE; +} + +static inline GLboolean +valid_draw_indirect_elements(struct gl_context *ctx, + GLenum mode, GLenum type, const GLvoid *indirect, + GLsizeiptr size, const char *name) +{ + if (!valid_elements_type(ctx, type, name)) + return GL_FALSE; + + /* + * Unlike regular DrawElementsInstancedBaseVertex commands, the indices + * may not come from a client array and must come from an index buffer. + * If no element array buffer is bound, an INVALID_OPERATION error is + * generated. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(no buffer bound to GL_ELEMENT_ARRAY_BUFFER)", name); + return GL_FALSE; + } + + return valid_draw_indirect(ctx, mode, indirect, size, name); +} + +GLboolean +_mesa_valid_draw_indirect_multi(struct gl_context *ctx, + GLsizei primcount, GLsizei stride, + const char *name) +{ + + /* From the ARB_multi_draw_indirect specification: + * "INVALID_VALUE is generated by MultiDrawArraysIndirect or + * MultiDrawElementsIndirect if <primcount> is negative." + * + * "<primcount> must be positive, otherwise an INVALID_VALUE error will + * be generated." + */ + if (primcount < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(primcount < 0)", name); + return GL_FALSE; + } + + + /* From the ARB_multi_draw_indirect specification: + * "<stride> must be a multiple of four, otherwise an INVALID_VALUE + * error is generated." + */ + if (stride % 4) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride %% 4)", name); + return GL_FALSE; + } + + return GL_TRUE; +} + +GLboolean +_mesa_validate_DrawArraysIndirect(struct gl_context *ctx, + GLenum mode, + const GLvoid *indirect) +{ + const unsigned drawArraysNumParams = 4; + + return valid_draw_indirect(ctx, mode, + indirect, drawArraysNumParams * sizeof(GLuint), + "glDrawArraysIndirect"); +} + +GLboolean +_mesa_validate_DrawElementsIndirect(struct gl_context *ctx, + GLenum mode, GLenum type, + const GLvoid *indirect) +{ + const unsigned drawElementsNumParams = 5; + + return valid_draw_indirect_elements(ctx, mode, type, + indirect, drawElementsNumParams * sizeof(GLuint), + "glDrawElementsIndirect"); +} + +GLboolean +_mesa_validate_MultiDrawArraysIndirect(struct gl_context *ctx, + GLenum mode, + const GLvoid *indirect, + GLsizei primcount, GLsizei stride) +{ + GLsizeiptr size = 0; + const unsigned drawArraysNumParams = 4; + + /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */ + assert(stride != 0); + + if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, + "glMultiDrawArraysIndirect")) + return GL_FALSE; + + /* number of bytes of the indirect buffer which will be read */ + size = primcount + ? (primcount - 1) * stride + drawArraysNumParams * sizeof(GLuint) + : 0; + + if (!valid_draw_indirect(ctx, mode, indirect, size, + "glMultiDrawArraysIndirect")) + return GL_FALSE; + + return GL_TRUE; +} + +GLboolean +_mesa_validate_MultiDrawElementsIndirect(struct gl_context *ctx, + GLenum mode, GLenum type, + const GLvoid *indirect, + GLsizei primcount, GLsizei stride) +{ + GLsizeiptr size = 0; + const unsigned drawElementsNumParams = 5; + + /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */ + assert(stride != 0); + + if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, + "glMultiDrawElementsIndirect")) + return GL_FALSE; + + /* number of bytes of the indirect buffer which will be read */ + size = primcount + ? (primcount - 1) * stride + drawElementsNumParams * sizeof(GLuint) + : 0; + + if (!valid_draw_indirect_elements(ctx, mode, type, + indirect, size, + "glMultiDrawElementsIndirect")) + return GL_FALSE; + + return GL_TRUE; +} + +static GLboolean +valid_draw_indirect_parameters(struct gl_context *ctx, + const char *name, + GLintptr drawcount) +{ + /* From the ARB_indirect_parameters specification: + * "INVALID_VALUE is generated by MultiDrawArraysIndirectCountARB or + * MultiDrawElementsIndirectCountARB if <drawcount> is not a multiple of + * four." + */ + if (drawcount & 3) { + _mesa_error(ctx, GL_INVALID_VALUE, + "%s(drawcount is not a multiple of 4)", name); + return GL_FALSE; + } + + /* From the ARB_indirect_parameters specification: + * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or + * MultiDrawElementsIndirectCountARB if no buffer is bound to the + * PARAMETER_BUFFER_ARB binding point." + */ + if (!_mesa_is_bufferobj(ctx->ParameterBuffer)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s: no buffer bound to PARAMETER_BUFFER", name); + return GL_FALSE; + } + + if (_mesa_check_disallowed_mapping(ctx->ParameterBuffer)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(PARAMETER_BUFFER is mapped)", name); + return GL_FALSE; + } + + /* From the ARB_indirect_parameters specification: + * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or + * MultiDrawElementsIndirectCountARB if reading a <sizei> typed value + * from the buffer bound to the PARAMETER_BUFFER_ARB target at the offset + * specified by <drawcount> would result in an out-of-bounds access." + */ + if (ctx->ParameterBuffer->Size < drawcount + sizeof(GLsizei)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(PARAMETER_BUFFER too small)", name); + return GL_FALSE; + } + + return GL_TRUE; +} + +GLboolean +_mesa_validate_MultiDrawArraysIndirectCount(struct gl_context *ctx, + GLenum mode, + GLintptr indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride) +{ + GLsizeiptr size = 0; + const unsigned drawArraysNumParams = 4; + + /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */ + assert(stride != 0); + + if (!_mesa_valid_draw_indirect_multi(ctx, maxdrawcount, stride, + "glMultiDrawArraysIndirectCountARB")) + return GL_FALSE; + + /* number of bytes of the indirect buffer which will be read */ + size = maxdrawcount + ? (maxdrawcount - 1) * stride + drawArraysNumParams * sizeof(GLuint) + : 0; + + if (!valid_draw_indirect(ctx, mode, (void *)indirect, size, + "glMultiDrawArraysIndirectCountARB")) + return GL_FALSE; + + return valid_draw_indirect_parameters( + ctx, "glMultiDrawArraysIndirectCountARB", drawcount); +} + +GLboolean +_mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx, + GLenum mode, GLenum type, + GLintptr indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride) +{ + GLsizeiptr size = 0; + const unsigned drawElementsNumParams = 5; + + /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */ + assert(stride != 0); + + if (!_mesa_valid_draw_indirect_multi(ctx, maxdrawcount, stride, + "glMultiDrawElementsIndirectCountARB")) + return GL_FALSE; + + /* number of bytes of the indirect buffer which will be read */ + size = maxdrawcount + ? (maxdrawcount - 1) * stride + drawElementsNumParams * sizeof(GLuint) + : 0; + + if (!valid_draw_indirect_elements(ctx, mode, type, + (void *)indirect, size, + "glMultiDrawElementsIndirectCountARB")) + return GL_FALSE; + + return valid_draw_indirect_parameters( + ctx, "glMultiDrawElementsIndirectCountARB", drawcount); +} diff --git a/lib/mesa/src/mesa/main/draw_validate.h b/lib/mesa/src/mesa/main/draw_validate.h new file mode 100644 index 000000000..d015c7e83 --- /dev/null +++ b/lib/mesa/src/mesa/main/draw_validate.h @@ -0,0 +1,134 @@ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef API_VALIDATE_H +#define API_VALIDATE_H + +#include <stdbool.h> +#include "glheader.h" + +struct gl_buffer_object; +struct gl_context; +struct gl_transform_feedback_object; + + +extern GLboolean +_mesa_valid_to_render(struct gl_context *ctx, const char *where); + +extern bool +_mesa_is_valid_prim_mode(const struct gl_context *ctx, GLenum mode); + +extern GLboolean +_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name); + +extern GLboolean +_mesa_valid_draw_indirect_multi(struct gl_context *ctx, GLsizei primcount, + GLsizei stride, const char *name); + +extern GLboolean +_mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count); + +extern bool +_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode, + const GLsizei *count, GLsizei primcount); + +extern GLboolean +_mesa_validate_DrawElements(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices); + +extern GLboolean +_mesa_validate_MultiDrawElements(struct gl_context *ctx, + GLenum mode, const GLsizei *count, + GLenum type, const GLvoid * const *indices, + GLsizei primcount); + +extern GLboolean +_mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices); + + +extern GLboolean +_mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint first, + GLsizei count, GLsizei primcount); + +extern GLboolean +_mesa_validate_DrawElementsInstanced(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLsizei primcount); + +extern GLboolean +_mesa_validate_DrawTransformFeedback(struct gl_context *ctx, + GLenum mode, + struct gl_transform_feedback_object *obj, + GLuint stream, + GLsizei numInstances); + +extern GLboolean +_mesa_validate_DrawArraysIndirect(struct gl_context *ctx, + GLenum mode, + const GLvoid *indirect); + +extern GLboolean +_mesa_validate_DrawElementsIndirect(struct gl_context *ctx, + GLenum mode, + GLenum type, + const GLvoid *indirect); + +extern GLboolean +_mesa_validate_MultiDrawArraysIndirect(struct gl_context *ctx, + GLenum mode, + const GLvoid *indirect, + GLsizei primcount, + GLsizei stride); + +extern GLboolean +_mesa_validate_MultiDrawElementsIndirect(struct gl_context *ctx, + GLenum mode, + GLenum type, + const GLvoid *indirect, + GLsizei primcount, + GLsizei stride); + +extern GLboolean +_mesa_validate_MultiDrawArraysIndirectCount(struct gl_context *ctx, + GLenum mode, + GLintptr indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride); + +extern GLboolean +_mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx, + GLenum mode, GLenum type, + GLintptr indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride); + +#endif diff --git a/lib/mesa/src/mesa/main/drawpix.c b/lib/mesa/src/mesa/main/drawpix.c index ec1d2618c..2f55dde7b 100644 --- a/lib/mesa/src/mesa/main/drawpix.c +++ b/lib/mesa/src/mesa/main/drawpix.c @@ -24,7 +24,7 @@ #include "glheader.h" #include "imports.h" -#include "api_validate.h" +#include "draw_validate.h" #include "bufferobj.h" #include "context.h" #include "drawpix.h" @@ -34,7 +34,6 @@ #include "image.h" #include "pbo.h" #include "state.h" -#include "dispatch.h" #include "glformats.h" #include "fbobject.h" diff --git a/lib/mesa/src/mesa/main/drawtex.c b/lib/mesa/src/mesa/main/drawtex.c index 9c4fdf90e..6114b3277 100644 --- a/lib/mesa/src/mesa/main/drawtex.c +++ b/lib/mesa/src/mesa/main/drawtex.c @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include "main/errors.h" #include "main/drawtex.h" #include "main/state.h" #include "main/imports.h" diff --git a/lib/mesa/src/mesa/main/errors.h b/lib/mesa/src/mesa/main/errors.h index 5ad5254ff..5911da295 100644 --- a/lib/mesa/src/mesa/main/errors.h +++ b/lib/mesa/src/mesa/main/errors.h @@ -38,15 +38,16 @@ #include <stdio.h> #include <stdarg.h> -#include "compiler.h" #include "glheader.h" -#include "mtypes.h" +#include "menums.h" #ifdef __cplusplus extern "C" { #endif +struct gl_context; + extern void _mesa_warning( struct gl_context *gc, const char *fmtString, ... ) PRINTFLIKE(2, 3); diff --git a/lib/mesa/src/mesa/main/eval.h b/lib/mesa/src/mesa/main/eval.h index 5b2fce119..938e3579b 100644 --- a/lib/mesa/src/mesa/main/eval.h +++ b/lib/mesa/src/mesa/main/eval.h @@ -37,7 +37,7 @@ #define EVAL_H -#include "main/mtypes.h" +#include "dd.h" #include <stdbool.h> diff --git a/lib/mesa/src/mesa/main/extensions.c b/lib/mesa/src/mesa/main/extensions.c index f185aa5aa..4d95a0727 100644 --- a/lib/mesa/src/mesa/main/extensions.c +++ b/lib/mesa/src/mesa/main/extensions.c @@ -39,7 +39,7 @@ struct gl_extensions _mesa_extension_override_enables; struct gl_extensions _mesa_extension_override_disables; -static char *extra_extensions = NULL; +static char *unrecognized_extensions = NULL; /** @@ -48,8 +48,6 @@ static char *extra_extensions = NULL; */ #define o(x) offsetof(struct gl_extensions, x) -static bool disabled_extensions[MESA_EXTENSION_COUNT]; - /** * Given an extension name, lookup up the corresponding member of struct * gl_extensions and return that member's index. If the name is @@ -78,8 +76,8 @@ name_to_index(const char* name) * Overrides extensions in \c ctx based on the values in * _mesa_extension_override_enables and _mesa_extension_override_disables. */ -static void -override_extensions_in_context(struct gl_context *ctx) +void +_mesa_override_extensions(struct gl_context *ctx) { unsigned i; const GLboolean *enables = @@ -131,9 +129,7 @@ _mesa_enable_sw_extensions(struct gl_context *ctx) ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE; ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE; ctx->Extensions.ARB_texture_filter_anisotropic = GL_TRUE; -#ifdef TEXTURE_FLOAT_ENABLED ctx->Extensions.ARB_texture_float = GL_TRUE; -#endif ctx->Extensions.ARB_texture_mirror_clamp_to_edge = GL_TRUE; ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE; ctx->Extensions.ARB_texture_rg = GL_TRUE; @@ -146,7 +142,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx) ctx->Extensions.ATI_texture_compression_3dc = GL_TRUE; ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE; ctx->Extensions.ATI_texture_mirror_once = GL_TRUE; - ctx->Extensions.ATI_separate_stencil = GL_TRUE; ctx->Extensions.EXT_blend_color = GL_TRUE; ctx->Extensions.EXT_blend_equation_separate = GL_TRUE; ctx->Extensions.EXT_blend_func_separate = GL_TRUE; @@ -198,66 +193,40 @@ set_extension(struct gl_extensions *ext, int i, GLboolean state) return offset; } -/** - * \brief Apply the \c MESA_EXTENSION_OVERRIDE environment variable. - * - * \c MESA_EXTENSION_OVERRIDE is a space-separated list of extensions to - * enable or disable. The list is processed thus: - * - Enable recognized extension names that are prefixed with '+'. - * - Disable recognized extension names that are prefixed with '-'. - * - Enable recognized extension names that are not prefixed. - * - Collect unrecognized extension names in a new string. - * - * \c MESA_EXTENSION_OVERRIDE was previously parsed during - * _mesa_one_time_init_extension_overrides. We just use the results of that - * parsing in this function. - * - * \return Space-separated list of unrecognized extension names (which must - * be freed). Does not return \c NULL. - */ -static char * -get_extension_override( struct gl_context *ctx ) -{ - override_extensions_in_context(ctx); - - if (extra_extensions == NULL) { - return calloc(1, sizeof(char)); - } else { - _mesa_problem(ctx, "Trying to enable unknown extensions: %s", - extra_extensions); - return strdup(extra_extensions); - } -} - /** - * \brief Free extra_extensions string + * \brief Free string pointed by unrecognized_extensions * - * These strings are allocated early during the first context creation by + * This string is allocated early during the first context creation by * _mesa_one_time_init_extension_overrides. */ static void free_unknown_extensions_strings(void) { - free(extra_extensions); + free(unrecognized_extensions); } /** - * \brief Initialize extension override tables. + * \brief Initialize extension override tables based on \c MESA_EXTENSION_OVERRIDE * * This should be called one time early during first context initialization. + + * \c MESA_EXTENSION_OVERRIDE is a space-separated list of extensions to + * enable or disable. The list is processed thus: + * - Enable recognized extension names that are prefixed with '+'. + * - Disable recognized extension names that are prefixed with '-'. + * - Enable recognized extension names that are not prefixed. + * - Collect unrecognized extension names in a new string. */ void -_mesa_one_time_init_extension_overrides(void) +_mesa_one_time_init_extension_overrides(struct gl_context *ctx) { const char *env_const = getenv("MESA_EXTENSION_OVERRIDE"); char *env; char *ext; - int len; size_t offset; - - atexit(free_unknown_extensions_strings); + unsigned unknown_ext = 0; memset(&_mesa_extension_override_enables, 0, sizeof(struct gl_extensions)); memset(&_mesa_extension_override_disables, 0, sizeof(struct gl_extensions)); @@ -266,18 +235,11 @@ _mesa_one_time_init_extension_overrides(void) return; } - /* extra_exts: List of unrecognized extensions. */ - extra_extensions = calloc(ALIGN(strlen(env_const) + 2, 4), sizeof(char)); - /* Copy env_const because strtok() is destructive. */ env = strdup(env_const); - if (env == NULL || - extra_extensions == NULL) { - free(env); - free(extra_extensions); + if (env == NULL) return; - } for (ext = strtok(env, " "); ext != NULL; ext = strtok(NULL, " ")) { int enable; @@ -299,31 +261,36 @@ _mesa_one_time_init_extension_overrides(void) i = name_to_index(ext); offset = set_extension(&_mesa_extension_override_enables, i, enable); - if (offset != 0 && (offset != o(dummy_true) || enable != GL_FALSE)) { - ((GLboolean *) &_mesa_extension_override_disables)[offset] = !enable; + offset = set_extension(&_mesa_extension_override_disables, i, !enable); + if (offset != 0) recognized = true; - } else { + else recognized = false; - } - - if (i >= 0) - disabled_extensions[i] = !enable; if (!recognized && enable) { - strcat(extra_extensions, ext); - strcat(extra_extensions, " "); + if (unknown_ext >= MAX_UNRECOGNIZED_EXTENSIONS) { + static bool warned; + + if (!warned) { + warned = true; + _mesa_problem(ctx, "Trying to enable too many unknown extension. " + "Only the first %d will be honoured", + MAX_UNRECOGNIZED_EXTENSIONS); + } + } else { + ctx->Extensions.unrecognized_extensions[unknown_ext] = ext; + unknown_ext++; + + _mesa_problem(ctx, "Trying to enable unknown extension: %s", ext); + } } } - free(env); - - /* Remove trailing space, and free if unused. */ - len = strlen(extra_extensions); - if (len == 0) { - free(extra_extensions); - extra_extensions = NULL; - } else if (extra_extensions[len - 1] == ' ') { - extra_extensions[len - 1] = '\0'; + if (!unknown_ext) { + free(env); + } else { + unrecognized_extensions = env; + atexit(free_unknown_extensions_strings); } } @@ -365,8 +332,7 @@ _mesa_extension_supported(const struct gl_context *ctx, extension_index i) const bool *base = (bool *) &ctx->Extensions; const struct mesa_extension *ext = _mesa_extension_table + i; - return !disabled_extensions[i] && - (ctx->Version >= ext->version[ctx->API]) && base[ext->offset]; + return (ctx->Version >= ext->version[ctx->API]) && base[ext->offset]; } /** @@ -408,9 +374,7 @@ _mesa_make_extension_string(struct gl_context *ctx) /* Number of extensions */ unsigned count; /* Indices of the extensions sorted by year */ - extension_index *extension_indices; - /* String of extra extensions. */ - char *extra_extensions = get_extension_override(ctx); + extension_index extension_indices[MESA_EXTENSION_COUNT]; unsigned k; unsigned j; unsigned maxYear = ~0; @@ -436,26 +400,21 @@ _mesa_make_extension_string(struct gl_context *ctx) ++count; } } - if (extra_extensions != NULL) - length += 1 + strlen(extra_extensions); /* +1 for space */ + for (k = 0; k < MAX_UNRECOGNIZED_EXTENSIONS; k++) + if (ctx->Extensions.unrecognized_extensions[k]) + length += 1 + strlen(ctx->Extensions.unrecognized_extensions[k]); /* +1 for space */ exts = calloc(ALIGN(length + 1, 4), sizeof(char)); if (exts == NULL) { - free(extra_extensions); return NULL; } - extension_indices = malloc(count * sizeof(extension_index)); - if (extension_indices == NULL) { - free(exts); - free(extra_extensions); - return NULL; - } - - /* Sort extensions in chronological order because certain old applications - * (e.g., Quake3 demo) store the extension list in a static size buffer so - * chronologically order ensure that the extensions that such applications - * expect will fit into that buffer. + /* Sort extensions in chronological order because idTech 2/3 games + * (e.g., Quake3 demo) store the extension list in a fixed size buffer. + * Some cases truncate, while others overflow the buffer. Resulting in + * misrendering and crashes, respectively. + * Address the former here, while the latter will be addressed by setting + * the MESA_EXTENSION_MAX_YEAR environment variable. */ j = 0; for (k = 0; k < MESA_EXTENSION_COUNT; ++k) { @@ -475,10 +434,11 @@ _mesa_make_extension_string(struct gl_context *ctx) strcat(exts, i->name); strcat(exts, " "); } - free(extension_indices); - if (extra_extensions != 0) { - strcat(exts, extra_extensions); - free(extra_extensions); + for (j = 0; j < MAX_UNRECOGNIZED_EXTENSIONS; j++) { + if (ctx->Extensions.unrecognized_extensions[j]) { + strcat(exts, ctx->Extensions.unrecognized_extensions[j]); + strcat(exts, " "); + } } return (GLubyte *) exts; @@ -500,6 +460,11 @@ _mesa_get_extension_count(struct gl_context *ctx) if (_mesa_extension_supported(ctx, k)) ctx->Extensions.Count++; } + + for (k = 0; k < MAX_UNRECOGNIZED_EXTENSIONS; ++k) { + if (ctx->Extensions.unrecognized_extensions[k]) + ctx->Extensions.Count++; + } return ctx->Extensions.Count; } @@ -521,5 +486,13 @@ _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index) } } + for (i = 0; i < MAX_UNRECOGNIZED_EXTENSIONS; ++i) { + if (ctx->Extensions.unrecognized_extensions[i]) { + if (n == index) + return (const GLubyte*) ctx->Extensions.unrecognized_extensions[i]; + else + ++n; + } + } return NULL; } diff --git a/lib/mesa/src/mesa/main/extensions.h b/lib/mesa/src/mesa/main/extensions.h index efef1be47..705d65dcd 100644 --- a/lib/mesa/src/mesa/main/extensions.h +++ b/lib/mesa/src/mesa/main/extensions.h @@ -36,7 +36,7 @@ #ifndef _EXTENSIONS_H_ #define _EXTENSIONS_H_ -#include "glheader.h" +#include "mtypes.h" #ifdef __cplusplus extern "C" { @@ -47,12 +47,14 @@ struct gl_extensions; extern void _mesa_enable_sw_extensions(struct gl_context *ctx); -extern void _mesa_one_time_init_extension_overrides(void); +extern void _mesa_one_time_init_extension_overrides(struct gl_context *ctx); extern void _mesa_init_extensions(struct gl_extensions *extentions); extern GLubyte *_mesa_make_extension_string(struct gl_context *ctx); +extern void _mesa_override_extensions(struct gl_context *ctx); + extern GLuint _mesa_get_extension_count(struct gl_context *ctx); @@ -104,6 +106,15 @@ _mesa_has_##name_str(const struct gl_context *ctx) \ #include "extensions_table.h" #undef EXT +/* Sometimes the driver wants to query the extension override status before + * a context is created. These variables are filled with extension override + * information before context creation. + * + * This can be useful during extension bring-up when an extension is + * partially implemented, but cannot yet be advertised as supported. + * + * Use it with care and keep access read-only. + */ extern struct gl_extensions _mesa_extension_override_enables; extern struct gl_extensions _mesa_extension_override_disables; diff --git a/lib/mesa/src/mesa/main/extensions_table.c b/lib/mesa/src/mesa/main/extensions_table.c index 1e37fbcc4..6241705de 100644 --- a/lib/mesa/src/mesa/main/extensions_table.c +++ b/lib/mesa/src/mesa/main/extensions_table.c @@ -23,7 +23,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "main/mtypes.h" #include "main/extensions.h" /** diff --git a/lib/mesa/src/mesa/main/externalobjects.c b/lib/mesa/src/mesa/main/externalobjects.c index e70280c96..56bf817a6 100644 --- a/lib/mesa/src/mesa/main/externalobjects.c +++ b/lib/mesa/src/mesa/main/externalobjects.c @@ -23,6 +23,8 @@ #include "macros.h" #include "mtypes.h" +#include "bufferobj.h" +#include "context.h" #include "externalobjects.h" #include "teximage.h" #include "texobj.h" @@ -148,8 +150,7 @@ _mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects) _mesa_debug(ctx, "%s(%d, %p)", func, n, memoryObjects); if (!ctx->Extensions.EXT_memory_object) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCreateMemoryObjectsEXT(unsupported)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); return; } @@ -195,9 +196,10 @@ _mesa_MemoryObjectParameterivEXT(GLuint memoryObject, GET_CURRENT_CONTEXT(ctx); struct gl_memory_object *memObj; + const char *func = "glMemoryObjectParameterivEXT"; + if (!ctx->Extensions.EXT_memory_object) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glMemoryObjectParameterivEXT(unsupported)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); return; } @@ -206,8 +208,7 @@ _mesa_MemoryObjectParameterivEXT(GLuint memoryObject, return; if (memObj->Immutable) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glMemoryObjectParameterivEXT(memoryObject is immutable"); + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(memoryObject is immutable", func); return; } @@ -224,8 +225,7 @@ _mesa_MemoryObjectParameterivEXT(GLuint memoryObject, return; invalid_pname: - _mesa_error(ctx, GL_INVALID_ENUM, - "glMemoryObjectParameterivEXT(pname=0x%x)", pname); + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); } void GLAPIENTRY @@ -236,9 +236,10 @@ _mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject, GET_CURRENT_CONTEXT(ctx); struct gl_memory_object *memObj; + const char *func = "glMemoryObjectParameterivEXT"; + if (!ctx->Extensions.EXT_memory_object) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetMemoryObjectParameterivEXT(unsupported)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); return; } @@ -259,8 +260,7 @@ _mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject, return; invalid_pname: - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetMemoryObjectParameterivEXT(pname=0x%x)", pname); + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); } static struct gl_memory_object * @@ -547,22 +547,144 @@ _mesa_TextureStorageMem1DEXT(GLuint texture, memory, offset, "glTextureStorageMem1DEXT"); } +/** + * Used as a placeholder for semaphore objects between glGenSemaphoresEXT() + * and glImportSemaphoreFdEXT(), so that glIsSemaphoreEXT() can work correctly. + */ +static struct gl_semaphore_object DummySemaphoreObject; + +/** + * Delete a semaphore object. Called via ctx->Driver.DeleteSemaphore(). + * Not removed from hash table here. + */ +void +_mesa_delete_semaphore_object(struct gl_context *ctx, + struct gl_semaphore_object *semObj) +{ + if (semObj != &DummySemaphoreObject) + free(semObj); +} + +/** + * Initialize a semaphore object to default values. + */ +void +_mesa_initialize_semaphore_object(struct gl_context *ctx, + struct gl_semaphore_object *obj, + GLuint name) +{ + memset(obj, 0, sizeof(struct gl_semaphore_object)); + obj->Name = name; +} + void GLAPIENTRY _mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores) { + GET_CURRENT_CONTEXT(ctx); + + const char *func = "glGenSemaphoresEXT"; + + if (MESA_VERBOSE & (VERBOSE_API)) + _mesa_debug(ctx, "%s(%d, %p)", func, n, semaphores); + + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func); + return; + } + + if (!semaphores) + return; + + _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects); + GLuint first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SemaphoreObjects, n); + if (first) { + for (GLsizei i = 0; i < n; i++) { + semaphores[i] = first + i; + _mesa_HashInsertLocked(ctx->Shared->SemaphoreObjects, + semaphores[i], &DummySemaphoreObject); + } + } + _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects); } void GLAPIENTRY _mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores) { + GET_CURRENT_CONTEXT(ctx); + + const char *func = "glDeleteSemaphoresEXT"; + + if (MESA_VERBOSE & (VERBOSE_API)) { + _mesa_debug(ctx, "%s(%d, %p)\n", func, n, semaphores); + } + + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func); + return; + } + + if (!semaphores) + return; + + _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects); + for (GLint i = 0; i < n; i++) { + if (semaphores[i] > 0) { + struct gl_semaphore_object *delObj + = _mesa_lookup_semaphore_object_locked(ctx, semaphores[i]); + if (delObj) { + _mesa_HashRemoveLocked(ctx->Shared->SemaphoreObjects, + semaphores[i]); + ctx->Driver.DeleteSemaphoreObject(ctx, delObj); + } + } + } + _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects); } GLboolean GLAPIENTRY _mesa_IsSemaphoreEXT(GLuint semaphore) { - return GL_FALSE; + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glIsSemaphoreEXT(unsupported)"); + return GL_FALSE; + } + + struct gl_semaphore_object *obj = + _mesa_lookup_semaphore_object(ctx, semaphore); + + return obj ? GL_TRUE : GL_FALSE; +} + +/** + * Helper that outputs the correct error status for parameter + * calls where no pnames are defined + */ +static void +semaphore_parameter_stub(const char* func, GLenum pname) +{ + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + /* EXT_semaphore and EXT_semaphore_fd define no parameters */ + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); } void GLAPIENTRY @@ -570,7 +692,9 @@ _mesa_SemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, const GLuint64 *params) { + const char *func = "glSemaphoreParameterui64vEXT"; + semaphore_parameter_stub(func, pname); } void GLAPIENTRY @@ -578,7 +702,9 @@ _mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, GLuint64 *params) { + const char *func = "glGetSemaphoreParameterui64vEXT"; + semaphore_parameter_stub(func, pname); } void GLAPIENTRY @@ -589,7 +715,57 @@ _mesa_WaitSemaphoreEXT(GLuint semaphore, const GLuint *textures, const GLenum *srcLayouts) { + GET_CURRENT_CONTEXT(ctx); + struct gl_semaphore_object *semObj = NULL; + struct gl_buffer_object **bufObjs = NULL; + struct gl_texture_object **texObjs = NULL; + + const char *func = "glWaitSemaphoreEXT"; + + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + semObj = _mesa_lookup_semaphore_object(ctx, semaphore); + if (!semObj) + return; + + FLUSH_VERTICES(ctx, 0); + FLUSH_CURRENT(ctx, 0); + + bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers); + if (!bufObjs) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)", + func, numBufferBarriers); + goto end; + } + for (unsigned i = 0; i < numBufferBarriers; i++) { + bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]); + } + + texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers); + if (!texObjs) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)", + func, numTextureBarriers); + goto end; + } + + for (unsigned i = 0; i < numTextureBarriers; i++) { + texObjs[i] = _mesa_lookup_texture(ctx, textures[i]); + } + + ctx->Driver.ServerWaitSemaphoreObject(ctx, semObj, + numBufferBarriers, bufObjs, + numTextureBarriers, texObjs, + srcLayouts); + +end: + free(bufObjs); + free(texObjs); } void GLAPIENTRY @@ -600,7 +776,57 @@ _mesa_SignalSemaphoreEXT(GLuint semaphore, const GLuint *textures, const GLenum *dstLayouts) { + GET_CURRENT_CONTEXT(ctx); + struct gl_semaphore_object *semObj = NULL; + struct gl_buffer_object **bufObjs = NULL; + struct gl_texture_object **texObjs = NULL; + + const char *func = "glSignalSemaphoreEXT"; + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + semObj = _mesa_lookup_semaphore_object(ctx, semaphore); + if (!semObj) + return; + + FLUSH_VERTICES(ctx, 0); + FLUSH_CURRENT(ctx, 0); + + bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers); + if (!bufObjs) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)", + func, numBufferBarriers); + goto end; + } + + for (unsigned i = 0; i < numBufferBarriers; i++) { + bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]); + } + + texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers); + if (!texObjs) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)", + func, numTextureBarriers); + goto end; + } + + for (unsigned i = 0; i < numTextureBarriers; i++) { + texObjs[i] = _mesa_lookup_texture(ctx, textures[i]); + } + + ctx->Driver.ServerSignalSemaphoreObject(ctx, semObj, + numBufferBarriers, bufObjs, + numTextureBarriers, texObjs, + dstLayouts); + +end: + free(bufObjs); + free(texObjs); } void GLAPIENTRY @@ -611,15 +837,15 @@ _mesa_ImportMemoryFdEXT(GLuint memory, { GET_CURRENT_CONTEXT(ctx); + const char *func = "glImportMemoryFdEXT"; + if (!ctx->Extensions.EXT_memory_object_fd) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glImportMemoryFdEXT(unsupported)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); return; } if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) { - _mesa_error(ctx, GL_INVALID_VALUE, "glImportMemoryFdEXT(handleType=%u)", - handleType); + _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); return; } @@ -636,5 +862,33 @@ _mesa_ImportSemaphoreFdEXT(GLuint semaphore, GLenum handleType, GLint fd) { + GET_CURRENT_CONTEXT(ctx); + + const char *func = "glImportSemaphoreFdEXT"; + + if (!ctx->Extensions.EXT_semaphore_fd) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); + return; + } + + struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx, + semaphore); + if (!semObj) + return; + + if (semObj == &DummySemaphoreObject) { + semObj = ctx->Driver.NewSemaphoreObject(ctx, semaphore); + if (!semObj) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); + return; + } + _mesa_HashInsert(ctx->Shared->SemaphoreObjects, semaphore, semObj); + } + ctx->Driver.ImportSemaphoreFd(ctx, semObj, fd); } diff --git a/lib/mesa/src/mesa/main/externalobjects.h b/lib/mesa/src/mesa/main/externalobjects.h index a9a12b821..75b0bc2ed 100644 --- a/lib/mesa/src/mesa/main/externalobjects.h +++ b/lib/mesa/src/mesa/main/externalobjects.h @@ -57,6 +57,26 @@ _mesa_lookup_memory_object_locked(struct gl_context *ctx, GLuint memory) _mesa_HashLookupLocked(ctx->Shared->MemoryObjects, memory); } +static inline struct gl_semaphore_object * +_mesa_lookup_semaphore_object(struct gl_context *ctx, GLuint semaphore) +{ + if (!semaphore) + return NULL; + + return (struct gl_semaphore_object *) + _mesa_HashLookup(ctx->Shared->SemaphoreObjects, semaphore); +} + +static inline struct gl_semaphore_object * +_mesa_lookup_semaphore_object_locked(struct gl_context *ctx, GLuint semaphore) +{ + if (!semaphore) + return NULL; + + return (struct gl_semaphore_object *) + _mesa_HashLookupLocked(ctx->Shared->SemaphoreObjects, semaphore); +} + extern void _mesa_init_memory_object_functions(struct dd_function_table *driver); @@ -65,7 +85,16 @@ _mesa_initialize_memory_object(struct gl_context *ctx, struct gl_memory_object *obj, GLuint name); extern void -_mesa_delete_memory_object(struct gl_context *ctx, struct gl_memory_object *mo); +_mesa_delete_memory_object(struct gl_context *ctx, + struct gl_memory_object *semObj); + +extern void +_mesa_initialize_semaphore_object(struct gl_context *ctx, + struct gl_semaphore_object *obj, + GLuint name); +extern void +_mesa_delete_semaphore_object(struct gl_context *ctx, + struct gl_semaphore_object *semObj); extern void GLAPIENTRY _mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects); diff --git a/lib/mesa/src/mesa/main/feedback.c b/lib/mesa/src/mesa/main/feedback.c index 699e2a855..65f4c35d9 100644 --- a/lib/mesa/src/mesa/main/feedback.c +++ b/lib/mesa/src/mesa/main/feedback.c @@ -35,7 +35,6 @@ #include "feedback.h" #include "macros.h" #include "mtypes.h" -#include "main/dispatch.h" #define FB_3D 0x01 diff --git a/lib/mesa/src/mesa/main/format_pack.c b/lib/mesa/src/mesa/main/format_pack.c index f9e194d31..6b183d55f 100644 --- a/lib/mesa/src/mesa/main/format_pack.c +++ b/lib/mesa/src/mesa/main/format_pack.c @@ -38,6 +38,8 @@ #include <stdint.h> +#include "config.h" +#include "errors.h" #include "format_pack.h" #include "format_utils.h" #include "macros.h" @@ -10752,6 +10754,10 @@ pack_float_Z_UNORM32(const GLfloat *src, void *dst) *d = (GLuint) (*src * scale); } +/** + ** Pack float to Z_FLOAT32 or Z_FLOAT32_X24S8. + **/ + static void pack_float_Z_FLOAT32(const GLfloat *src, void *dst) { @@ -10824,18 +10830,12 @@ pack_uint_Z_UNORM32(const GLuint *src, void *dst) *d = *src; } -static void -pack_uint_Z_FLOAT32(const GLuint *src, void *dst) -{ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; - *d = (GLuint) (*src * scale); - assert(*d >= 0.0f); - assert(*d <= 1.0f); -} +/** + ** Pack uint to Z_FLOAT32 or Z_FLOAT32_X24S8. + **/ static void -pack_uint_Z_FLOAT32_X24S8(const GLuint *src, void *dst) +pack_uint_Z_FLOAT32(const GLuint *src, void *dst) { GLfloat *d = ((GLfloat *) dst); const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; @@ -10859,9 +10859,8 @@ _mesa_get_pack_uint_z_func(mesa_format format) case MESA_FORMAT_Z_UNORM32: return pack_uint_Z_UNORM32; case MESA_FORMAT_Z_FLOAT32: - return pack_uint_Z_FLOAT32; case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - return pack_uint_Z_FLOAT32_X24S8; + return pack_uint_Z_FLOAT32; default: _mesa_problem(NULL, "unexpected format in _mesa_get_pack_uint_z_func()"); return NULL; diff --git a/lib/mesa/src/mesa/main/format_unpack.c b/lib/mesa/src/mesa/main/format_unpack.c index 21c55416b..b3289acd3 100644 --- a/lib/mesa/src/mesa/main/format_unpack.c +++ b/lib/mesa/src/mesa/main/format_unpack.c @@ -38,6 +38,7 @@ #include <stdint.h> +#include "errors.h" #include "format_unpack.h" #include "format_utils.h" #include "macros.h" diff --git a/lib/mesa/src/mesa/main/format_utils.c b/lib/mesa/src/mesa/main/format_utils.c index 31580750b..6959bf062 100644 --- a/lib/mesa/src/mesa/main/format_utils.c +++ b/lib/mesa/src/mesa/main/format_utils.c @@ -22,6 +22,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include "errors.h" #include "format_utils.h" #include "glformats.h" #include "format_pack.h" diff --git a/lib/mesa/src/mesa/main/format_utils.h b/lib/mesa/src/mesa/main/format_utils.h index 378997b38..78365cab5 100644 --- a/lib/mesa/src/mesa/main/format_utils.h +++ b/lib/mesa/src/mesa/main/format_utils.h @@ -31,6 +31,7 @@ #ifndef FORMAT_UTILS_H #define FORMAT_UTILS_H +#include "formats.h" #include "imports.h" #include "macros.h" #include "util/rounding.h" diff --git a/lib/mesa/src/mesa/main/glheader.h b/lib/mesa/src/mesa/main/glheader.h index 3f2a92378..e95fc9fb4 100644 --- a/lib/mesa/src/mesa/main/glheader.h +++ b/lib/mesa/src/mesa/main/glheader.h @@ -43,13 +43,13 @@ extern "C" { #endif -typedef int GLclampx; - - -#ifndef GL_OES_EGL_image -typedef void *GLeglImageOES; -#endif +/* Custom Mesa types to save space. */ +typedef unsigned short GLenum16; +typedef unsigned char GLbitfield8; +typedef unsigned short GLbitfield16; +typedef GLuint64 GLbitfield64; +/* Common GLES 1.0 and 2.0 tokens */ #ifndef GL_OES_EGL_image_external #define GL_TEXTURE_EXTERNAL_OES 0x8D65 @@ -58,6 +58,14 @@ typedef void *GLeglImageOES; #define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 #endif +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + + +/* GLES 1.0 only tokens */ + +typedef int GLclampx; #ifndef GL_OES_point_size_array #define GL_POINT_SIZE_ARRAY_OES 0x8B9C @@ -72,31 +80,15 @@ typedef void *GLeglImageOES; #define GL_TEXTURE_CROP_RECT_OES 0x8B9D #endif - -#ifndef GL_PROGRAM_BINARY_LENGTH_OES -#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 -#endif - -/* GLES 2.0 tokens */ -#ifndef GL_RGB565 -#define GL_RGB565 0x8D62 -#endif - #ifndef GL_TEXTURE_GEN_STR_OES #define GL_TEXTURE_GEN_STR_OES 0x8D60 #endif -#ifndef GL_OES_compressed_paletted_texture -#define GL_PALETTE4_RGB8_OES 0x8B90 -#define GL_PALETTE4_RGBA8_OES 0x8B91 -#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 -#define GL_PALETTE4_RGBA4_OES 0x8B93 -#define GL_PALETTE4_RGB5_A1_OES 0x8B94 -#define GL_PALETTE8_RGB8_OES 0x8B95 -#define GL_PALETTE8_RGBA8_OES 0x8B96 -#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 -#define GL_PALETTE8_RGBA4_OES 0x8B98 -#define GL_PALETTE8_RGB5_A1_OES 0x8B99 + +/* GLES 2.0 only tokens */ + +#ifndef GL_PROGRAM_BINARY_LENGTH_OES +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 #endif #ifndef GL_OES_texture_compression_astc @@ -122,34 +114,30 @@ typedef void *GLeglImageOES; #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 #endif -#ifndef GL_ES_VERSION_2_0 -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#define GL_SHADER_COMPILER 0x8DFA -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#endif - -#ifndef GL_ATI_texture_compression_3dc -#define GL_ATI_texture_compression_3dc 1 -#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 -#endif - -#ifndef GL_OES_compressed_ETC1_RGB8_texture -#define GL_ETC1_RGB8_OES 0x8D64 -#endif - #ifndef GL_EXT_shader_framebuffer_fetch #define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 #endif +#ifndef GL_EXT_disjoint_timer_query +#define GL_GPU_DISJOINT_EXT 0x8FBB +#endif + /* Inexplicably, GL_HALF_FLOAT_OES has a different value than GL_HALF_FLOAT. */ #ifndef GL_HALF_FLOAT_OES #define GL_HALF_FLOAT_OES 0x8D61 #endif +#ifndef GL_MESA_framebuffer_flip_y +#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB +#endif + +/* There is no formal spec for the following extension. */ +#ifndef GL_ATI_texture_compression_3dc +#define GL_ATI_texture_compression_3dc 1 +#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 +#endif + /** * Internal token to represent a GLSL shader program (a collection of @@ -161,28 +149,6 @@ typedef void *GLeglImageOES; #define GL_SHADER_PROGRAM_MESA 0x9999 -/* Several fields of struct gl_config can take these as values. Since - * GLX header files may not be available everywhere they need to be used, - * redefine them here. - */ -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 -#define GLX_NON_CONFORMANT_CONFIG 0x800D -#define GLX_SWAP_EXCHANGE_OML 0x8061 -#define GLX_SWAP_COPY_OML 0x8062 -#define GLX_SWAP_UNDEFINED_OML 0x8063 - -#define GLX_DONT_CARE 0xFFFFFFFF - - #ifdef __cplusplus } #endif diff --git a/lib/mesa/src/mesa/main/glspirv.c b/lib/mesa/src/mesa/main/glspirv.c new file mode 100644 index 000000000..04e46ba57 --- /dev/null +++ b/lib/mesa/src/mesa/main/glspirv.c @@ -0,0 +1,378 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "glspirv.h" +#include "errors.h" +#include "shaderobj.h" +#include "mtypes.h" + +#include "compiler/nir/nir.h" +#include "compiler/spirv/nir_spirv.h" + +#include "program/program.h" + +#include "util/u_atomic.h" + +void +_mesa_spirv_module_reference(struct gl_spirv_module **dest, + struct gl_spirv_module *src) +{ + struct gl_spirv_module *old = *dest; + + if (old && p_atomic_dec_zero(&old->RefCount)) + free(old); + + *dest = src; + + if (src) + p_atomic_inc(&src->RefCount); +} + +void +_mesa_shader_spirv_data_reference(struct gl_shader_spirv_data **dest, + struct gl_shader_spirv_data *src) +{ + struct gl_shader_spirv_data *old = *dest; + + if (old && p_atomic_dec_zero(&old->RefCount)) { + _mesa_spirv_module_reference(&(*dest)->SpirVModule, NULL); + ralloc_free(old); + } + + *dest = src; + + if (src) + p_atomic_inc(&src->RefCount); +} + +void +_mesa_spirv_shader_binary(struct gl_context *ctx, + unsigned n, struct gl_shader **shaders, + const void* binary, size_t length) +{ + struct gl_spirv_module *module; + struct gl_shader_spirv_data *spirv_data; + + module = malloc(sizeof(*module) + length); + if (!module) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary"); + return; + } + + p_atomic_set(&module->RefCount, 0); + module->Length = length; + memcpy(&module->Binary[0], binary, length); + + for (int i = 0; i < n; ++i) { + struct gl_shader *sh = shaders[i]; + + spirv_data = rzalloc(NULL, struct gl_shader_spirv_data); + _mesa_shader_spirv_data_reference(&sh->spirv_data, spirv_data); + _mesa_spirv_module_reference(&spirv_data->SpirVModule, module); + + sh->CompileStatus = COMPILE_FAILURE; + + free((void *)sh->Source); + sh->Source = NULL; + free((void *)sh->FallbackSource); + sh->FallbackSource = NULL; + + ralloc_free(sh->ir); + sh->ir = NULL; + ralloc_free(sh->symbols); + sh->symbols = NULL; + } +} + +/** + * This is the equivalent to compiler/glsl/linker.cpp::link_shaders() + * but for SPIR-V programs. + * + * This method just creates the gl_linked_shader structs with a reference to + * the SPIR-V data collected during previous steps. + * + * The real linking happens later in the driver-specifc call LinkShader(). + * This is so backends can implement different linking strategies for + * SPIR-V programs. + */ +void +_mesa_spirv_link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) +{ + prog->data->LinkStatus = LINKING_SUCCESS; + prog->data->Validated = false; + + for (unsigned i = 0; i < prog->NumShaders; i++) { + struct gl_shader *shader = prog->Shaders[i]; + gl_shader_stage shader_type = shader->Stage; + + /* We only support one shader per stage. The gl_spirv spec doesn't seem + * to prevent this, but the way the API is designed, requiring all shaders + * to be specialized with an entry point, makes supporting this quite + * undefined. + * + * TODO: Turn this into a proper error once the spec bug + * <https://gitlab.khronos.org/opengl/API/issues/58> is resolved. + */ + if (prog->_LinkedShaders[shader_type]) { + ralloc_strcat(&prog->data->InfoLog, + "\nError trying to link more than one SPIR-V shader " + "per stage.\n"); + prog->data->LinkStatus = LINKING_FAILURE; + return; + } + + assert(shader->spirv_data); + + struct gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader); + linked->Stage = shader_type; + + /* Create program and attach it to the linked shader */ + struct gl_program *gl_prog = + ctx->Driver.NewProgram(ctx, + _mesa_shader_stage_to_program(shader_type), + prog->Name, false); + if (!gl_prog) { + prog->data->LinkStatus = LINKING_FAILURE; + _mesa_delete_linked_shader(ctx, linked); + return; + } + + _mesa_reference_shader_program_data(ctx, + &gl_prog->sh.data, + prog->data); + + /* Don't use _mesa_reference_program() just take ownership */ + linked->Program = gl_prog; + + /* Reference the SPIR-V data from shader to the linked shader */ + _mesa_shader_spirv_data_reference(&linked->spirv_data, + shader->spirv_data); + + prog->_LinkedShaders[shader_type] = linked; + prog->data->linked_stages |= 1 << shader_type; + } + + int last_vert_stage = + util_last_bit(prog->data->linked_stages & + ((1 << (MESA_SHADER_GEOMETRY + 1)) - 1)); + + if (last_vert_stage) + prog->last_vert_prog = prog->_LinkedShaders[last_vert_stage - 1]->Program; +} + +nir_shader * +_mesa_spirv_to_nir(struct gl_context *ctx, + const struct gl_shader_program *prog, + gl_shader_stage stage, + const nir_shader_compiler_options *options) +{ + nir_shader *nir = NULL; + + struct gl_linked_shader *linked_shader = prog->_LinkedShaders[stage]; + assert (linked_shader); + + struct gl_shader_spirv_data *spirv_data = linked_shader->spirv_data; + assert(spirv_data); + + struct gl_spirv_module *spirv_module = spirv_data->SpirVModule; + assert (spirv_module != NULL); + + const char *entry_point_name = spirv_data->SpirVEntryPoint; + assert(entry_point_name); + + struct nir_spirv_specialization *spec_entries = + calloc(sizeof(*spec_entries), + spirv_data->NumSpecializationConstants); + + for (unsigned i = 0; i < spirv_data->NumSpecializationConstants; ++i) { + spec_entries[i].id = spirv_data->SpecializationConstantsIndex[i]; + spec_entries[i].data32 = spirv_data->SpecializationConstantsValue[i]; + spec_entries[i].defined_on_module = false; + } + + const struct spirv_to_nir_options spirv_options = { + .lower_workgroup_access_to_offsets = true, + .caps = ctx->Const.SpirVCapabilities + }; + + nir_function *entry_point = + spirv_to_nir((const uint32_t *) &spirv_module->Binary[0], + spirv_module->Length / 4, + spec_entries, spirv_data->NumSpecializationConstants, + stage, entry_point_name, + &spirv_options, + options); + free(spec_entries); + + assert (entry_point); + nir = entry_point->shader; + assert(nir->info.stage == stage); + + nir->options = options; + + nir->info.name = + ralloc_asprintf(nir, "SPIRV:%s:%d", + _mesa_shader_stage_to_abbrev(nir->info.stage), + prog->Name); + nir_validate_shader(nir, "after spirv_to_nir"); + + nir->info.separate_shader = linked_shader->Program->info.separate_shader; + + /* We have to lower away local constant initializers right before we + * inline functions. That way they get properly initialized at the top + * of the function and not at the top of its caller. + */ + NIR_PASS_V(nir, nir_lower_constant_initializers, nir_var_local); + NIR_PASS_V(nir, nir_lower_returns); + NIR_PASS_V(nir, nir_inline_functions); + NIR_PASS_V(nir, nir_copy_prop); + + /* Pick off the single entrypoint that we want */ + foreach_list_typed_safe(nir_function, func, node, &nir->functions) { + if (func != entry_point) + exec_node_remove(&func->node); + } + assert(exec_list_length(&nir->functions) == 1); + + /* Split member structs. We do this before lower_io_to_temporaries so that + * it doesn't lower system values to temporaries by accident. + */ + NIR_PASS_V(nir, nir_split_var_copies); + NIR_PASS_V(nir, nir_split_per_member_structs); + + if (nir->info.stage == MESA_SHADER_VERTEX) + nir_remap_dual_slot_attributes(nir, &linked_shader->Program->DualSlotInputs); + + return nir; +} + +void GLAPIENTRY +_mesa_SpecializeShaderARB(GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader *sh; + bool has_entry_point; + struct nir_spirv_specialization *spec_entries = NULL; + + if (!ctx->Extensions.ARB_gl_spirv) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glSpecializeShaderARB"); + return; + } + + sh = _mesa_lookup_shader_err(ctx, shader, "glSpecializeShaderARB"); + if (!sh) + return; + + if (!sh->spirv_data) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glSpecializeShaderARB(not SPIR-V)"); + return; + } + + if (sh->CompileStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glSpecializeShaderARB(already specialized)"); + return; + } + + struct gl_shader_spirv_data *spirv_data = sh->spirv_data; + + /* From the GL_ARB_gl_spirv spec: + * + * "The OpenGL API expects the SPIR-V module to have already been + * validated, and can return an error if it discovers anything invalid + * in the module. An invalid SPIR-V module is allowed to result in + * undefined behavior." + * + * However, the following errors still need to be detected (from the same + * spec): + * + * "INVALID_VALUE is generated if <pEntryPoint> does not name a valid + * entry point for <shader>. + * + * INVALID_VALUE is generated if any element of <pConstantIndex> + * refers to a specialization constant that does not exist in the + * shader module contained in <shader>." + * + * We cannot flag those errors a-priori because detecting them requires + * parsing the module. However, flagging them during specialization is okay, + * since it makes no difference in terms of application-visible state. + */ + spec_entries = calloc(sizeof(*spec_entries), numSpecializationConstants); + + for (unsigned i = 0; i < numSpecializationConstants; ++i) { + spec_entries[i].id = pConstantIndex[i]; + spec_entries[i].data32 = pConstantValue[i]; + spec_entries[i].defined_on_module = false; + } + + has_entry_point = + gl_spirv_validation((uint32_t *)&spirv_data->SpirVModule->Binary[0], + spirv_data->SpirVModule->Length / 4, + spec_entries, numSpecializationConstants, + sh->Stage, pEntryPoint); + + /* See previous spec comment */ + if (!has_entry_point) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glSpecializeShaderARB(\"%s\" is not a valid entry point" + " for shader)", pEntryPoint); + goto end; + } + + for (unsigned i = 0; i < numSpecializationConstants; ++i) { + if (spec_entries[i].defined_on_module == false) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glSpecializeShaderARB(constant \"%i\" does not exist " + "in shader)", spec_entries[i].id); + goto end; + } + } + + spirv_data->SpirVEntryPoint = ralloc_strdup(spirv_data, pEntryPoint); + + /* Note that we didn't make a real compilation of the module (spirv_to_nir), + * but just checked some error conditions. Real "compilation" will be done + * later, upon linking. + */ + sh->CompileStatus = COMPILE_SUCCESS; + + spirv_data->NumSpecializationConstants = numSpecializationConstants; + spirv_data->SpecializationConstantsIndex = + rzalloc_array_size(spirv_data, sizeof(GLuint), + numSpecializationConstants); + spirv_data->SpecializationConstantsValue = + rzalloc_array_size(spirv_data, sizeof(GLuint), + numSpecializationConstants); + for (unsigned i = 0; i < numSpecializationConstants; ++i) { + spirv_data->SpecializationConstantsIndex[i] = pConstantIndex[i]; + spirv_data->SpecializationConstantsValue[i] = pConstantValue[i]; + } + + end: + free(spec_entries); +} diff --git a/lib/mesa/src/mesa/main/glspirv.h b/lib/mesa/src/mesa/main/glspirv.h new file mode 100644 index 000000000..8025c17c0 --- /dev/null +++ b/lib/mesa/src/mesa/main/glspirv.h @@ -0,0 +1,111 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef GLSPIRV_H +#define GLSPIRV_H + +#include "compiler/nir/nir.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gl_shader_program; +struct gl_context; +struct gl_shader; + +/** + * A SPIR-V module contains the raw SPIR-V binary as set by ShaderBinary. + * + * It is reference-counted, because the same module can be attached to multiple + * shader objects simultaneously. + */ +struct gl_spirv_module { + unsigned RefCount; + GLint Length; + char Binary[0]; +}; + +/** + * SPIR-V data needed to compile and link a SPIR-V shader. + * + * It includes a SPIR-V binary that is potentially shared among different + * shaders; and shader-specific specialization constants and entry point. + * + * It is reference-counted because it is shared between gl_shader and its + * corresponding gl_linked_shader. + */ +struct gl_shader_spirv_data { + GLint RefCount; + + struct gl_spirv_module *SpirVModule; + + GLchar *SpirVEntryPoint; + + GLuint NumSpecializationConstants; + GLuint *SpecializationConstantsIndex; + GLuint *SpecializationConstantsValue; +}; + +void +_mesa_spirv_module_reference(struct gl_spirv_module **dest, + struct gl_spirv_module *src); + +void +_mesa_shader_spirv_data_reference(struct gl_shader_spirv_data **dest, + struct gl_shader_spirv_data *src); + +void +_mesa_spirv_shader_binary(struct gl_context *ctx, + unsigned n, struct gl_shader **shaders, + const void* binary, size_t length); + +void +_mesa_spirv_link_shaders(struct gl_context *ctx, + struct gl_shader_program *prog); + +nir_shader * +_mesa_spirv_to_nir(struct gl_context *ctx, + const struct gl_shader_program *prog, + gl_shader_stage stage, + const nir_shader_compiler_options *options); + +/** + * \name API functions + */ +/*@{*/ + +void GLAPIENTRY +_mesa_SpecializeShaderARB(GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue); + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* GLSPIRV_H */ diff --git a/lib/mesa/src/mesa/main/histogram.c b/lib/mesa/src/mesa/main/histogram.c index 5759763d4..5696f548c 100644 --- a/lib/mesa/src/mesa/main/histogram.c +++ b/lib/mesa/src/mesa/main/histogram.c @@ -26,7 +26,6 @@ #include "glheader.h" #include "context.h" #include "histogram.h" -#include "main/dispatch.h" /********************************************************************** diff --git a/lib/mesa/src/mesa/main/image.h b/lib/mesa/src/mesa/main/image.h index b5075be4b..7955bbb7c 100644 --- a/lib/mesa/src/mesa/main/image.h +++ b/lib/mesa/src/mesa/main/image.h @@ -28,7 +28,6 @@ #include "glheader.h" -#include "compiler.h" struct gl_context; struct gl_pixelstore_attrib; diff --git a/lib/mesa/src/mesa/main/matrix.c b/lib/mesa/src/mesa/main/matrix.c index 83f081e88..8065a8370 100644 --- a/lib/mesa/src/mesa/main/matrix.c +++ b/lib/mesa/src/mesa/main/matrix.c @@ -657,20 +657,16 @@ void _mesa_update_modelview_project( struct gl_context *ctx, GLuint new_state ) * _math_matrix_ctr() for each element to initialize it. */ static void -init_matrix_stack( struct gl_matrix_stack *stack, - GLuint maxDepth, GLuint dirtyFlag ) +init_matrix_stack(struct gl_matrix_stack *stack, + GLuint maxDepth, GLuint dirtyFlag) { - GLuint i; - stack->Depth = 0; stack->MaxDepth = maxDepth; stack->DirtyFlag = dirtyFlag; /* The stack will be dynamically resized at glPushMatrix() time */ stack->Stack = calloc(1, sizeof(GLmatrix)); stack->StackSize = 1; - for (i = 0; i < stack->StackSize; i++) { - _math_matrix_ctr(&stack->Stack[i]); - } + _math_matrix_ctr(&stack->Stack[0]); stack->Top = stack->Stack; } diff --git a/lib/mesa/src/mesa/main/menums.h b/lib/mesa/src/mesa/main/menums.h new file mode 100644 index 000000000..40b16cb9c --- /dev/null +++ b/lib/mesa/src/mesa/main/menums.h @@ -0,0 +1,213 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * Copyright (C) 2018 Advanced Micro Devices, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file menums.h + * Often used definitions and enums. + */ + +#ifndef MENUMS_H +#define MENUMS_H + +#include "util/macros.h" + +/** + * Enum for the OpenGL APIs we know about and may support. + * + * NOTE: This must match the api_enum table in + * src/mesa/main/get_hash_generator.py + */ +typedef enum +{ + API_OPENGL_COMPAT, /* legacy / compatibility contexts */ + API_OPENGLES, + API_OPENGLES2, + API_OPENGL_CORE, + API_OPENGL_LAST = API_OPENGL_CORE +} gl_api; + +/** + * An index for each type of texture object. These correspond to the GL + * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc. + * Note: the order is from highest priority to lowest priority. + */ +typedef enum +{ + TEXTURE_2D_MULTISAMPLE_INDEX, + TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX, + TEXTURE_CUBE_ARRAY_INDEX, + TEXTURE_BUFFER_INDEX, + TEXTURE_2D_ARRAY_INDEX, + TEXTURE_1D_ARRAY_INDEX, + TEXTURE_EXTERNAL_INDEX, + TEXTURE_CUBE_INDEX, + TEXTURE_3D_INDEX, + TEXTURE_RECT_INDEX, + TEXTURE_2D_INDEX, + TEXTURE_1D_INDEX, + NUM_TEXTURE_TARGETS +} gl_texture_index; + +/** + * Remapped color logical operations + * + * With the exception of NVIDIA hardware, which consumes the OpenGL enumerants + * directly, everything wants this mapping of color logical operations. + * + * Fun fact: These values are just the bit-reverse of the low-nibble of the GL + * enumerant values (i.e., `GL_NOOP & 0x0f` is `b0101' while + * \c COLOR_LOGICOP_NOOP is `b1010`). + * + * Fun fact #2: These values are just an encoding of the operation as a table + * of bit values. The result of the logic op is: + * + * result_bit = (logic_op >> (2 * src_bit + dst_bit)) & 1 + * + * For the GL enums, the result is: + * + * result_bit = logic_op & (1 << (2 * src_bit + dst_bit)) + */ +enum PACKED gl_logicop_mode { + COLOR_LOGICOP_CLEAR = 0, + COLOR_LOGICOP_NOR = 1, + COLOR_LOGICOP_AND_INVERTED = 2, + COLOR_LOGICOP_COPY_INVERTED = 3, + COLOR_LOGICOP_AND_REVERSE = 4, + COLOR_LOGICOP_INVERT = 5, + COLOR_LOGICOP_XOR = 6, + COLOR_LOGICOP_NAND = 7, + COLOR_LOGICOP_AND = 8, + COLOR_LOGICOP_EQUIV = 9, + COLOR_LOGICOP_NOOP = 10, + COLOR_LOGICOP_OR_INVERTED = 11, + COLOR_LOGICOP_COPY = 12, + COLOR_LOGICOP_OR_REVERSE = 13, + COLOR_LOGICOP_OR = 14, + COLOR_LOGICOP_SET = 15 +}; + +/** + * Indexes for all renderbuffers + */ +typedef enum +{ + /* the four standard color buffers */ + BUFFER_FRONT_LEFT, + BUFFER_BACK_LEFT, + BUFFER_FRONT_RIGHT, + BUFFER_BACK_RIGHT, + BUFFER_DEPTH, + BUFFER_STENCIL, + BUFFER_ACCUM, + /* optional aux buffer */ + BUFFER_AUX0, + /* generic renderbuffers */ + BUFFER_COLOR0, + BUFFER_COLOR1, + BUFFER_COLOR2, + BUFFER_COLOR3, + BUFFER_COLOR4, + BUFFER_COLOR5, + BUFFER_COLOR6, + BUFFER_COLOR7, + BUFFER_COUNT, + BUFFER_NONE = -1, +} gl_buffer_index; + +typedef enum +{ + MAP_USER, + MAP_INTERNAL, + MAP_COUNT +} gl_map_buffer_index; + +/** @{ + * + * These are a mapping of the GL_ARB_debug_output/GL_KHR_debug enums + * to small enums suitable for use as an array index. + */ + +enum mesa_debug_source +{ + MESA_DEBUG_SOURCE_API, + MESA_DEBUG_SOURCE_WINDOW_SYSTEM, + MESA_DEBUG_SOURCE_SHADER_COMPILER, + MESA_DEBUG_SOURCE_THIRD_PARTY, + MESA_DEBUG_SOURCE_APPLICATION, + MESA_DEBUG_SOURCE_OTHER, + MESA_DEBUG_SOURCE_COUNT +}; + +enum mesa_debug_type +{ + MESA_DEBUG_TYPE_ERROR, + MESA_DEBUG_TYPE_DEPRECATED, + MESA_DEBUG_TYPE_UNDEFINED, + MESA_DEBUG_TYPE_PORTABILITY, + MESA_DEBUG_TYPE_PERFORMANCE, + MESA_DEBUG_TYPE_OTHER, + MESA_DEBUG_TYPE_MARKER, + MESA_DEBUG_TYPE_PUSH_GROUP, + MESA_DEBUG_TYPE_POP_GROUP, + MESA_DEBUG_TYPE_COUNT +}; + +enum mesa_debug_severity +{ + MESA_DEBUG_SEVERITY_LOW, + MESA_DEBUG_SEVERITY_MEDIUM, + MESA_DEBUG_SEVERITY_HIGH, + MESA_DEBUG_SEVERITY_NOTIFICATION, + MESA_DEBUG_SEVERITY_COUNT +}; + +/** @} */ + +/** Set a single bit */ +#define BITFIELD_BIT(b) (1u << (b)) +/** Set all bits up to excluding bit b */ +#define BITFIELD_MASK(b) \ + ((b) == 32 ? (~0u) : BITFIELD_BIT((b) % 32) - 1) +/** Set count bits starting from bit b */ +#define BITFIELD_RANGE(b, count) \ + (BITFIELD_MASK((b) + (count)) & ~BITFIELD_MASK(b)) + + +/** + * \name 64-bit extension of GLbitfield. + */ +/*@{*/ + +/** Set a single bit */ +#define BITFIELD64_BIT(b) (1ull << (b)) +/** Set all bits up to excluding bit b */ +#define BITFIELD64_MASK(b) \ + ((b) == 64 ? (~0ull) : BITFIELD64_BIT(b) - 1) +/** Set count bits starting from bit b */ +#define BITFIELD64_RANGE(b, count) \ + (BITFIELD64_MASK((b) + (count)) & ~BITFIELD64_MASK(b)) + +#endif diff --git a/lib/mesa/src/mesa/main/meson.build b/lib/mesa/src/mesa/main/meson.build new file mode 100644 index 000000000..a5f0e02c6 --- /dev/null +++ b/lib/mesa/src/mesa/main/meson.build @@ -0,0 +1,46 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +main_dispatch_h = custom_target( + 'dispatch.h', + input : [files('../../mapi/glapi/gen/gl_table.py'), gl_and_es_api_files], + output : 'dispatch.h', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@', '-m', 'remap_table'], + depend_files : glapi_gen_depends, + capture : true, +) + +main_marshal_generated_h = custom_target( + 'marshal_generated.h', + input : [files('../../mapi/glapi/gen/gl_marshal_h.py'), gl_and_es_api_files], + output : 'marshal_generated.h', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : files('../../mapi/glapi/gen/marshal_XML.py') + glapi_gen_depends, + capture : true, +) + +main_remap_helper_h = custom_target( + 'remap_helper.h', + input : [files('../../mapi/glapi/gen/remap_helper.py'), gl_and_es_api_files], + output : 'remap_helper.h', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : glapi_gen_depends, + capture : true, +) diff --git a/lib/mesa/src/mesa/main/mipmap.h b/lib/mesa/src/mesa/main/mipmap.h index d11c7fada..3ec997217 100644 --- a/lib/mesa/src/mesa/main/mipmap.h +++ b/lib/mesa/src/mesa/main/mipmap.h @@ -26,8 +26,15 @@ #ifndef MIPMAP_H #define MIPMAP_H -#include "mtypes.h" +#include "glheader.h" +struct gl_context; +struct gl_texture_object; + +unsigned +_mesa_compute_num_levels(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum target); extern void _mesa_generate_mipmap_level(GLenum target, diff --git a/lib/mesa/src/mesa/main/mm.c b/lib/mesa/src/mesa/main/mm.c index 473e90fc2..5f0bfe969 100644 --- a/lib/mesa/src/mesa/main/mm.c +++ b/lib/mesa/src/mesa/main/mm.c @@ -26,7 +26,6 @@ #include <stdio.h> #include <stdlib.h> -#include "compiler.h" #include "mm.h" diff --git a/lib/mesa/src/mesa/main/multisample.h b/lib/mesa/src/mesa/main/multisample.h index a7cd2918d..49683cacd 100644 --- a/lib/mesa/src/mesa/main/multisample.h +++ b/lib/mesa/src/mesa/main/multisample.h @@ -55,6 +55,7 @@ _mesa_MinSampleShading(GLclampf value); extern GLenum _mesa_check_sample_count(struct gl_context *ctx, GLenum target, - GLenum internalFormat, GLsizei samples); + GLenum internalFormat, GLsizei samples, + GLsizei storageSamples); #endif diff --git a/lib/mesa/src/mesa/main/pack.h b/lib/mesa/src/mesa/main/pack.h index ac0a099e3..8625a145f 100644 --- a/lib/mesa/src/mesa/main/pack.h +++ b/lib/mesa/src/mesa/main/pack.h @@ -28,8 +28,10 @@ #define PACK_H -#include "mtypes.h" +#include "glheader.h" +struct gl_context; +struct gl_pixelstore_attrib; extern void _mesa_unpack_polygon_stipple(const GLubyte *pattern, GLuint dest[32], diff --git a/lib/mesa/src/mesa/main/pbo.c b/lib/mesa/src/mesa/main/pbo.c index 7762324a4..cea55f2a0 100644 --- a/lib/mesa/src/mesa/main/pbo.c +++ b/lib/mesa/src/mesa/main/pbo.c @@ -31,6 +31,7 @@ +#include "errors.h" #include "glheader.h" #include "bufferobj.h" #include "glformats.h" diff --git a/lib/mesa/src/mesa/main/pbo.h b/lib/mesa/src/mesa/main/pbo.h index b3f24e62b..bc764175f 100644 --- a/lib/mesa/src/mesa/main/pbo.h +++ b/lib/mesa/src/mesa/main/pbo.h @@ -28,8 +28,10 @@ #define PBO_H -#include "mtypes.h" +#include "glheader.h" +struct gl_context; +struct gl_pixelstore_attrib; extern GLboolean _mesa_validate_pbo_access(GLuint dimensions, diff --git a/lib/mesa/src/mesa/main/pixeltransfer.h b/lib/mesa/src/mesa/main/pixeltransfer.h index b0a301f26..caa2911fc 100644 --- a/lib/mesa/src/mesa/main/pixeltransfer.h +++ b/lib/mesa/src/mesa/main/pixeltransfer.h @@ -28,7 +28,9 @@ #define PIXELTRANSFER_H -#include "mtypes.h" +#include "glheader.h" + +struct gl_context; extern void diff --git a/lib/mesa/src/mesa/main/program_binary.c b/lib/mesa/src/mesa/main/program_binary.c new file mode 100644 index 000000000..7390fef58 --- /dev/null +++ b/lib/mesa/src/mesa/main/program_binary.c @@ -0,0 +1,321 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (c) 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file program_binary.c + * + * Helper functions for serializing a binary program. + */ + + +#include "compiler/blob.h" +#include "compiler/glsl/serialize.h" +#include "main/errors.h" +#include "main/mtypes.h" +#include "main/shaderapi.h" +#include "util/bitscan.h" +#include "util/crc32.h" +#include "program_binary.h" +#include "program/prog_parameter.h" + +/** + * Mesa supports one binary format, but it must differentiate between formats + * produced by different drivers and different Mesa versions. + * + * Mesa uses a uint32_t value to specify an internal format. The only format + * defined has one uint32_t value of 0, followed by 20 bytes specifying a sha1 + * that uniquely identifies the Mesa driver type and version. + */ + +struct program_binary_header { + /* If internal_format is 0, it must be followed by the 20 byte sha1 that + * identifies the Mesa driver and version supported. If we want to support + * something besides a sha1, then a new internal_format value can be added. + */ + uint32_t internal_format; + uint8_t sha1[20]; + /* Fields following sha1 can be changed since the sha1 will guarantee that + * the binary only works with the same Mesa version. + */ + uint32_t size; + uint32_t crc32; +}; + +/** + * Returns the header size needed for a binary + */ +static unsigned +get_program_binary_header_size(void) +{ + return sizeof(struct program_binary_header); +} + +static bool +write_program_binary(const void *payload, unsigned payload_size, + const void *sha1, void *binary, unsigned binary_size, + GLenum *binary_format) +{ + struct program_binary_header *hdr = binary; + + if (binary_size < sizeof(*hdr)) + return false; + + /* binary_size is the size of the buffer provided by the application. + * Make sure our program (payload) will fit in the buffer. + */ + if (payload_size > binary_size - sizeof(*hdr)) + return false; + + hdr->internal_format = 0; + memcpy(hdr->sha1, sha1, sizeof(hdr->sha1)); + memcpy(hdr + 1, payload, payload_size); + hdr->size = payload_size; + + hdr->crc32 = util_hash_crc32(hdr + 1, payload_size); + *binary_format = GL_PROGRAM_BINARY_FORMAT_MESA; + + return true; +} + +static bool +simple_header_checks(const struct program_binary_header *hdr, unsigned length) +{ + if (hdr == NULL || length < sizeof(*hdr)) + return false; + + if (hdr->internal_format != 0) + return false; + + return true; +} + +static bool +check_crc32(const struct program_binary_header *hdr, unsigned length) +{ + uint32_t crc32; + unsigned crc32_len; + + crc32_len = hdr->size; + if (crc32_len > length - sizeof(*hdr)) + return false; + + crc32 = util_hash_crc32(hdr + 1, crc32_len); + if (hdr->crc32 != crc32) + return false; + + return true; +} + +static bool +is_program_binary_valid(GLenum binary_format, const void *sha1, + const struct program_binary_header *hdr, + unsigned length) +{ + if (binary_format != GL_PROGRAM_BINARY_FORMAT_MESA) + return false; + + if (!simple_header_checks(hdr, length)) + return false; + + if (memcmp(hdr->sha1, sha1, sizeof(hdr->sha1)) != 0) + return false; + + if (!check_crc32(hdr, length)) + return false; + + return true; +} + +/** + * Returns the payload within the binary. + * + * If NULL is returned, then the binary not supported. If non-NULL is + * returned, it will be a pointer contained within the specified `binary` + * buffer. + * + * This can be used to access the payload of `binary` during the + * glProgramBinary call. + */ +static const void* +get_program_binary_payload(GLenum binary_format, const void *sha1, + const void *binary, unsigned length) +{ + const struct program_binary_header *hdr = binary; + if (!is_program_binary_valid(binary_format, sha1, hdr, length)) + return NULL; + return (const uint8_t*)binary + sizeof(*hdr); +} + +static void +write_program_payload(struct gl_context *ctx, struct blob *blob, + struct gl_shader_program *sh_prog) +{ + for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { + struct gl_linked_shader *shader = sh_prog->_LinkedShaders[stage]; + if (shader) + ctx->Driver.ProgramBinarySerializeDriverBlob(ctx, sh_prog, + shader->Program); + } + + serialize_glsl_program(blob, ctx, sh_prog); + + for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { + struct gl_linked_shader *shader = sh_prog->_LinkedShaders[stage]; + if (shader) { + struct gl_program *prog = sh_prog->_LinkedShaders[stage]->Program; + ralloc_free(prog->driver_cache_blob); + prog->driver_cache_blob = NULL; + prog->driver_cache_blob_size = 0; + } + } +} + +static bool +read_program_payload(struct gl_context *ctx, struct blob_reader *blob, + GLenum binary_format, struct gl_shader_program *sh_prog) +{ + if (!deserialize_glsl_program(blob, ctx, sh_prog)) + return false; + + unsigned int stage; + for (stage = 0; stage < ARRAY_SIZE(sh_prog->_LinkedShaders); stage++) { + struct gl_linked_shader *shader = sh_prog->_LinkedShaders[stage]; + if (!shader) + continue; + + ctx->Driver.ProgramBinaryDeserializeDriverBlob(ctx, sh_prog, + shader->Program); + } + + return true; +} + +void +_mesa_get_program_binary_length(struct gl_context *ctx, + struct gl_shader_program *sh_prog, + GLint *length) +{ + struct blob blob; + blob_init_fixed(&blob, NULL, SIZE_MAX); + write_program_payload(ctx, &blob, sh_prog); + *length = get_program_binary_header_size() + blob.size; + blob_finish(&blob); +} + +void +_mesa_get_program_binary(struct gl_context *ctx, + struct gl_shader_program *sh_prog, + GLsizei buf_size, GLsizei *length, + GLenum *binary_format, GLvoid *binary) +{ + struct blob blob; + uint8_t driver_sha1[20]; + unsigned header_size = get_program_binary_header_size(); + + ctx->Driver.GetProgramBinaryDriverSHA1(ctx, driver_sha1); + + blob_init(&blob); + + if (buf_size < header_size) + goto fail; + + write_program_payload(ctx, &blob, sh_prog); + if (blob.size + header_size > buf_size || + blob.out_of_memory) + goto fail; + + bool written = write_program_binary(blob.data, blob.size, driver_sha1, + binary, buf_size, binary_format); + if (!written || blob.out_of_memory) + goto fail; + + *length = header_size + blob.size; + + blob_finish(&blob); + return; + +fail: + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramBinary(buffer too small)"); + *length = 0; + blob_finish(&blob); +} + +void +_mesa_program_binary(struct gl_context *ctx, struct gl_shader_program *sh_prog, + GLenum binary_format, const GLvoid *binary, + GLsizei length) +{ + uint8_t driver_sha1[20]; + unsigned header_size = get_program_binary_header_size(); + + ctx->Driver.GetProgramBinaryDriverSHA1(ctx, driver_sha1); + + const void *payload = get_program_binary_payload(binary_format, driver_sha1, + binary, length); + + if (payload == NULL) { + sh_prog->data->LinkStatus = LINKING_FAILURE; + return; + } + + struct blob_reader blob; + blob_reader_init(&blob, payload, length - header_size); + + unsigned programs_in_use = 0; + if (ctx->_Shader) + for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { + if (ctx->_Shader->CurrentProgram[stage] && + ctx->_Shader->CurrentProgram[stage]->Id == sh_prog->Name) { + programs_in_use |= 1 << stage; + } + } + + if (!read_program_payload(ctx, &blob, binary_format, sh_prog)) { + sh_prog->data->LinkStatus = LINKING_FAILURE; + return; + } + + /* From section 7.3 (Program Objects) of the OpenGL 4.5 spec: + * + * "If LinkProgram or ProgramBinary successfully re-links a program + * object that is active for any shader stage, then the newly generated + * executable code will be installed as part of the current rendering + * state for all shader stages where the program is active. + * Additionally, the newly generated executable code is made part of + * the state of any program pipeline for all stages where the program + * is attached." + */ + while (programs_in_use) { + const int stage = u_bit_scan(&programs_in_use); + + struct gl_program *prog = NULL; + if (sh_prog->_LinkedShaders[stage]) + prog = sh_prog->_LinkedShaders[stage]->Program; + + _mesa_use_program(ctx, stage, sh_prog, prog, ctx->_Shader); + } + + sh_prog->data->LinkStatus = LINKING_SKIPPED; +} diff --git a/lib/mesa/src/mesa/main/program_binary.h b/lib/mesa/src/mesa/main/program_binary.h new file mode 100644 index 000000000..9e16b9ec5 --- /dev/null +++ b/lib/mesa/src/mesa/main/program_binary.h @@ -0,0 +1,56 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2004-2007 Brian Paul All Rights Reserved. + * Copyright (C) 2010 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef PROGRAM_BINARY_H +#define PROGRAM_BINARY_H + +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void +_mesa_get_program_binary_length(struct gl_context *ctx, + struct gl_shader_program *sh_prog, + GLint *length); + +void +_mesa_get_program_binary(struct gl_context *ctx, + struct gl_shader_program *sh_prog, + GLsizei buf_size, GLsizei *length, + GLenum *binary_format, GLvoid *binary); + +void +_mesa_program_binary(struct gl_context *ctx, struct gl_shader_program *sh_prog, + GLenum binary_format, const GLvoid *binary, + GLsizei length); + +#ifdef __cplusplus +} +#endif + +#endif /* PROGRAM_BINARY_H */ diff --git a/lib/mesa/src/mesa/main/querymatrix.c b/lib/mesa/src/mesa/main/querymatrix.c index 18361c929..b80bae6a6 100644 --- a/lib/mesa/src/mesa/main/querymatrix.c +++ b/lib/mesa/src/mesa/main/querymatrix.c @@ -17,6 +17,7 @@ #include "glheader.h" #include "querymatrix.h" #include "main/get.h" +#include "util/macros.h" /** diff --git a/lib/mesa/src/mesa/main/querymatrix.h b/lib/mesa/src/mesa/main/querymatrix.h index e08d843a9..649218910 100644 --- a/lib/mesa/src/mesa/main/querymatrix.h +++ b/lib/mesa/src/mesa/main/querymatrix.h @@ -25,7 +25,7 @@ #define QUERYMATRIX_H -#include "mtypes.h" +#include "glheader.h" /* diff --git a/lib/mesa/src/mesa/main/remap.c b/lib/mesa/src/mesa/main/remap.c index 6dc4235cb..fa412c0c4 100644 --- a/lib/mesa/src/mesa/main/remap.c +++ b/lib/mesa/src/mesa/main/remap.c @@ -44,6 +44,7 @@ #define need_MESA_remap_table #include "main/remap_helper.h" +#include "errors.h" /* this is global for quick access */ diff --git a/lib/mesa/src/mesa/main/tests/meson.build b/lib/mesa/src/mesa/main/tests/meson.build new file mode 100644 index 000000000..d1bd81a56 --- /dev/null +++ b/lib/mesa/src/mesa/main/tests/meson.build @@ -0,0 +1,45 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +files_main_test = files('enum_strings.cpp') +link_main_test = [] + +if with_shared_glapi + files_main_test += files( + 'dispatch_sanity.cpp', + 'mesa_formats.cpp', + 'mesa_extensions.cpp', + 'program_state_string.cpp', + ) + link_main_test += libglapi +else + files_main_test += files('stubs.cpp') +endif + +test( + 'main-test', + executable( + 'main_test', + [files_main_test, main_dispatch_h], + include_directories : [inc_include, inc_src, inc_mapi, inc_mesa], + dependencies : [idep_gtest, dep_clock, dep_dl, dep_thread], + link_with : [libmesa_classic, link_main_test], + ) +) diff --git a/lib/mesa/src/mesa/main/tests/program_state_string.cpp b/lib/mesa/src/mesa/main/tests/program_state_string.cpp index ddfdb49ee..38805f92c 100644 --- a/lib/mesa/src/mesa/main/tests/program_state_string.cpp +++ b/lib/mesa/src/mesa/main/tests/program_state_string.cpp @@ -25,13 +25,12 @@ #include "GL/gl.h" #include "GL/glext.h" -#include "main/compiler.h" #include "program/prog_statevars.h" TEST(program_state_string, depth_range) { - const gl_state_index state[STATE_LENGTH] = { + const gl_state_index16 state[STATE_LENGTH] = { STATE_DEPTH_RANGE }; diff --git a/lib/mesa/src/mesa/main/texcompress_astc.cpp b/lib/mesa/src/mesa/main/texcompress_astc.cpp new file mode 100644 index 000000000..23540c470 --- /dev/null +++ b/lib/mesa/src/mesa/main/texcompress_astc.cpp @@ -0,0 +1,1871 @@ +/* + * Copyright 2015 Philip Taylor <philip@zaynar.co.uk> + * Copyright 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file texcompress_astc.c + * + * Decompression code for GL_KHR_texture_compression_astc_ldr, which is just + * ASTC 2D LDR. + * + * The ASTC 2D LDR decoder (without the sRGB part) was copied from the OASTC + * library written by Philip Taylor. I added sRGB support and adjusted it for + * Mesa. - Marek + */ + +#include "texcompress_astc.h" +#include "macros.h" +#include "util/half_float.h" +#include <stdio.h> + +static bool VERBOSE_DECODE = false; +static bool VERBOSE_WRITE = false; + +static inline uint8_t +uint16_div_64k_to_half_to_unorm8(uint16_t v) +{ + return _mesa_half_to_unorm8(_mesa_uint16_div_64k_to_half(v)); +} + +class decode_error +{ +public: + enum type { + ok, + unsupported_hdr_void_extent, + reserved_block_mode_1, + reserved_block_mode_2, + dual_plane_and_too_many_partitions, + invalid_range_in_void_extent, + weight_grid_exceeds_block_size, + invalid_colour_endpoints_size, + invalid_colour_endpoints_count, + invalid_weight_bits, + invalid_num_weights, + }; +}; + + +struct cem_range { + uint8_t max; + uint8_t t, q, b; +}; + +/* Based on the Color Unquantization Parameters table, + * plus the bit-only representations, sorted by increasing size + */ +static cem_range cem_ranges[] = { + { 5, 1, 0, 1 }, + { 7, 0, 0, 3 }, + { 9, 0, 1, 1 }, + { 11, 1, 0, 2 }, + { 15, 0, 0, 4 }, + { 19, 0, 1, 2 }, + { 23, 1, 0, 3 }, + { 31, 0, 0, 5 }, + { 39, 0, 1, 3 }, + { 47, 1, 0, 4 }, + { 63, 0, 0, 6 }, + { 79, 0, 1, 4 }, + { 95, 1, 0, 5 }, + { 127, 0, 0, 7 }, + { 159, 0, 1, 5 }, + { 191, 1, 0, 6 }, + { 255, 0, 0, 8 }, +}; + +#define CAT_BITS_2(a, b) ( ((a) << 1) | (b) ) +#define CAT_BITS_3(a, b, c) ( ((a) << 2) | ((b) << 1) | (c) ) +#define CAT_BITS_4(a, b, c, d) ( ((a) << 3) | ((b) << 2) | ((c) << 1) | (d) ) +#define CAT_BITS_5(a, b, c, d, e) ( ((a) << 4) | ((b) << 3) | ((c) << 2) | ((d) << 1) | (e) ) + +/** + * Unpack 5n+8 bits from 'in' into 5 output values. + * If n <= 4 then T should be uint32_t, else it must be uint64_t. + */ +template <typename T> +static void unpack_trit_block(int n, T in, uint8_t *out) +{ + assert(n <= 6); /* else output will overflow uint8_t */ + + uint8_t T0 = (in >> (n)) & 0x1; + uint8_t T1 = (in >> (n+1)) & 0x1; + uint8_t T2 = (in >> (2*n+2)) & 0x1; + uint8_t T3 = (in >> (2*n+3)) & 0x1; + uint8_t T4 = (in >> (3*n+4)) & 0x1; + uint8_t T5 = (in >> (4*n+5)) & 0x1; + uint8_t T6 = (in >> (4*n+6)) & 0x1; + uint8_t T7 = (in >> (5*n+7)) & 0x1; + uint8_t mmask = (1 << n) - 1; + uint8_t m0 = (in >> (0)) & mmask; + uint8_t m1 = (in >> (n+2)) & mmask; + uint8_t m2 = (in >> (2*n+4)) & mmask; + uint8_t m3 = (in >> (3*n+5)) & mmask; + uint8_t m4 = (in >> (4*n+7)) & mmask; + + uint8_t C; + uint8_t t4, t3, t2, t1, t0; + if (CAT_BITS_3(T4, T3, T2) == 0x7) { + C = CAT_BITS_5(T7, T6, T5, T1, T0); + t4 = t3 = 2; + } else { + C = CAT_BITS_5(T4, T3, T2, T1, T0); + if (CAT_BITS_2(T6, T5) == 0x3) { + t4 = 2; + t3 = T7; + } else { + t4 = T7; + t3 = CAT_BITS_2(T6, T5); + } + } + + if ((C & 0x3) == 0x3) { + t2 = 2; + t1 = (C >> 4) & 0x1; + uint8_t C3 = (C >> 3) & 0x1; + uint8_t C2 = (C >> 2) & 0x1; + t0 = (C3 << 1) | (C2 & ~C3); + } else if (((C >> 2) & 0x3) == 0x3) { + t2 = 2; + t1 = 2; + t0 = C & 0x3; + } else { + t2 = (C >> 4) & 0x1; + t1 = (C >> 2) & 0x3; + uint8_t C1 = (C >> 1) & 0x1; + uint8_t C0 = (C >> 0) & 0x1; + t0 = (C1 << 1) | (C0 & ~C1); + } + + out[0] = (t0 << n) | m0; + out[1] = (t1 << n) | m1; + out[2] = (t2 << n) | m2; + out[3] = (t3 << n) | m3; + out[4] = (t4 << n) | m4; +} + +/** + * Unpack 3n+7 bits from 'in' into 3 output values + */ +static void unpack_quint_block(int n, uint32_t in, uint8_t *out) +{ + assert(n <= 5); /* else output will overflow uint8_t */ + + uint8_t Q0 = (in >> (n)) & 0x1; + uint8_t Q1 = (in >> (n+1)) & 0x1; + uint8_t Q2 = (in >> (n+2)) & 0x1; + uint8_t Q3 = (in >> (2*n+3)) & 0x1; + uint8_t Q4 = (in >> (2*n+4)) & 0x1; + uint8_t Q5 = (in >> (3*n+5)) & 0x1; + uint8_t Q6 = (in >> (3*n+6)) & 0x1; + uint8_t mmask = (1 << n) - 1; + uint8_t m0 = (in >> (0)) & mmask; + uint8_t m1 = (in >> (n+3)) & mmask; + uint8_t m2 = (in >> (2*n+5)) & mmask; + + uint8_t C; + uint8_t q2, q1, q0; + if (CAT_BITS_4(Q6, Q5, Q2, Q1) == 0x3) { + q2 = CAT_BITS_3(Q0, Q4 & ~Q0, Q3 & ~Q0); + q1 = 4; + q0 = 4; + } else { + if (CAT_BITS_2(Q2, Q1) == 0x3) { + q2 = 4; + C = CAT_BITS_5(Q4, Q3, 0x1 & ~Q6, 0x1 & ~Q5, Q0); + } else { + q2 = CAT_BITS_2(Q6, Q5); + C = CAT_BITS_5(Q4, Q3, Q2, Q1, Q0); + } + if ((C & 0x7) == 0x5) { + q1 = 4; + q0 = (C >> 3) & 0x3; + } else { + q1 = (C >> 3) & 0x3; + q0 = C & 0x7; + } + } + out[0] = (q0 << n) | m0; + out[1] = (q1 << n) | m1; + out[2] = (q2 << n) | m2; +} + + +struct uint8x4_t +{ + uint8_t v[4]; + + uint8x4_t() { } + + uint8x4_t(int a, int b, int c, int d) + { + assert(0 <= a && a <= 255); + assert(0 <= b && b <= 255); + assert(0 <= c && c <= 255); + assert(0 <= d && d <= 255); + v[0] = a; + v[1] = b; + v[2] = c; + v[3] = d; + } + + static uint8x4_t clamped(int a, int b, int c, int d) + { + uint8x4_t r; + r.v[0] = MAX2(0, MIN2(255, a)); + r.v[1] = MAX2(0, MIN2(255, b)); + r.v[2] = MAX2(0, MIN2(255, c)); + r.v[3] = MAX2(0, MIN2(255, d)); + return r; + } +}; + +static uint8x4_t blue_contract(int r, int g, int b, int a) +{ + return uint8x4_t((r+b) >> 1, (g+b) >> 1, b, a); +} + +static uint8x4_t blue_contract_clamped(int r, int g, int b, int a) +{ + return uint8x4_t::clamped((r+b) >> 1, (g+b) >> 1, b, a); +} + +static void bit_transfer_signed(int &a, int &b) +{ + b >>= 1; + b |= a & 0x80; + a >>= 1; + a &= 0x3f; + if (a & 0x20) + a -= 0x40; +} + +static uint32_t hash52(uint32_t p) +{ + p ^= p >> 15; + p -= p << 17; + p += p << 7; + p += p << 4; + p ^= p >> 5; + p += p << 16; + p ^= p >> 7; + p ^= p >> 3; + p ^= p << 6; + p ^= p >> 17; + return p; +} + +static int select_partition(int seed, int x, int y, int z, int partitioncount, + int small_block) +{ + if (small_block) { + x <<= 1; + y <<= 1; + z <<= 1; + } + seed += (partitioncount - 1) * 1024; + uint32_t rnum = hash52(seed); + uint8_t seed1 = rnum & 0xF; + uint8_t seed2 = (rnum >> 4) & 0xF; + uint8_t seed3 = (rnum >> 8) & 0xF; + uint8_t seed4 = (rnum >> 12) & 0xF; + uint8_t seed5 = (rnum >> 16) & 0xF; + uint8_t seed6 = (rnum >> 20) & 0xF; + uint8_t seed7 = (rnum >> 24) & 0xF; + uint8_t seed8 = (rnum >> 28) & 0xF; + uint8_t seed9 = (rnum >> 18) & 0xF; + uint8_t seed10 = (rnum >> 22) & 0xF; + uint8_t seed11 = (rnum >> 26) & 0xF; + uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF; + + seed1 *= seed1; + seed2 *= seed2; + seed3 *= seed3; + seed4 *= seed4; + seed5 *= seed5; + seed6 *= seed6; + seed7 *= seed7; + seed8 *= seed8; + seed9 *= seed9; + seed10 *= seed10; + seed11 *= seed11; + seed12 *= seed12; + + int sh1, sh2, sh3; + if (seed & 1) { + sh1 = (seed & 2 ? 4 : 5); + sh2 = (partitioncount == 3 ? 6 : 5); + } else { + sh1 = (partitioncount == 3 ? 6 : 5); + sh2 = (seed & 2 ? 4 : 5); + } + sh3 = (seed & 0x10) ? sh1 : sh2; + + seed1 >>= sh1; + seed2 >>= sh2; + seed3 >>= sh1; + seed4 >>= sh2; + seed5 >>= sh1; + seed6 >>= sh2; + seed7 >>= sh1; + seed8 >>= sh2; + seed9 >>= sh3; + seed10 >>= sh3; + seed11 >>= sh3; + seed12 >>= sh3; + + int a = seed1 * x + seed2 * y + seed11 * z + (rnum >> 14); + int b = seed3 * x + seed4 * y + seed12 * z + (rnum >> 10); + int c = seed5 * x + seed6 * y + seed9 * z + (rnum >> 6); + int d = seed7 * x + seed8 * y + seed10 * z + (rnum >> 2); + + a &= 0x3F; + b &= 0x3F; + c &= 0x3F; + d &= 0x3F; + + if (partitioncount < 4) + d = 0; + if (partitioncount < 3) + c = 0; + + if (a >= b && a >= c && a >= d) + return 0; + else if (b >= c && b >= d) + return 1; + else if (c >= d) + return 2; + else + return 3; +} + + +struct InputBitVector +{ + uint32_t data[4]; + + void printf_bits(int offset, int count, const char *fmt = "", ...) + { + char out[129]; + memset(out, '.', 128); + out[128] = '\0'; + int idx = offset; + for (int i = 0; i < count; ++i) { + out[127 - idx] = ((data[idx >> 5] >> (idx & 31)) & 1) ? '1' : '0'; + ++idx; + } + printf("%s ", out); + va_list ap; + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("\n"); + } + + uint32_t get_bits(int offset, int count) + { + assert(count >= 0 && count < 32); + + uint32_t out = 0; + if (offset < 32) + out |= data[0] >> offset; + + if (0 < offset && offset <= 32) + out |= data[1] << (32 - offset); + if (32 < offset && offset < 64) + out |= data[1] >> (offset - 32); + + if (32 < offset && offset <= 64) + out |= data[2] << (64 - offset); + if (64 < offset && offset < 96) + out |= data[2] >> (offset - 64); + + if (64 < offset && offset <= 96) + out |= data[3] << (96 - offset); + if (96 < offset && offset < 128) + out |= data[3] >> (offset - 96); + + out &= (1 << count) - 1; + return out; + } + + uint64_t get_bits64(int offset, int count) + { + assert(count >= 0 && count < 64); + + uint64_t out = 0; + if (offset < 32) + out |= data[0] >> offset; + + if (offset <= 32) + out |= (uint64_t)data[1] << (32 - offset); + if (32 < offset && offset < 64) + out |= data[1] >> (offset - 32); + + if (0 < offset && offset <= 64) + out |= (uint64_t)data[2] << (64 - offset); + if (64 < offset && offset < 96) + out |= data[2] >> (offset - 64); + + if (32 < offset && offset <= 96) + out |= (uint64_t)data[3] << (96 - offset); + if (96 < offset && offset < 128) + out |= data[3] >> (offset - 96); + + out &= ((uint64_t)1 << count) - 1; + return out; + } + + uint32_t get_bits_rev(int offset, int count) + { + assert(offset >= count); + uint32_t tmp = get_bits(offset - count, count); + uint32_t out = 0; + for (int i = 0; i < count; ++i) + out |= ((tmp >> i) & 1) << (count - 1 - i); + return out; + } +}; + +struct OutputBitVector +{ + uint32_t data[4]; + int offset; + + OutputBitVector() + : offset(0) + { + memset(data, 0, sizeof(data)); + } + + void append(uint32_t value, int size) + { + if (VERBOSE_WRITE) + printf("append offset=%d size=%d values=0x%x\n", offset, size, value); + + assert(offset + size <= 128); + + assert(size <= 32); + if (size < 32) + assert((value >> size) == 0); + + while (size) { + int c = MIN2(size, 32 - (offset & 31)); + data[offset >> 5] |= (value << (offset & 31)); + offset += c; + size -= c; + value >>= c; + } + } + + void append64(uint64_t value, int size) + { + if (VERBOSE_WRITE) + printf("append offset=%d size=%d values=0x%llx\n", offset, size, (unsigned long long)value); + + assert(offset + size <= 128); + + assert(size <= 64); + if (size < 64) + assert((value >> size) == 0); + + while (size) { + int c = MIN2(size, 32 - (offset & 31)); + data[offset >> 5] |= (value << (offset & 31)); + offset += c; + size -= c; + value >>= c; + } + } + + void append(OutputBitVector &v, int size) + { + if (VERBOSE_WRITE) + printf("append vector offset=%d size=%d\n", offset, size); + + assert(offset + size <= 128); + int i = 0; + while (size >= 32) { + append(v.data[i++], 32); + size -= 32; + } + if (size > 0) + append(v.data[i] & ((1 << size) - 1), size); + } + + void append_end(OutputBitVector &v, int size) + { + for (int i = 0; i < size; ++i) + data[(127 - i) >> 5] |= ((v.data[i >> 5] >> (i & 31)) & 1) << ((127 - i) & 31); + } + + /* Insert the given number of '1' bits. (We could use 0s instead, but 1s are + * more likely to flush out bugs where we accidentally read undefined bits.) + */ + void skip(int size) + { + if (VERBOSE_WRITE) + printf("skip offset=%d size=%d\n", offset, size); + + assert(offset + size <= 128); + while (size >= 32) { + append(0xffffffff, 32); + size -= 32; + } + if (size > 0) + append(0xffffffff >> (32 - size), size); + } +}; + + +class Decoder +{ +public: + Decoder(int block_w, int block_h, int block_d, bool srgb, bool output_unorm8) + : block_w(block_w), block_h(block_h), block_d(block_d), srgb(srgb), + output_unorm8(output_unorm8) {} + + decode_error::type decode(const uint8_t *in, uint16_t *output) const; + + int block_w, block_h, block_d; + bool srgb, output_unorm8; +}; + +struct Block +{ + bool is_error; + bool bogus_colour_endpoints; + bool bogus_weights; + + int high_prec; + int dual_plane; + int colour_component_selector; + int wt_range; + int wt_w, wt_h, wt_d; + int num_parts; + int partition_index; + + bool is_void_extent; + int void_extent_d; + int void_extent_min_s; + int void_extent_max_s; + int void_extent_min_t; + int void_extent_max_t; + uint16_t void_extent_colour_r; + uint16_t void_extent_colour_g; + uint16_t void_extent_colour_b; + uint16_t void_extent_colour_a; + + bool is_multi_cem; + int num_extra_cem_bits; + int colour_endpoint_data_offset; + int extra_cem_bits; + int cem_base_class; + int cems[4]; + + int num_cem_values; + + /* Calculated by unpack_weights(): */ + uint8_t weights_quant[64 + 4]; /* max 64 values, plus padding for overflows in trit parsing */ + + /* Calculated by unquantise_weights(): */ + uint8_t weights[64 + 18]; /* max 64 values, plus padding for the infill interpolation */ + + /* Calculated by unpack_colour_endpoints(): */ + uint8_t colour_endpoints_quant[18 + 4]; /* max 18 values, plus padding for overflows in trit parsing */ + + /* Calculated by unquantise_colour_endpoints(): */ + uint8_t colour_endpoints[18]; + + /* Calculated by calculate_from_weights(): */ + int wt_trits; + int wt_quints; + int wt_bits; + int wt_max; + int num_weights; + int weight_bits; + + /* Calculated by calculate_remaining_bits(): */ + int remaining_bits; + + /* Calculated by calculate_colour_endpoints_size(): */ + int colour_endpoint_bits; + int ce_max; + int ce_trits; + int ce_quints; + int ce_bits; + + /* Calculated by compute_infill_weights(); */ + uint8_t infill_weights[2][216]; /* large enough for 6x6x6 */ + + /* Calculated by decode_colour_endpoints(); */ + uint8x4_t endpoints_decoded[2][4]; + + void calculate_from_weights(); + void calculate_remaining_bits(); + decode_error::type calculate_colour_endpoints_size(); + + void unquantise_weights(); + void unquantise_colour_endpoints(); + + decode_error::type decode(const Decoder &decoder, InputBitVector in); + + decode_error::type decode_block_mode(InputBitVector in); + decode_error::type decode_void_extent(InputBitVector in); + void decode_cem(InputBitVector in); + void unpack_colour_endpoints(InputBitVector in); + void decode_colour_endpoints(); + void unpack_weights(InputBitVector in); + void compute_infill_weights(int block_w, int block_h, int block_d); + + void write_decoded(const Decoder &decoder, uint16_t *output); +}; + + +decode_error::type Decoder::decode(const uint8_t *in, uint16_t *output) const +{ + Block blk; + InputBitVector in_vec; + memcpy(&in_vec.data, in, 16); + decode_error::type err = blk.decode(*this, in_vec); + if (err == decode_error::ok) { + blk.write_decoded(*this, output); + } else { + /* Fill output with the error colour */ + for (int i = 0; i < block_w * block_h * block_d; ++i) { + if (output_unorm8) { + output[i*4+0] = 0xff; + output[i*4+1] = 0; + output[i*4+2] = 0xff; + output[i*4+3] = 0xff; + } else { + assert(!srgb); /* srgb must use unorm8 */ + + output[i*4+0] = FP16_ONE; + output[i*4+1] = FP16_ZERO; + output[i*4+2] = FP16_ONE; + output[i*4+3] = FP16_ONE; + } + } + } + return err; +} + + +decode_error::type Block::decode_void_extent(InputBitVector block) +{ + /* TODO: 3D */ + + is_void_extent = true; + void_extent_d = block.get_bits(9, 1); + void_extent_min_s = block.get_bits(12, 13); + void_extent_max_s = block.get_bits(25, 13); + void_extent_min_t = block.get_bits(38, 13); + void_extent_max_t = block.get_bits(51, 13); + void_extent_colour_r = block.get_bits(64, 16); + void_extent_colour_g = block.get_bits(80, 16); + void_extent_colour_b = block.get_bits(96, 16); + void_extent_colour_a = block.get_bits(112, 16); + + /* TODO: maybe we should do something useful with the extent coordinates? */ + + if (void_extent_d) { + return decode_error::unsupported_hdr_void_extent; + } + + if (void_extent_min_s == 0x1fff && void_extent_max_s == 0x1fff + && void_extent_min_t == 0x1fff && void_extent_max_t == 0x1fff) { + + /* No extents */ + + } else { + + /* Check for illegal encoding */ + if (void_extent_min_s >= void_extent_max_s || void_extent_min_t >= void_extent_max_t) { + return decode_error::invalid_range_in_void_extent; + } + } + + return decode_error::ok; +} + +decode_error::type Block::decode_block_mode(InputBitVector in) +{ + dual_plane = in.get_bits(10, 1); + high_prec = in.get_bits(9, 1); + + if (in.get_bits(0, 2) != 0x0) { + wt_range = (in.get_bits(0, 2) << 1) | in.get_bits(4, 1); + int a = in.get_bits(5, 2); + int b = in.get_bits(7, 2); + switch (in.get_bits(2, 2)) { + case 0x0: + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "DHBBAAR00RR"); + wt_w = b + 4; + wt_h = a + 2; + break; + case 0x1: + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "DHBBAAR01RR"); + wt_w = b + 8; + wt_h = a + 2; + break; + case 0x2: + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "DHBBAAR10RR"); + wt_w = a + 2; + wt_h = b + 8; + break; + case 0x3: + if ((b & 0x2) == 0) { + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "DH0BAAR11RR"); + wt_w = a + 2; + wt_h = b + 6; + } else { + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "DH1BAAR11RR"); + wt_w = (b & 0x1) + 2; + wt_h = a + 2; + } + break; + } + } else { + if (in.get_bits(6, 3) == 0x7) { + if (in.get_bits(0, 9) == 0x1fc) { + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "xx111111100 (void extent)"); + return decode_void_extent(in); + } else { + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "xx111xxxx00"); + return decode_error::reserved_block_mode_1; + } + } + if (in.get_bits(0, 4) == 0x0) { + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "xxxxxxx0000"); + return decode_error::reserved_block_mode_2; + } + + wt_range = in.get_bits(1, 3) | in.get_bits(4, 1); + int a = in.get_bits(5, 2); + int b; + + switch (in.get_bits(7, 2)) { + case 0x0: + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "DH00AARRR00"); + wt_w = 12; + wt_h = a + 2; + break; + case 0x1: + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "DH01AARRR00"); + wt_w = a + 2; + wt_h = 12; + break; + case 0x3: + if (in.get_bits(5, 1) == 0) { + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "DH1100RRR00"); + wt_w = 6; + wt_h = 10; + } else { + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "DH1101RRR00"); + wt_w = 10; + wt_h = 6; + } + break; + case 0x2: + if (VERBOSE_DECODE) + in.printf_bits(0, 11, "BB10AARRR00"); + b = in.get_bits(9, 2); + wt_w = a + 6; + wt_h = b + 6; + dual_plane = 0; + high_prec = 0; + break; + } + } + return decode_error::ok; +} + +void Block::decode_cem(InputBitVector in) +{ + cems[0] = cems[1] = cems[2] = cems[3] = -1; + + num_extra_cem_bits = 0; + extra_cem_bits = 0; + + if (num_parts > 1) { + + partition_index = in.get_bits(13, 10); + if (VERBOSE_DECODE) + in.printf_bits(13, 10, "partition ID (%d)", partition_index); + + uint32_t cem = in.get_bits(23, 6); + + if ((cem & 0x3) == 0x0) { + cem >>= 2; + cem_base_class = cem >> 2; + is_multi_cem = false; + + for (int i = 0; i < num_parts; ++i) + cems[i] = cem; + + if (VERBOSE_DECODE) + in.printf_bits(23, 6, "CEM (single, %d)", cem); + } else { + + cem_base_class = (cem & 0x3) - 1; + is_multi_cem = true; + + if (VERBOSE_DECODE) + in.printf_bits(23, 6, "CEM (multi, base class %d)", cem_base_class); + + int offset = 128 - weight_bits; + + if (num_parts == 2) { + if (VERBOSE_DECODE) { + in.printf_bits(25, 4, "M0M0 C1 C0"); + in.printf_bits(offset - 2, 2, "M1M1"); + } + + uint32_t c0 = in.get_bits(25, 1); + uint32_t c1 = in.get_bits(26, 1); + + extra_cem_bits = c0 + c1; + + num_extra_cem_bits = 2; + + uint32_t m0 = in.get_bits(27, 2); + uint32_t m1 = in.get_bits(offset - 2, 2); + + cems[0] = ((cem_base_class + c0) << 2) | m0; + cems[1] = ((cem_base_class + c1) << 2) | m1; + + } else if (num_parts == 3) { + if (VERBOSE_DECODE) { + in.printf_bits(25, 4, "M0 C2 C1 C0"); + in.printf_bits(offset - 5, 5, "M2M2 M1M1 M0"); + } + + uint32_t c0 = in.get_bits(25, 1); + uint32_t c1 = in.get_bits(26, 1); + uint32_t c2 = in.get_bits(27, 1); + + extra_cem_bits = c0 + c1 + c2; + + num_extra_cem_bits = 5; + + uint32_t m0 = in.get_bits(28, 1) | (in.get_bits(128 - weight_bits - 5, 1) << 1); + uint32_t m1 = in.get_bits(offset - 4, 2); + uint32_t m2 = in.get_bits(offset - 2, 2); + + cems[0] = ((cem_base_class + c0) << 2) | m0; + cems[1] = ((cem_base_class + c1) << 2) | m1; + cems[2] = ((cem_base_class + c2) << 2) | m2; + + } else if (num_parts == 4) { + if (VERBOSE_DECODE) { + in.printf_bits(25, 4, "C3 C2 C1 C0"); + in.printf_bits(offset - 8, 8, "M3M3 M2M2 M1M1 M0M0"); + } + + uint32_t c0 = in.get_bits(25, 1); + uint32_t c1 = in.get_bits(26, 1); + uint32_t c2 = in.get_bits(27, 1); + uint32_t c3 = in.get_bits(28, 1); + + extra_cem_bits = c0 + c1 + c2 + c3; + + num_extra_cem_bits = 8; + + uint32_t m0 = in.get_bits(offset - 8, 2); + uint32_t m1 = in.get_bits(offset - 6, 2); + uint32_t m2 = in.get_bits(offset - 4, 2); + uint32_t m3 = in.get_bits(offset - 2, 2); + + cems[0] = ((cem_base_class + c0) << 2) | m0; + cems[1] = ((cem_base_class + c1) << 2) | m1; + cems[2] = ((cem_base_class + c2) << 2) | m2; + cems[3] = ((cem_base_class + c3) << 2) | m3; + } else { + unreachable(""); + } + } + + colour_endpoint_data_offset = 29; + + } else { + uint32_t cem = in.get_bits(13, 4); + + cem_base_class = cem >> 2; + is_multi_cem = false; + + cems[0] = cem; + + partition_index = -1; + + if (VERBOSE_DECODE) + in.printf_bits(13, 4, "CEM = %d (class %d)", cem, cem_base_class); + + colour_endpoint_data_offset = 17; + } +} + +void Block::unpack_colour_endpoints(InputBitVector in) +{ + if (ce_trits) { + int offset = colour_endpoint_data_offset; + int bits_left = colour_endpoint_bits; + for (int i = 0; i < num_cem_values; i += 5) { + int bits_to_read = MIN2(bits_left, 8 + ce_bits * 5); + /* If ce_trits then ce_bits <= 6, so bits_to_read <= 38 and we have to use uint64_t */ + uint64_t raw = in.get_bits64(offset, bits_to_read); + unpack_trit_block(ce_bits, raw, &colour_endpoints_quant[i]); + + if (VERBOSE_DECODE) + in.printf_bits(offset, bits_to_read, + "trits [%d,%d,%d,%d,%d]", + colour_endpoints_quant[i+0], colour_endpoints_quant[i+1], + colour_endpoints_quant[i+2], colour_endpoints_quant[i+3], + colour_endpoints_quant[i+4]); + + offset += 8 + ce_bits * 5; + bits_left -= 8 + ce_bits * 5; + } + } else if (ce_quints) { + int offset = colour_endpoint_data_offset; + int bits_left = colour_endpoint_bits; + for (int i = 0; i < num_cem_values; i += 3) { + int bits_to_read = MIN2(bits_left, 7 + ce_bits * 3); + /* If ce_quints then ce_bits <= 5, so bits_to_read <= 22 and we can use uint32_t */ + uint32_t raw = in.get_bits(offset, bits_to_read); + unpack_quint_block(ce_bits, raw, &colour_endpoints_quant[i]); + + if (VERBOSE_DECODE) + in.printf_bits(offset, bits_to_read, + "quints [%d,%d,%d]", + colour_endpoints_quant[i], colour_endpoints_quant[i+1], colour_endpoints_quant[i+2]); + + offset += 7 + ce_bits * 3; + bits_left -= 7 + ce_bits * 3; + } + } else { + assert((colour_endpoint_bits % ce_bits) == 0); + int offset = colour_endpoint_data_offset; + for (int i = 0; i < num_cem_values; i++) { + colour_endpoints_quant[i] = in.get_bits(offset, ce_bits); + + if (VERBOSE_DECODE) + in.printf_bits(offset, ce_bits, "bits [%d]", colour_endpoints_quant[i]); + + offset += ce_bits; + } + } +} + +void Block::decode_colour_endpoints() +{ + int cem_values_idx = 0; + for (int part = 0; part < num_parts; ++part) { + uint8_t *v = &colour_endpoints[cem_values_idx]; + int v0 = v[0]; + int v1 = v[1]; + int v2 = v[2]; + int v3 = v[3]; + int v4 = v[4]; + int v5 = v[5]; + int v6 = v[6]; + int v7 = v[7]; + cem_values_idx += ((cems[part] >> 2) + 1) * 2; + + uint8x4_t e0, e1; + int s0, s1, L0, L1; + + switch (cems[part]) + { + case 0: + e0 = uint8x4_t(v0, v0, v0, 0xff); + e1 = uint8x4_t(v1, v1, v1, 0xff); + break; + case 1: + L0 = (v0 >> 2) | (v1 & 0xc0); + L1 = L0 + (v1 & 0x3f); + if (L1 > 0xff) + L1 = 0xff; + e0 = uint8x4_t(L0, L0, L0, 0xff); + e1 = uint8x4_t(L1, L1, L1, 0xff); + break; + case 4: + e0 = uint8x4_t(v0, v0, v0, v2); + e1 = uint8x4_t(v1, v1, v1, v3); + break; + case 5: + bit_transfer_signed(v1, v0); + bit_transfer_signed(v3, v2); + e0 = uint8x4_t(v0, v0, v0, v2); + e1 = uint8x4_t::clamped(v0+v1, v0+v1, v0+v1, v2+v3); + break; + case 6: + e0 = uint8x4_t(v0*v3 >> 8, v1*v3 >> 8, v2*v3 >> 8, 0xff); + e1 = uint8x4_t(v0, v1, v2, 0xff); + break; + case 8: + s0 = v0 + v2 + v4; + s1 = v1 + v3 + v5; + if (s1 >= s0) { + e0 = uint8x4_t(v0, v2, v4, 0xff); + e1 = uint8x4_t(v1, v3, v5, 0xff); + } else { + e0 = blue_contract(v1, v3, v5, 0xff); + e1 = blue_contract(v0, v2, v4, 0xff); + } + break; + case 9: + bit_transfer_signed(v1, v0); + bit_transfer_signed(v3, v2); + bit_transfer_signed(v5, v4); + if (v1 + v3 + v5 >= 0) { + e0 = uint8x4_t(v0, v2, v4, 0xff); + e1 = uint8x4_t::clamped(v0+v1, v2+v3, v4+v5, 0xff); + } else { + e0 = blue_contract_clamped(v0+v1, v2+v3, v4+v5, 0xff); + e1 = blue_contract(v0, v2, v4, 0xff); + } + break; + case 10: + e0 = uint8x4_t(v0*v3 >> 8, v1*v3 >> 8, v2*v3 >> 8, v4); + e1 = uint8x4_t(v0, v1, v2, v5); + break; + case 12: + s0 = v0 + v2 + v4; + s1 = v1 + v3 + v5; + if (s1 >= s0) { + e0 = uint8x4_t(v0, v2, v4, v6); + e1 = uint8x4_t(v1, v3, v5, v7); + } else { + e0 = blue_contract(v1, v3, v5, v7); + e1 = blue_contract(v0, v2, v4, v6); + } + break; + case 13: + bit_transfer_signed(v1, v0); + bit_transfer_signed(v3, v2); + bit_transfer_signed(v5, v4); + bit_transfer_signed(v7, v6); + if (v1 + v3 + v5 >= 0) { + e0 = uint8x4_t(v0, v2, v4, v6); + e1 = uint8x4_t::clamped(v0+v1, v2+v3, v4+v5, v6+v7); + } else { + e0 = blue_contract_clamped(v0+v1, v2+v3, v4+v5, v6+v7); + e1 = blue_contract(v0, v2, v4, v6); + } + break; + default: + /* HDR endpoints not supported; return error colour */ + e0 = uint8x4_t(255, 0, 255, 255); + e1 = uint8x4_t(255, 0, 255, 255); + break; + } + + endpoints_decoded[0][part] = e0; + endpoints_decoded[1][part] = e1; + + if (VERBOSE_DECODE) { + printf("cems[%d]=%d v=[", part, cems[part]); + for (int i = 0; i < (cems[part] >> 2) + 1; ++i) { + if (i) + printf(", "); + printf("%3d", v[i]); + } + printf("] e0=[%3d,%4d,%4d,%4d] e1=[%3d,%4d,%4d,%4d]\n", + e0.v[0], e0.v[1], e0.v[2], e0.v[3], + e1.v[0], e1.v[1], e1.v[2], e1.v[3]); + } + } +} + +void Block::unpack_weights(InputBitVector in) +{ + if (wt_trits) { + int offset = 128; + int bits_left = weight_bits; + for (int i = 0; i < num_weights; i += 5) { + int bits_to_read = MIN2(bits_left, 8 + 5*wt_bits); + /* If wt_trits then wt_bits <= 3, so bits_to_read <= 23 and we can use uint32_t */ + uint32_t raw = in.get_bits_rev(offset, bits_to_read); + unpack_trit_block(wt_bits, raw, &weights_quant[i]); + + if (VERBOSE_DECODE) + in.printf_bits(offset - bits_to_read, bits_to_read, "weight trits [%d,%d,%d,%d,%d]", + weights_quant[i+0], weights_quant[i+1], + weights_quant[i+2], weights_quant[i+3], + weights_quant[i+4]); + + offset -= 8 + wt_bits * 5; + bits_left -= 8 + wt_bits * 5; + } + + } else if (wt_quints) { + + int offset = 128; + int bits_left = weight_bits; + for (int i = 0; i < num_weights; i += 3) { + int bits_to_read = MIN2(bits_left, 7 + 3*wt_bits); + /* If wt_quints then wt_bits <= 2, so bits_to_read <= 13 and we can use uint32_t */ + uint32_t raw = in.get_bits_rev(offset, bits_to_read); + unpack_quint_block(wt_bits, raw, &weights_quant[i]); + + if (VERBOSE_DECODE) + in.printf_bits(offset - bits_to_read, bits_to_read, "weight quints [%d,%d,%d]", + weights_quant[i], weights_quant[i+1], weights_quant[i+2]); + + offset -= 7 + wt_bits * 3; + bits_left -= 7 + wt_bits * 3; + } + + } else { + int offset = 128; + assert((weight_bits % wt_bits) == 0); + for (int i = 0; i < num_weights; ++i) { + weights_quant[i] = in.get_bits_rev(offset, wt_bits); + + if (VERBOSE_DECODE) + in.printf_bits(offset - wt_bits, wt_bits, "weight bits [%d]", weights_quant[i]); + + offset -= wt_bits; + } + } +} + +void Block::unquantise_weights() +{ + assert(num_weights <= (int)ARRAY_SIZE(weights_quant)); + assert(num_weights <= (int)ARRAY_SIZE(weights)); + + memset(weights, 0, sizeof(weights)); + + for (int i = 0; i < num_weights; ++i) { + + uint8_t v = weights_quant[i]; + uint8_t w; + + if (wt_trits) { + + if (wt_bits == 0) { + w = v * 32; + } else { + uint8_t A, B, C, D; + A = (v & 0x1) ? 0x7F : 0x00; + switch (wt_bits) { + case 1: + B = 0; + C = 50; + D = v >> 1; + break; + case 2: + B = (v & 0x2) ? 0x45 : 0x00; + C = 23; + D = v >> 2; + break; + case 3: + B = ((v & 0x6) >> 1) | ((v & 0x6) << 4); + C = 11; + D = v >> 3; + break; + default: + unreachable(""); + } + uint16_t T = D * C + B; + T = T ^ A; + T = (A & 0x20) | (T >> 2); + assert(T < 64); + if (T > 32) + T++; + w = T; + } + + } else if (wt_quints) { + + if (wt_bits == 0) { + w = v * 16; + } else { + uint8_t A, B, C, D; + A = (v & 0x1) ? 0x7F : 0x00; + switch (wt_bits) { + case 1: + B = 0; + C = 28; + D = v >> 1; + break; + case 2: + B = (v & 0x2) ? 0x42 : 0x00; + C = 13; + D = v >> 2; + break; + default: + unreachable(""); + } + uint16_t T = D * C + B; + T = T ^ A; + T = (A & 0x20) | (T >> 2); + assert(T < 64); + if (T > 32) + T++; + w = T; + } + weights[i] = w; + + } else { + + switch (wt_bits) { + case 1: w = v ? 0x3F : 0x00; break; + case 2: w = v | (v << 2) | (v << 4); break; + case 3: w = v | (v << 3); break; + case 4: w = (v >> 2) | (v << 2); break; + case 5: w = (v >> 4) | (v << 1); break; + default: unreachable(""); + } + assert(w < 64); + if (w > 32) + w++; + } + weights[i] = w; + } +} + +void Block::compute_infill_weights(int block_w, int block_h, int block_d) +{ + int Ds = block_w <= 1 ? 0 : (1024 + block_w / 2) / (block_w - 1); + int Dt = block_h <= 1 ? 0 : (1024 + block_h / 2) / (block_h - 1); + int Dr = block_d <= 1 ? 0 : (1024 + block_d / 2) / (block_d - 1); + for (int r = 0; r < block_d; ++r) { + for (int t = 0; t < block_h; ++t) { + for (int s = 0; s < block_w; ++s) { + int cs = Ds * s; + int ct = Dt * t; + int cr = Dr * r; + int gs = (cs * (wt_w - 1) + 32) >> 6; + int gt = (ct * (wt_h - 1) + 32) >> 6; + int gr = (cr * (wt_d - 1) + 32) >> 6; + assert(gs >= 0 && gs <= 176); + assert(gt >= 0 && gt <= 176); + assert(gr >= 0 && gr <= 176); + int js = gs >> 4; + int fs = gs & 0xf; + int jt = gt >> 4; + int ft = gt & 0xf; + int jr = gr >> 4; + int fr = gr & 0xf; + + /* TODO: 3D */ + (void)jr; + (void)fr; + + int w11 = (fs * ft + 8) >> 4; + int w10 = ft - w11; + int w01 = fs - w11; + int w00 = 16 - fs - ft + w11; + + if (dual_plane) { + int p00, p01, p10, p11, i0, i1; + int v0 = js + jt * wt_w; + p00 = weights[(v0) * 2]; + p01 = weights[(v0 + 1) * 2]; + p10 = weights[(v0 + wt_w) * 2]; + p11 = weights[(v0 + wt_w + 1) * 2]; + i0 = (p00*w00 + p01*w01 + p10*w10 + p11*w11 + 8) >> 4; + p00 = weights[(v0) * 2 + 1]; + p01 = weights[(v0 + 1) * 2 + 1]; + p10 = weights[(v0 + wt_w) * 2 + 1]; + p11 = weights[(v0 + wt_w + 1) * 2 + 1]; + assert((v0 + wt_w + 1) * 2 + 1 < (int)ARRAY_SIZE(weights)); + i1 = (p00*w00 + p01*w01 + p10*w10 + p11*w11 + 8) >> 4; + assert(0 <= i0 && i0 <= 64); + infill_weights[0][s + t*block_w + r*block_w*block_h] = i0; + infill_weights[1][s + t*block_w + r*block_w*block_h] = i1; + } else { + int p00, p01, p10, p11, i; + int v0 = js + jt * wt_w; + p00 = weights[v0]; + p01 = weights[v0 + 1]; + p10 = weights[v0 + wt_w]; + p11 = weights[v0 + wt_w + 1]; + assert(v0 + wt_w + 1 < (int)ARRAY_SIZE(weights)); + i = (p00*w00 + p01*w01 + p10*w10 + p11*w11 + 8) >> 4; + assert(0 <= i && i <= 64); + infill_weights[0][s + t*block_w + r*block_w*block_h] = i; + } + } + } + } +} + +void Block::unquantise_colour_endpoints() +{ + assert(num_cem_values <= (int)ARRAY_SIZE(colour_endpoints_quant)); + assert(num_cem_values <= (int)ARRAY_SIZE(colour_endpoints)); + + for (int i = 0; i < num_cem_values; ++i) { + uint8_t v = colour_endpoints_quant[i]; + + if (ce_trits) { + uint16_t A, B, C, D; + uint16_t t; + A = (v & 0x1) ? 0x1FF : 0x000; + switch (ce_bits) { + case 1: + B = 0; + C = 204; + D = v >> 1; + break; + case 2: + B = (v & 0x2) ? 0x116 : 0x000; + C = 93; + D = v >> 2; + break; + case 3: + t = ((v >> 1) & 0x3); + B = t | (t << 2) | (t << 7); + C = 44; + D = v >> 3; + break; + case 4: + t = ((v >> 1) & 0x7); + B = t | (t << 6); + C = 22; + D = v >> 4; + break; + case 5: + t = ((v >> 1) & 0xF); + B = (t >> 2) | (t << 5); + C = 11; + D = v >> 5; + break; + case 6: + B = ((v & 0x3E) << 3) | ((v >> 5) & 0x1); + C = 5; + D = v >> 6; + break; + default: + unreachable(""); + } + uint16_t T = D * C + B; + T = T ^ A; + T = (A & 0x80) | (T >> 2); + assert(T < 256); + colour_endpoints[i] = T; + } else if (ce_quints) { + uint16_t A, B, C, D; + uint16_t t; + A = (v & 0x1) ? 0x1FF : 0x000; + switch (ce_bits) { + case 1: + B = 0; + C = 113; + D = v >> 1; + break; + case 2: + B = (v & 0x2) ? 0x10C : 0x000; + C = 54; + D = v >> 2; + break; + case 3: + t = ((v >> 1) & 0x3); + B = (t >> 1) | (t << 1) | (t << 7); + C = 26; + D = v >> 3; + break; + case 4: + t = ((v >> 1) & 0x7); + B = (t >> 1) | (t << 6); + C = 13; + D = v >> 4; + break; + case 5: + t = ((v >> 1) & 0xF); + B = (t >> 4) | (t << 5); + C = 6; + D = v >> 5; + break; + default: + unreachable(""); + } + uint16_t T = D * C + B; + T = T ^ A; + T = (A & 0x80) | (T >> 2); + assert(T < 256); + colour_endpoints[i] = T; + } else { + switch (ce_bits) { + case 1: v = v ? 0xFF : 0x00; break; + case 2: v = (v << 6) | (v << 4) | (v << 2) | v; break; + case 3: v = (v << 5) | (v << 2) | (v >> 1); break; + case 4: v = (v << 4) | v; break; + case 5: v = (v << 3) | (v >> 2); break; + case 6: v = (v << 2) | (v >> 4); break; + case 7: v = (v << 1) | (v >> 6); break; + case 8: break; + default: unreachable(""); + } + colour_endpoints[i] = v; + } + } +} + +decode_error::type Block::decode(const Decoder &decoder, InputBitVector in) +{ + decode_error::type err; + + is_error = false; + bogus_colour_endpoints = false; + bogus_weights = false; + is_void_extent = false; + + wt_d = 1; + /* TODO: 3D */ + + /* TODO: test for all the illegal encodings */ + + if (VERBOSE_DECODE) + in.printf_bits(0, 128); + + err = decode_block_mode(in); + if (err != decode_error::ok) + return err; + + if (is_void_extent) + return decode_error::ok; + + /* TODO: 3D */ + + calculate_from_weights(); + + if (VERBOSE_DECODE) + printf("weights_grid=%dx%dx%d dual_plane=%d num_weights=%d high_prec=%d r=%d range=0..%d (%dt %dq %db) weight_bits=%d\n", + wt_w, wt_h, wt_d, dual_plane, num_weights, high_prec, wt_range, wt_max, wt_trits, wt_quints, wt_bits, weight_bits); + + if (wt_w > decoder.block_w || wt_h > decoder.block_h || wt_d > decoder.block_d) + return decode_error::weight_grid_exceeds_block_size; + + num_parts = in.get_bits(11, 2) + 1; + + if (VERBOSE_DECODE) + in.printf_bits(11, 2, "partitions = %d", num_parts); + + if (dual_plane && num_parts > 3) + return decode_error::dual_plane_and_too_many_partitions; + + decode_cem(in); + + if (VERBOSE_DECODE) + printf("cem=[%d,%d,%d,%d] base_cem_class=%d\n", cems[0], cems[1], cems[2], cems[3], cem_base_class); + + int num_cem_pairs = (cem_base_class + 1) * num_parts + extra_cem_bits; + num_cem_values = num_cem_pairs * 2; + + calculate_remaining_bits(); + err = calculate_colour_endpoints_size(); + if (err != decode_error::ok) + return err; + + if (VERBOSE_DECODE) + in.printf_bits(colour_endpoint_data_offset, colour_endpoint_bits, + "endpoint data (%d bits, %d vals, %dt %dq %db)", + colour_endpoint_bits, num_cem_values, ce_trits, ce_quints, ce_bits); + + unpack_colour_endpoints(in); + + if (VERBOSE_DECODE) { + printf("cem values raw =["); + for (int i = 0; i < num_cem_values; i++) { + if (i) + printf(", "); + printf("%3d", colour_endpoints_quant[i]); + } + printf("]\n"); + } + + if (num_cem_values > 18) + return decode_error::invalid_colour_endpoints_count; + + unquantise_colour_endpoints(); + + if (VERBOSE_DECODE) { + printf("cem values norm=["); + for (int i = 0; i < num_cem_values; i++) { + if (i) + printf(", "); + printf("%3d", colour_endpoints[i]); + } + printf("]\n"); + } + + decode_colour_endpoints(); + + if (dual_plane) { + int ccs_offset = 128 - weight_bits - num_extra_cem_bits - 2; + colour_component_selector = in.get_bits(ccs_offset, 2); + + if (VERBOSE_DECODE) + in.printf_bits(ccs_offset, 2, "colour component selector = %d", colour_component_selector); + } else { + colour_component_selector = 0; + } + + + if (VERBOSE_DECODE) + in.printf_bits(128 - weight_bits, weight_bits, "weights (%d bits)", weight_bits); + + if (num_weights > 64) + return decode_error::invalid_num_weights; + + if (weight_bits < 24 || weight_bits > 96) + return decode_error::invalid_weight_bits; + + unpack_weights(in); + + unquantise_weights(); + + if (VERBOSE_DECODE) { + printf("weights=["); + for (int i = 0; i < num_weights; ++i) { + if (i) + printf(", "); + printf("%d", weights[i]); + } + printf("]\n"); + + for (int plane = 0; plane <= dual_plane; ++plane) { + printf("weights (plane %d):\n", plane); + int i = 0; + (void)i; + + for (int r = 0; r < wt_d; ++r) { + for (int t = 0; t < wt_h; ++t) { + for (int s = 0; s < wt_w; ++s) { + printf("%3d", weights[i++ * (1 + dual_plane) + plane]); + } + printf("\n"); + } + if (r < wt_d - 1) + printf("\n"); + } + } + } + + compute_infill_weights(decoder.block_w, decoder.block_h, decoder.block_d); + + if (VERBOSE_DECODE) { + for (int plane = 0; plane <= dual_plane; ++plane) { + printf("infilled weights (plane %d):\n", plane); + int i = 0; + (void)i; + + for (int r = 0; r < decoder.block_d; ++r) { + for (int t = 0; t < decoder.block_h; ++t) { + for (int s = 0; s < decoder.block_w; ++s) { + printf("%3d", infill_weights[plane][i++]); + } + printf("\n"); + } + if (r < decoder.block_d - 1) + printf("\n"); + } + } + } + if (VERBOSE_DECODE) + printf("\n"); + + return decode_error::ok; +} + +void Block::write_decoded(const Decoder &decoder, uint16_t *output) +{ + /* sRGB can only be stored as unorm8. */ + assert(!decoder.srgb || decoder.output_unorm8); + + if (is_void_extent) { + for (int idx = 0; idx < decoder.block_w*decoder.block_h*decoder.block_d; ++idx) { + if (decoder.output_unorm8) { + if (decoder.srgb) { + output[idx*4+0] = void_extent_colour_r >> 8; + output[idx*4+1] = void_extent_colour_g >> 8; + output[idx*4+2] = void_extent_colour_b >> 8; + } else { + output[idx*4+0] = uint16_div_64k_to_half_to_unorm8(void_extent_colour_r); + output[idx*4+1] = uint16_div_64k_to_half_to_unorm8(void_extent_colour_g); + output[idx*4+2] = uint16_div_64k_to_half_to_unorm8(void_extent_colour_b); + } + output[idx*4+3] = uint16_div_64k_to_half_to_unorm8(void_extent_colour_a); + } else { + /* Store the color as FP16. */ + output[idx*4+0] = _mesa_uint16_div_64k_to_half(void_extent_colour_r); + output[idx*4+1] = _mesa_uint16_div_64k_to_half(void_extent_colour_g); + output[idx*4+2] = _mesa_uint16_div_64k_to_half(void_extent_colour_b); + output[idx*4+3] = _mesa_uint16_div_64k_to_half(void_extent_colour_a); + } + } + return; + } + + int small_block = (decoder.block_w * decoder.block_h * decoder.block_d) < 31; + + int idx = 0; + for (int z = 0; z < decoder.block_d; ++z) { + for (int y = 0; y < decoder.block_h; ++y) { + for (int x = 0; x < decoder.block_w; ++x) { + + int partition; + if (num_parts > 1) { + partition = select_partition(partition_index, x, y, z, num_parts, small_block); + assert(partition < num_parts); + } else { + partition = 0; + } + + /* TODO: HDR */ + + uint8x4_t e0 = endpoints_decoded[0][partition]; + uint8x4_t e1 = endpoints_decoded[1][partition]; + uint16_t c0[4], c1[4]; + + /* Expand to 16 bits. */ + if (decoder.srgb) { + c0[0] = (uint16_t)((e0.v[0] << 8) | 0x80); + c0[1] = (uint16_t)((e0.v[1] << 8) | 0x80); + c0[2] = (uint16_t)((e0.v[2] << 8) | 0x80); + c0[3] = (uint16_t)((e0.v[3] << 8) | 0x80); + + c1[0] = (uint16_t)((e1.v[0] << 8) | 0x80); + c1[1] = (uint16_t)((e1.v[1] << 8) | 0x80); + c1[2] = (uint16_t)((e1.v[2] << 8) | 0x80); + c1[3] = (uint16_t)((e1.v[3] << 8) | 0x80); + } else { + c0[0] = (uint16_t)((e0.v[0] << 8) | e0.v[0]); + c0[1] = (uint16_t)((e0.v[1] << 8) | e0.v[1]); + c0[2] = (uint16_t)((e0.v[2] << 8) | e0.v[2]); + c0[3] = (uint16_t)((e0.v[3] << 8) | e0.v[3]); + + c1[0] = (uint16_t)((e1.v[0] << 8) | e1.v[0]); + c1[1] = (uint16_t)((e1.v[1] << 8) | e1.v[1]); + c1[2] = (uint16_t)((e1.v[2] << 8) | e1.v[2]); + c1[3] = (uint16_t)((e1.v[3] << 8) | e1.v[3]); + } + + int w[4]; + if (dual_plane) { + int w0 = infill_weights[0][idx]; + int w1 = infill_weights[1][idx]; + w[0] = w[1] = w[2] = w[3] = w0; + w[colour_component_selector] = w1; + } else { + int w0 = infill_weights[0][idx]; + w[0] = w[1] = w[2] = w[3] = w0; + } + + /* Interpolate to produce UNORM16, applying weights. */ + uint16_t c[4] = { + (uint16_t)((c0[0] * (64 - w[0]) + c1[0] * w[0] + 32) >> 6), + (uint16_t)((c0[1] * (64 - w[1]) + c1[1] * w[1] + 32) >> 6), + (uint16_t)((c0[2] * (64 - w[2]) + c1[2] * w[2] + 32) >> 6), + (uint16_t)((c0[3] * (64 - w[3]) + c1[3] * w[3] + 32) >> 6), + }; + + if (decoder.output_unorm8) { + if (decoder.srgb) { + output[idx*4+0] = c[0] >> 8; + output[idx*4+1] = c[1] >> 8; + output[idx*4+2] = c[2] >> 8; + } else { + output[idx*4+0] = c[0] == 65535 ? 0xff : uint16_div_64k_to_half_to_unorm8(c[0]); + output[idx*4+1] = c[1] == 65535 ? 0xff : uint16_div_64k_to_half_to_unorm8(c[1]); + output[idx*4+2] = c[2] == 65535 ? 0xff : uint16_div_64k_to_half_to_unorm8(c[2]); + } + output[idx*4+3] = c[3] == 65535 ? 0xff : uint16_div_64k_to_half_to_unorm8(c[3]); + } else { + /* Store the color as FP16. */ + output[idx*4+0] = c[0] == 65535 ? FP16_ONE : _mesa_uint16_div_64k_to_half(c[0]); + output[idx*4+1] = c[1] == 65535 ? FP16_ONE : _mesa_uint16_div_64k_to_half(c[1]); + output[idx*4+2] = c[2] == 65535 ? FP16_ONE : _mesa_uint16_div_64k_to_half(c[2]); + output[idx*4+3] = c[3] == 65535 ? FP16_ONE : _mesa_uint16_div_64k_to_half(c[3]); + } + + idx++; + } + } + } +} + +void Block::calculate_from_weights() +{ + wt_trits = 0; + wt_quints = 0; + wt_bits = 0; + switch (high_prec) { + case 0: + switch (wt_range) { + case 0x2: wt_max = 1; wt_bits = 1; break; + case 0x3: wt_max = 2; wt_trits = 1; break; + case 0x4: wt_max = 3; wt_bits = 2; break; + case 0x5: wt_max = 4; wt_quints = 1; break; + case 0x6: wt_max = 5; wt_trits = 1; wt_bits = 1; break; + case 0x7: wt_max = 7; wt_bits = 3; break; + default: abort(); + } + break; + case 1: + switch (wt_range) { + case 0x2: wt_max = 9; wt_quints = 1; wt_bits = 1; break; + case 0x3: wt_max = 11; wt_trits = 1; wt_bits = 2; break; + case 0x4: wt_max = 15; wt_bits = 4; break; + case 0x5: wt_max = 19; wt_quints = 1; wt_bits = 2; break; + case 0x6: wt_max = 23; wt_trits = 1; wt_bits = 3; break; + case 0x7: wt_max = 31; wt_bits = 5; break; + default: abort(); + } + break; + } + + assert(wt_trits || wt_quints || wt_bits); + + num_weights = wt_w * wt_h * wt_d; + + if (dual_plane) + num_weights *= 2; + + weight_bits = + (num_weights * 8 * wt_trits + 4) / 5 + + (num_weights * 7 * wt_quints + 2) / 3 + + num_weights * wt_bits; +} + +void Block::calculate_remaining_bits() +{ + int config_bits; + if (num_parts > 1) { + if (!is_multi_cem) + config_bits = 29; + else + config_bits = 25 + 3 * num_parts; + } else { + config_bits = 17; + } + + if (dual_plane) + config_bits += 2; + + remaining_bits = 128 - config_bits - weight_bits; +} + +decode_error::type Block::calculate_colour_endpoints_size() +{ + /* Specified as illegal */ + if (remaining_bits < (13 * num_cem_values + 4) / 5) { + colour_endpoint_bits = ce_max = ce_trits = ce_quints = ce_bits = 0; + return decode_error::invalid_colour_endpoints_size; + } + + /* Find the largest cem_ranges that fits within remaining_bits */ + for (int i = ARRAY_SIZE(cem_ranges)-1; i >= 0; --i) { + int cem_bits; + cem_bits = (num_cem_values * 8 * cem_ranges[i].t + 4) / 5 + + (num_cem_values * 7 * cem_ranges[i].q + 2) / 3 + + num_cem_values * cem_ranges[i].b; + + if (cem_bits <= remaining_bits) + { + colour_endpoint_bits = cem_bits; + ce_max = cem_ranges[i].max; + ce_trits = cem_ranges[i].t; + ce_quints = cem_ranges[i].q; + ce_bits = cem_ranges[i].b; + return decode_error::ok; + } + } + + assert(0); + return decode_error::invalid_colour_endpoints_size; +} + +/** + * Decode ASTC 2D LDR texture data. + * + * \param src_width in pixels + * \param src_height in pixels + * \param dst_stride in bytes + */ +extern "C" void +_mesa_unpack_astc_2d_ldr(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned src_width, + unsigned src_height, + mesa_format format) +{ + assert(_mesa_is_format_astc_2d(format)); + bool srgb = _mesa_get_format_color_encoding(format) == GL_SRGB; + + unsigned blk_w, blk_h; + _mesa_get_format_block_size(format, &blk_w, &blk_h); + + const unsigned block_size = 16; + unsigned x_blocks = (src_width + blk_w - 1) / blk_w; + unsigned y_blocks = (src_height + blk_h - 1) / blk_h; + + Decoder dec(blk_w, blk_h, 1, srgb, true); + + for (unsigned y = 0; y < y_blocks; ++y) { + for (unsigned x = 0; x < x_blocks; ++x) { + /* Same size as the largest block. */ + uint16_t block_out[12 * 12 * 4]; + + dec.decode(src_row + x * block_size, block_out); + + /* This can be smaller with NPOT dimensions. */ + unsigned dst_blk_w = MIN2(blk_w, src_width - x*blk_w); + unsigned dst_blk_h = MIN2(blk_h, src_height - y*blk_h); + + for (unsigned sub_y = 0; sub_y < dst_blk_h; ++sub_y) { + for (unsigned sub_x = 0; sub_x < dst_blk_w; ++sub_x) { + uint8_t *dst = dst_row + sub_y * dst_stride + + (x * blk_w + sub_x) * 4; + const uint16_t *src = &block_out[(sub_y * blk_w + sub_x) * 4]; + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + } + } + } + src_row += src_stride; + dst_row += dst_stride * blk_h; + } +} diff --git a/lib/mesa/src/mesa/main/texcompress_astc.h b/lib/mesa/src/mesa/main/texcompress_astc.h new file mode 100644 index 000000000..9f9c5281d --- /dev/null +++ b/lib/mesa/src/mesa/main/texcompress_astc.h @@ -0,0 +1,47 @@ +/* + * Copyright 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef TEXCOMPRESS_ASTC_H +#define TEXCOMPRESS_ASTC_H + +#include <inttypes.h> +#include "texcompress.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void +_mesa_unpack_astc_2d_ldr(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned src_width, + unsigned src_height, + mesa_format format); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/mesa/src/mesa/main/texcompress_bptc.c b/lib/mesa/src/mesa/main/texcompress_bptc.c index 26e591580..46279f144 100644 --- a/lib/mesa/src/mesa/main/texcompress_bptc.c +++ b/lib/mesa/src/mesa/main/texcompress_bptc.c @@ -29,631 +29,38 @@ #include <stdbool.h> #include "texcompress.h" #include "texcompress_bptc.h" -#include "util/format_srgb.h" -#include "util/half_float.h" +#include "texcompress_bptc_tmp.h" #include "texstore.h" -#include "macros.h" #include "image.h" +#include "mtypes.h" -#define BLOCK_SIZE 4 -#define N_PARTITIONS 64 -#define BLOCK_BYTES 16 - -struct bptc_unorm_mode { - int n_subsets; - int n_partition_bits; - bool has_rotation_bits; - bool has_index_selection_bit; - int n_color_bits; - int n_alpha_bits; - bool has_endpoint_pbits; - bool has_shared_pbits; - int n_index_bits; - int n_secondary_index_bits; -}; - -struct bptc_float_bitfield { - int8_t endpoint; - uint8_t component; - uint8_t offset; - uint8_t n_bits; - bool reverse; -}; - -struct bptc_float_mode { - bool reserved; - bool transformed_endpoints; - int n_partition_bits; - int n_endpoint_bits; - int n_index_bits; - int n_delta_bits[3]; - struct bptc_float_bitfield bitfields[24]; -}; - -struct bit_writer { - uint8_t buf; - int pos; - uint8_t *dst; -}; - -static const struct bptc_unorm_mode -bptc_unorm_modes[] = { - /* 0 */ { 3, 4, false, false, 4, 0, true, false, 3, 0 }, - /* 1 */ { 2, 6, false, false, 6, 0, false, true, 3, 0 }, - /* 2 */ { 3, 6, false, false, 5, 0, false, false, 2, 0 }, - /* 3 */ { 2, 6, false, false, 7, 0, true, false, 2, 0 }, - /* 4 */ { 1, 0, true, true, 5, 6, false, false, 2, 3 }, - /* 5 */ { 1, 0, true, false, 7, 8, false, false, 2, 2 }, - /* 6 */ { 1, 0, false, false, 7, 7, true, false, 4, 0 }, - /* 7 */ { 2, 6, false, false, 5, 5, true, false, 2, 0 } -}; - -static const struct bptc_float_mode -bptc_float_modes[] = { - /* 00 */ - { false, true, 5, 10, 3, { 5, 5, 5 }, - { { 2, 1, 4, 1, false }, { 2, 2, 4, 1, false }, { 3, 2, 4, 1, false }, - { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, - { 1, 2, 0, 5, false }, { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, - { 2, 0, 0, 5, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, - { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 01 */ - { false, true, 5, 7, 3, { 6, 6, 6 }, - { { 2, 1, 5, 1, false }, { 3, 1, 4, 1, false }, { 3, 1, 5, 1, false }, - { 0, 0, 0, 7, false }, { 3, 2, 0, 1, false }, { 3, 2, 1, 1, false }, - { 2, 2, 4, 1, false }, { 0, 1, 0, 7, false }, { 2, 2, 5, 1, false }, - { 3, 2, 2, 1, false }, { 2, 1, 4, 1, false }, { 0, 2, 0, 7, false }, - { 3, 2, 3, 1, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 6, false }, - { 3, 1, 0, 4, false }, { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, - { 2, 0, 0, 6, false }, - { 3, 0, 0, 6, false }, - { -1 } } - }, - /* 00010 */ - { false, true, 5, 11, 3, { 5, 4, 4 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 5, false }, { 0, 0, 10, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 4, false }, { 0, 1, 10, 1, false }, { 3, 2, 0, 1, false }, - { 3, 1, 0, 4, false }, { 1, 2, 0, 4, false }, { 0, 2, 10, 1, false }, - { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false }, - { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 00011 */ - { false, false, 0, 10, 4, { 10, 10, 10 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 10, false }, { 1, 1, 0, 10, false }, { 1, 2, 0, 10, false }, - { -1 } } - }, - /* 00110 */ - { false, true, 5, 11, 3, { 4, 5, 4 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 4, false }, { 0, 0, 10, 1, false }, { 3, 1, 4, 1, false }, - { 2, 1, 0, 4, false }, { 1, 1, 0, 5, false }, { 0, 1, 10, 1, false }, - { 3, 1, 0, 4, false }, { 1, 2, 0, 4, false }, { 0, 2, 10, 1, false }, - { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 4, false }, - { 3, 2, 0, 1, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 4, false }, - { 2, 1, 4, 1, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 00111 */ - { false, true, 0, 11, 4, { 9, 9, 9 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 9, false }, { 0, 0, 10, 1, false }, { 1, 1, 0, 9, false }, - { 0, 1, 10, 1, false }, { 1, 2, 0, 9, false }, { 0, 2, 10, 1, false }, - { -1 } } - }, - /* 01010 */ - { false, true, 5, 11, 3, { 4, 4, 5 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 4, false }, { 0, 0, 10, 1, false }, { 2, 2, 4, 1, false }, - { 2, 1, 0, 4, false }, { 1, 1, 0, 4, false }, { 0, 1, 10, 1, false }, - { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false }, - { 0, 2, 10, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 4, false }, - { 3, 2, 1, 1, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 4, false }, - { 3, 2, 4, 1, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 01011 */ - { false, true, 0, 12, 4, { 8, 8, 8 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 8, false }, { 0, 0, 10, 2, true }, { 1, 1, 0, 8, false }, - { 0, 1, 10, 2, true }, { 1, 2, 0, 8, false }, { 0, 2, 10, 2, true }, - { -1 } } - }, - /* 01110 */ - { false, true, 5, 9, 3, { 5, 5, 5 }, - { { 0, 0, 0, 9, false }, { 2, 2, 4, 1, false }, { 0, 1, 0, 9, false }, - { 2, 1, 4, 1, false }, { 0, 2, 0, 9, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, - { 1, 2, 0, 5, false }, { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, - { 2, 0, 0, 5, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, - { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 01111 */ - { false, true, 0, 16, 4, { 4, 4, 4 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 4, false }, { 0, 0, 10, 6, true }, { 1, 1, 0, 4, false }, - { 0, 1, 10, 6, true }, { 1, 2, 0, 4, false }, { 0, 2, 10, 6, true }, - { -1 } } - }, - /* 10010 */ - { false, true, 5, 8, 3, { 6, 5, 5 }, - { { 0, 0, 0, 8, false }, { 3, 1, 4, 1, false }, { 2, 2, 4, 1, false }, - { 0, 1, 0, 8, false }, { 3, 2, 2, 1, false }, { 2, 1, 4, 1, false }, - { 0, 2, 0, 8, false }, { 3, 2, 3, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 5, false }, - { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false }, - { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 6, false }, - { 3, 0, 0, 6, false }, - { -1 } } - }, - /* 10011 */ - { true /* reserved */ }, - /* 10110 */ - { false, true, 5, 8, 3, { 5, 6, 5 }, - { { 0, 0, 0, 8, false }, { 3, 2, 0, 1, false }, { 2, 2, 4, 1, false }, - { 0, 1, 0, 8, false }, { 2, 1, 5, 1, false }, { 2, 1, 4, 1, false }, - { 0, 2, 0, 8, false }, { 3, 1, 5, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 6, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false }, - { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false }, - { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 10111 */ - { true /* reserved */ }, - /* 11010 */ - { false, true, 5, 8, 3, { 5, 5, 6 }, - { { 0, 0, 0, 8, false }, { 3, 2, 1, 1, false }, { 2, 2, 4, 1, false }, - { 0, 1, 0, 8, false }, { 2, 2, 5, 1, false }, { 2, 1, 4, 1, false }, - { 0, 2, 0, 8, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, - { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false }, - { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 11011 */ - { true /* reserved */ }, - /* 11110 */ - { false, false, 5, 6, 3, { 6, 6, 6 }, - { { 0, 0, 0, 6, false }, { 3, 1, 4, 1, false }, { 3, 2, 0, 1, false }, - { 3, 2, 1, 1, false }, { 2, 2, 4, 1, false }, { 0, 1, 0, 6, false }, - { 2, 1, 5, 1, false }, { 2, 2, 5, 1, false }, { 3, 2, 2, 1, false }, - { 2, 1, 4, 1, false }, { 0, 2, 0, 6, false }, { 3, 1, 5, 1, false }, - { 3, 2, 3, 1, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 6, false }, - { 3, 1, 0, 4, false }, { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, - { 2, 0, 0, 6, false }, { 3, 0, 0, 6, false }, - { -1 } } - }, - /* 11111 */ - { true /* reserved */ }, -}; - -/* This partition table is used when the mode has two subsets. Each - * partition is represented by a 32-bit value which gives 2 bits per texel - * within the block. The value of the two bits represents which subset to use - * (0 or 1). - */ -static const uint32_t -partition_table1[N_PARTITIONS] = { - 0x50505050U, 0x40404040U, 0x54545454U, 0x54505040U, - 0x50404000U, 0x55545450U, 0x55545040U, 0x54504000U, - 0x50400000U, 0x55555450U, 0x55544000U, 0x54400000U, - 0x55555440U, 0x55550000U, 0x55555500U, 0x55000000U, - 0x55150100U, 0x00004054U, 0x15010000U, 0x00405054U, - 0x00004050U, 0x15050100U, 0x05010000U, 0x40505054U, - 0x00404050U, 0x05010100U, 0x14141414U, 0x05141450U, - 0x01155440U, 0x00555500U, 0x15014054U, 0x05414150U, - 0x44444444U, 0x55005500U, 0x11441144U, 0x05055050U, - 0x05500550U, 0x11114444U, 0x41144114U, 0x44111144U, - 0x15055054U, 0x01055040U, 0x05041050U, 0x05455150U, - 0x14414114U, 0x50050550U, 0x41411414U, 0x00141400U, - 0x00041504U, 0x00105410U, 0x10541000U, 0x04150400U, - 0x50410514U, 0x41051450U, 0x05415014U, 0x14054150U, - 0x41050514U, 0x41505014U, 0x40011554U, 0x54150140U, - 0x50505500U, 0x00555050U, 0x15151010U, 0x54540404U, -}; - -/* This partition table is used when the mode has three subsets. In this case - * the values can be 0, 1 or 2. - */ -static const uint32_t -partition_table2[N_PARTITIONS] = { - 0xaa685050U, 0x6a5a5040U, 0x5a5a4200U, 0x5450a0a8U, - 0xa5a50000U, 0xa0a05050U, 0x5555a0a0U, 0x5a5a5050U, - 0xaa550000U, 0xaa555500U, 0xaaaa5500U, 0x90909090U, - 0x94949494U, 0xa4a4a4a4U, 0xa9a59450U, 0x2a0a4250U, - 0xa5945040U, 0x0a425054U, 0xa5a5a500U, 0x55a0a0a0U, - 0xa8a85454U, 0x6a6a4040U, 0xa4a45000U, 0x1a1a0500U, - 0x0050a4a4U, 0xaaa59090U, 0x14696914U, 0x69691400U, - 0xa08585a0U, 0xaa821414U, 0x50a4a450U, 0x6a5a0200U, - 0xa9a58000U, 0x5090a0a8U, 0xa8a09050U, 0x24242424U, - 0x00aa5500U, 0x24924924U, 0x24499224U, 0x50a50a50U, - 0x500aa550U, 0xaaaa4444U, 0x66660000U, 0xa5a0a5a0U, - 0x50a050a0U, 0x69286928U, 0x44aaaa44U, 0x66666600U, - 0xaa444444U, 0x54a854a8U, 0x95809580U, 0x96969600U, - 0xa85454a8U, 0x80959580U, 0xaa141414U, 0x96960000U, - 0xaaaa1414U, 0xa05050a0U, 0xa0a5a5a0U, 0x96000000U, - 0x40804080U, 0xa9a8a9a8U, 0xaaaaaa44U, 0x2a4a5254U -}; - -static const uint8_t -anchor_indices[][N_PARTITIONS] = { - /* Anchor index values for the second subset of two-subset partitioning */ - { - 0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf, - 0xf,0x2,0x8,0x2,0x2,0x8,0x8,0xf,0x2,0x8,0x2,0x2,0x8,0x8,0x2,0x2, - 0xf,0xf,0x6,0x8,0x2,0x8,0xf,0xf,0x2,0x8,0x2,0x2,0x2,0xf,0xf,0x6, - 0x6,0x2,0x6,0x8,0xf,0xf,0x2,0x2,0xf,0xf,0xf,0xf,0xf,0x2,0x2,0xf - }, - - /* Anchor index values for the second subset of three-subset partitioning */ - { - 0x3,0x3,0xf,0xf,0x8,0x3,0xf,0xf,0x8,0x8,0x6,0x6,0x6,0x5,0x3,0x3, - 0x3,0x3,0x8,0xf,0x3,0x3,0x6,0xa,0x5,0x8,0x8,0x6,0x8,0x5,0xf,0xf, - 0x8,0xf,0x3,0x5,0x6,0xa,0x8,0xf,0xf,0x3,0xf,0x5,0xf,0xf,0xf,0xf, - 0x3,0xf,0x5,0x5,0x5,0x8,0x5,0xa,0x5,0xa,0x8,0xd,0xf,0xc,0x3,0x3 - }, - - /* Anchor index values for the third subset of three-subset - * partitioning - */ - { - 0xf,0x8,0x8,0x3,0xf,0xf,0x3,0x8,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x8, - 0xf,0x8,0xf,0x3,0xf,0x8,0xf,0x8,0x3,0xf,0x6,0xa,0xf,0xf,0xa,0x8, - 0xf,0x3,0xf,0xa,0xa,0x8,0x9,0xa,0x6,0xf,0x8,0xf,0x3,0x6,0x6,0x8, - 0xf,0x3,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x3,0xf,0xf,0x8 - } -}; - -static int -extract_bits(const uint8_t *block, - int offset, - int n_bits) -{ - int byte_index = offset / 8; - int bit_index = offset % 8; - int n_bits_in_byte = MIN2(n_bits, 8 - bit_index); - int result = 0; - int bit = 0; - - while (true) { - result |= ((block[byte_index] >> bit_index) & - ((1 << n_bits_in_byte) - 1)) << bit; - - n_bits -= n_bits_in_byte; - - if (n_bits <= 0) - return result; - - bit += n_bits_in_byte; - byte_index++; - bit_index = 0; - n_bits_in_byte = MIN2(n_bits, 8); - } -} - -static uint8_t -expand_component(uint8_t byte, - int n_bits) -{ - /* Expands a n-bit quantity into a byte by copying the most-significant - * bits into the unused least-significant bits. - */ - return byte << (8 - n_bits) | (byte >> (2 * n_bits - 8)); -} - -static int -extract_unorm_endpoints(const struct bptc_unorm_mode *mode, - const uint8_t *block, - int bit_offset, - uint8_t endpoints[][4]) -{ - int component; - int subset; - int endpoint; - int pbit; - int n_components; - - /* Extract each color component */ - for (component = 0; component < 3; component++) { - for (subset = 0; subset < mode->n_subsets; subset++) { - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoints[subset * 2 + endpoint][component] = - extract_bits(block, bit_offset, mode->n_color_bits); - bit_offset += mode->n_color_bits; - } - } - } - - /* Extract the alpha values */ - if (mode->n_alpha_bits > 0) { - for (subset = 0; subset < mode->n_subsets; subset++) { - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoints[subset * 2 + endpoint][3] = - extract_bits(block, bit_offset, mode->n_alpha_bits); - bit_offset += mode->n_alpha_bits; - } - } - - n_components = 4; - } else { - for (subset = 0; subset < mode->n_subsets; subset++) - for (endpoint = 0; endpoint < 2; endpoint++) - endpoints[subset * 2 + endpoint][3] = 255; - - n_components = 3; - } - - /* Add in the p-bits */ - if (mode->has_endpoint_pbits) { - for (subset = 0; subset < mode->n_subsets; subset++) { - for (endpoint = 0; endpoint < 2; endpoint++) { - pbit = extract_bits(block, bit_offset, 1); - bit_offset += 1; - - for (component = 0; component < n_components; component++) { - endpoints[subset * 2 + endpoint][component] <<= 1; - endpoints[subset * 2 + endpoint][component] |= pbit; - } - } - } - } else if (mode->has_shared_pbits) { - for (subset = 0; subset < mode->n_subsets; subset++) { - pbit = extract_bits(block, bit_offset, 1); - bit_offset += 1; - - for (endpoint = 0; endpoint < 2; endpoint++) { - for (component = 0; component < n_components; component++) { - endpoints[subset * 2 + endpoint][component] <<= 1; - endpoints[subset * 2 + endpoint][component] |= pbit; - } - } - } - } - - /* Expand the n-bit values to a byte */ - for (subset = 0; subset < mode->n_subsets; subset++) { - for (endpoint = 0; endpoint < 2; endpoint++) { - for (component = 0; component < 3; component++) { - endpoints[subset * 2 + endpoint][component] = - expand_component(endpoints[subset * 2 + endpoint][component], - mode->n_color_bits + - mode->has_endpoint_pbits + - mode->has_shared_pbits); - } - - if (mode->n_alpha_bits > 0) { - endpoints[subset * 2 + endpoint][3] = - expand_component(endpoints[subset * 2 + endpoint][3], - mode->n_alpha_bits + - mode->has_endpoint_pbits + - mode->has_shared_pbits); - } - } - } - - return bit_offset; -} - -static bool -is_anchor(int n_subsets, - int partition_num, - int texel) -{ - if (texel == 0) - return true; - - switch (n_subsets) { - case 1: - return false; - case 2: - return anchor_indices[0][partition_num] == texel; - case 3: - return (anchor_indices[1][partition_num] == texel || - anchor_indices[2][partition_num] == texel); - default: - assert(false); - return false; - } -} - -static int -count_anchors_before_texel(int n_subsets, - int partition_num, - int texel) -{ - int count = 1; - - if (texel == 0) - return 0; - - switch (n_subsets) { - case 1: - break; - case 2: - if (texel > anchor_indices[0][partition_num]) - count++; - break; - case 3: - if (texel > anchor_indices[1][partition_num]) - count++; - if (texel > anchor_indices[2][partition_num]) - count++; - break; - default: - assert(false); - return 0; - } - - return count; -} - -static int32_t -interpolate(int32_t a, int32_t b, - int index, - int index_bits) +static void +fetch_bptc_rgb_float(const GLubyte *map, + GLint rowStride, GLint i, GLint j, + GLfloat *texel, + bool is_signed) { - static const uint8_t weights2[] = { 0, 21, 43, 64 }; - static const uint8_t weights3[] = { 0, 9, 18, 27, 37, 46, 55, 64 }; - static const uint8_t weights4[] = - { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; - static const uint8_t *weights[] = { - NULL, NULL, weights2, weights3, weights4 - }; - int weight; + const GLubyte *block; - weight = weights[index_bits][index]; + block = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; - return ((64 - weight) * a + weight * b + 32) >> 6; + fetch_rgb_float_from_block(block, texel, (i % 4) + (j % 4) * 4, is_signed); } static void -apply_rotation(int rotation, - uint8_t *result) +fetch_bptc_rgb_signed_float(const GLubyte *map, + GLint rowStride, GLint i, GLint j, + GLfloat *texel) { - uint8_t t; - - if (rotation == 0) - return; - - rotation--; - - t = result[rotation]; - result[rotation] = result[3]; - result[3] = t; + fetch_bptc_rgb_float(map, rowStride, i, j, texel, true); } static void -fetch_rgba_unorm_from_block(const uint8_t *block, - uint8_t *result, - int texel) +fetch_bptc_rgb_unsigned_float(const GLubyte *map, + GLint rowStride, GLint i, GLint j, + GLfloat *texel) { - int mode_num = ffs(block[0]); - const struct bptc_unorm_mode *mode; - int bit_offset, secondary_bit_offset; - int partition_num; - int subset_num; - int rotation; - int index_selection; - int index_bits; - int indices[2]; - int index; - int anchors_before_texel; - bool anchor; - uint8_t endpoints[3 * 2][4]; - uint32_t subsets; - int component; - - if (mode_num == 0) { - /* According to the spec this mode is reserved and shouldn't be used. */ - memset(result, 0, 3); - result[3] = 0xff; - return; - } - - mode = bptc_unorm_modes + mode_num - 1; - bit_offset = mode_num; - - partition_num = extract_bits(block, bit_offset, mode->n_partition_bits); - bit_offset += mode->n_partition_bits; - - switch (mode->n_subsets) { - case 1: - subsets = 0; - break; - case 2: - subsets = partition_table1[partition_num]; - break; - case 3: - subsets = partition_table2[partition_num]; - break; - default: - assert(false); - return; - } - - if (mode->has_rotation_bits) { - rotation = extract_bits(block, bit_offset, 2); - bit_offset += 2; - } else { - rotation = 0; - } - - if (mode->has_index_selection_bit) { - index_selection = extract_bits(block, bit_offset, 1); - bit_offset++; - } else { - index_selection = 0; - } - - bit_offset = extract_unorm_endpoints(mode, block, bit_offset, endpoints); - - anchors_before_texel = count_anchors_before_texel(mode->n_subsets, - partition_num, texel); - - /* Calculate the offset to the secondary index */ - secondary_bit_offset = (bit_offset + - BLOCK_SIZE * BLOCK_SIZE * mode->n_index_bits - - mode->n_subsets + - mode->n_secondary_index_bits * texel - - anchors_before_texel); - - /* Calculate the offset to the primary index for this texel */ - bit_offset += mode->n_index_bits * texel - anchors_before_texel; - - subset_num = (subsets >> (texel * 2)) & 3; - - anchor = is_anchor(mode->n_subsets, partition_num, texel); - - index_bits = mode->n_index_bits; - if (anchor) - index_bits--; - indices[0] = extract_bits(block, bit_offset, index_bits); - - if (mode->n_secondary_index_bits) { - index_bits = mode->n_secondary_index_bits; - if (anchor) - index_bits--; - indices[1] = extract_bits(block, secondary_bit_offset, index_bits); - } - - index = indices[index_selection]; - index_bits = (index_selection ? - mode->n_secondary_index_bits : - mode->n_index_bits); - - for (component = 0; component < 3; component++) - result[component] = interpolate(endpoints[subset_num * 2][component], - endpoints[subset_num * 2 + 1][component], - index, - index_bits); - - /* Alpha uses the opposite index from the color components */ - if (mode->n_secondary_index_bits && !index_selection) { - index = indices[1]; - index_bits = mode->n_secondary_index_bits; - } else { - index = indices[0]; - index_bits = mode->n_index_bits; - } - - result[3] = interpolate(endpoints[subset_num * 2][3], - endpoints[subset_num * 2 + 1][3], - index, - index_bits); - - apply_rotation(rotation, result); + fetch_bptc_rgb_float(map, rowStride, i, j, texel, false); } static void @@ -698,257 +105,6 @@ fetch_bptc_srgb_alpha_unorm(const GLubyte *map, texel[ACOMP] = UBYTE_TO_FLOAT(texel_bytes[3]); } -static int32_t -sign_extend(int32_t value, - int n_bits) -{ - if ((value & (1 << (n_bits - 1)))) { - value |= (~(int32_t) 0) << n_bits; - } - - return value; -} - -static int -signed_unquantize(int value, int n_endpoint_bits) -{ - bool sign; - - if (n_endpoint_bits >= 16) - return value; - - if (value == 0) - return 0; - - sign = false; - - if (value < 0) { - sign = true; - value = -value; - } - - if (value >= (1 << (n_endpoint_bits - 1)) - 1) - value = 0x7fff; - else - value = ((value << 15) + 0x4000) >> (n_endpoint_bits - 1); - - if (sign) - value = -value; - - return value; -} - -static int -unsigned_unquantize(int value, int n_endpoint_bits) -{ - if (n_endpoint_bits >= 15) - return value; - - if (value == 0) - return 0; - - if (value == (1 << n_endpoint_bits) - 1) - return 0xffff; - - return ((value << 15) + 0x4000) >> (n_endpoint_bits - 1); -} - -static int -extract_float_endpoints(const struct bptc_float_mode *mode, - const uint8_t *block, - int bit_offset, - int32_t endpoints[][3], - bool is_signed) -{ - const struct bptc_float_bitfield *bitfield; - int endpoint, component; - int n_endpoints; - int value; - int i; - - if (mode->n_partition_bits) - n_endpoints = 4; - else - n_endpoints = 2; - - memset(endpoints, 0, sizeof endpoints[0][0] * n_endpoints * 3); - - for (bitfield = mode->bitfields; bitfield->endpoint != -1; bitfield++) { - value = extract_bits(block, bit_offset, bitfield->n_bits); - bit_offset += bitfield->n_bits; - - if (bitfield->reverse) { - for (i = 0; i < bitfield->n_bits; i++) { - if (value & (1 << i)) - endpoints[bitfield->endpoint][bitfield->component] |= - 1 << ((bitfield->n_bits - 1 - i) + bitfield->offset); - } - } else { - endpoints[bitfield->endpoint][bitfield->component] |= - value << bitfield->offset; - } - } - - if (mode->transformed_endpoints) { - /* The endpoints are specified as signed offsets from e0 */ - for (endpoint = 1; endpoint < n_endpoints; endpoint++) { - for (component = 0; component < 3; component++) { - value = sign_extend(endpoints[endpoint][component], - mode->n_delta_bits[component]); - endpoints[endpoint][component] = - ((endpoints[0][component] + value) & - ((1 << mode->n_endpoint_bits) - 1)); - } - } - } - - if (is_signed) { - for (endpoint = 0; endpoint < n_endpoints; endpoint++) { - for (component = 0; component < 3; component++) { - value = sign_extend(endpoints[endpoint][component], - mode->n_endpoint_bits); - endpoints[endpoint][component] = - signed_unquantize(value, mode->n_endpoint_bits); - } - } - } else { - for (endpoint = 0; endpoint < n_endpoints; endpoint++) { - for (component = 0; component < 3; component++) { - endpoints[endpoint][component] = - unsigned_unquantize(endpoints[endpoint][component], - mode->n_endpoint_bits); - } - } - } - - return bit_offset; -} - -static int32_t -finish_unsigned_unquantize(int32_t value) -{ - return value * 31 / 64; -} - -static int32_t -finish_signed_unquantize(int32_t value) -{ - if (value < 0) - return (-value * 31 / 32) | 0x8000; - else - return value * 31 / 32; -} - -static void -fetch_rgb_float_from_block(const uint8_t *block, - float *result, - int texel, - bool is_signed) -{ - int mode_num; - const struct bptc_float_mode *mode; - int bit_offset; - int partition_num; - int subset_num; - int index_bits; - int index; - int anchors_before_texel; - int32_t endpoints[2 * 2][3]; - uint32_t subsets; - int n_subsets; - int component; - int32_t value; - - if (block[0] & 0x2) { - mode_num = (((block[0] >> 1) & 0xe) | (block[0] & 1)) + 2; - bit_offset = 5; - } else { - mode_num = block[0] & 3; - bit_offset = 2; - } - - mode = bptc_float_modes + mode_num; - - if (mode->reserved) { - memset(result, 0, sizeof result[0] * 3); - result[3] = 1.0f; - return; - } - - bit_offset = extract_float_endpoints(mode, block, bit_offset, - endpoints, is_signed); - - if (mode->n_partition_bits) { - partition_num = extract_bits(block, bit_offset, mode->n_partition_bits); - bit_offset += mode->n_partition_bits; - - subsets = partition_table1[partition_num]; - n_subsets = 2; - } else { - partition_num = 0; - subsets = 0; - n_subsets = 1; - } - - anchors_before_texel = - count_anchors_before_texel(n_subsets, partition_num, texel); - - /* Calculate the offset to the primary index for this texel */ - bit_offset += mode->n_index_bits * texel - anchors_before_texel; - - subset_num = (subsets >> (texel * 2)) & 3; - - index_bits = mode->n_index_bits; - if (is_anchor(n_subsets, partition_num, texel)) - index_bits--; - index = extract_bits(block, bit_offset, index_bits); - - for (component = 0; component < 3; component++) { - value = interpolate(endpoints[subset_num * 2][component], - endpoints[subset_num * 2 + 1][component], - index, - mode->n_index_bits); - - if (is_signed) - value = finish_signed_unquantize(value); - else - value = finish_unsigned_unquantize(value); - - result[component] = _mesa_half_to_float(value); - } - - result[3] = 1.0f; -} - -static void -fetch_bptc_rgb_float(const GLubyte *map, - GLint rowStride, GLint i, GLint j, - GLfloat *texel, - bool is_signed) -{ - const GLubyte *block; - - block = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; - - fetch_rgb_float_from_block(block, texel, (i % 4) + (j % 4) * 4, is_signed); -} - -static void -fetch_bptc_rgb_signed_float(const GLubyte *map, - GLint rowStride, GLint i, GLint j, - GLfloat *texel) -{ - fetch_bptc_rgb_float(map, rowStride, i, j, texel, true); -} - -static void -fetch_bptc_rgb_unsigned_float(const GLubyte *map, - GLint rowStride, GLint i, GLint j, - GLfloat *texel) -{ - fetch_bptc_rgb_float(map, rowStride, i, j, texel, false); -} - compressed_fetch_func _mesa_get_bptc_fetch_func(mesa_format format) { @@ -966,312 +122,6 @@ _mesa_get_bptc_fetch_func(mesa_format format) } } -static void -write_bits(struct bit_writer *writer, int n_bits, int value) -{ - do { - if (n_bits + writer->pos >= 8) { - *(writer->dst++) = writer->buf | (value << writer->pos); - writer->buf = 0; - value >>= (8 - writer->pos); - n_bits -= (8 - writer->pos); - writer->pos = 0; - } else { - writer->buf |= value << writer->pos; - writer->pos += n_bits; - break; - } - } while (n_bits > 0); -} - -static void -get_average_luminance_alpha_unorm(int width, int height, - const uint8_t *src, int src_rowstride, - int *average_luminance, int *average_alpha) -{ - int luminance_sum = 0, alpha_sum = 0; - int y, x; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - luminance_sum += src[0] + src[1] + src[2]; - alpha_sum += src[3]; - src += 4; - } - src += src_rowstride - width * 4; - } - - *average_luminance = luminance_sum / (width * height); - *average_alpha = alpha_sum / (width * height); -} - -static void -get_rgba_endpoints_unorm(int width, int height, - const uint8_t *src, int src_rowstride, - int average_luminance, int average_alpha, - uint8_t endpoints[][4]) -{ - int endpoint_luminances[2]; - int midpoint; - int sums[2][4]; - int endpoint; - int luminance; - uint8_t temp[3]; - const uint8_t *p = src; - int rgb_left_endpoint_count = 0; - int alpha_left_endpoint_count = 0; - int y, x, i; - - memset(sums, 0, sizeof sums); - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - luminance = p[0] + p[1] + p[2]; - if (luminance < average_luminance) { - endpoint = 0; - rgb_left_endpoint_count++; - } else { - endpoint = 1; - } - for (i = 0; i < 3; i++) - sums[endpoint][i] += p[i]; - - if (p[2] < average_alpha) { - endpoint = 0; - alpha_left_endpoint_count++; - } else { - endpoint = 1; - } - sums[endpoint][3] += p[3]; - - p += 4; - } - - p += src_rowstride - width * 4; - } - - if (rgb_left_endpoint_count == 0 || - rgb_left_endpoint_count == width * height) { - for (i = 0; i < 3; i++) - endpoints[0][i] = endpoints[1][i] = - (sums[0][i] + sums[1][i]) / (width * height); - } else { - for (i = 0; i < 3; i++) { - endpoints[0][i] = sums[0][i] / rgb_left_endpoint_count; - endpoints[1][i] = (sums[1][i] / - (width * height - rgb_left_endpoint_count)); - } - } - - if (alpha_left_endpoint_count == 0 || - alpha_left_endpoint_count == width * height) { - endpoints[0][3] = endpoints[1][3] = - (sums[0][3] + sums[1][3]) / (width * height); - } else { - endpoints[0][3] = sums[0][3] / alpha_left_endpoint_count; - endpoints[1][3] = (sums[1][3] / - (width * height - alpha_left_endpoint_count)); - } - - /* We may need to swap the endpoints to ensure the most-significant bit of - * the first index is zero */ - - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoint_luminances[endpoint] = - endpoints[endpoint][0] + - endpoints[endpoint][1] + - endpoints[endpoint][2]; - } - midpoint = (endpoint_luminances[0] + endpoint_luminances[1]) / 2; - - if ((src[0] + src[1] + src[2] <= midpoint) != - (endpoint_luminances[0] <= midpoint)) { - memcpy(temp, endpoints[0], 3); - memcpy(endpoints[0], endpoints[1], 3); - memcpy(endpoints[1], temp, 3); - } - - /* Same for the alpha endpoints */ - - midpoint = (endpoints[0][3] + endpoints[1][3]) / 2; - - if ((src[3] <= midpoint) != (endpoints[0][3] <= midpoint)) { - temp[0] = endpoints[0][3]; - endpoints[0][3] = endpoints[1][3]; - endpoints[1][3] = temp[0]; - } -} - -static void -write_rgb_indices_unorm(struct bit_writer *writer, - int src_width, int src_height, - const uint8_t *src, int src_rowstride, - uint8_t endpoints[][4]) -{ - int luminance; - int endpoint_luminances[2]; - int endpoint; - int index; - int y, x; - - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoint_luminances[endpoint] = - endpoints[endpoint][0] + - endpoints[endpoint][1] + - endpoints[endpoint][2]; - } - - /* If the endpoints have the same luminance then we'll just use index 0 for - * all of the texels */ - if (endpoint_luminances[0] == endpoint_luminances[1]) { - write_bits(writer, BLOCK_SIZE * BLOCK_SIZE * 2 - 1, 0); - return; - } - - for (y = 0; y < src_height; y++) { - for (x = 0; x < src_width; x++) { - luminance = src[0] + src[1] + src[2]; - - index = ((luminance - endpoint_luminances[0]) * 3 / - (endpoint_luminances[1] - endpoint_luminances[0])); - if (index < 0) - index = 0; - else if (index > 3) - index = 3; - - assert(x != 0 || y != 0 || index < 2); - - write_bits(writer, (x == 0 && y == 0) ? 1 : 2, index); - - src += 4; - } - - /* Pad the indices out to the block size */ - if (src_width < BLOCK_SIZE) - write_bits(writer, 2 * (BLOCK_SIZE - src_width), 0); - - src += src_rowstride - src_width * 4; - } - - /* Pad the indices out to the block size */ - if (src_height < BLOCK_SIZE) - write_bits(writer, 2 * BLOCK_SIZE * (BLOCK_SIZE - src_height), 0); -} - -static void -write_alpha_indices_unorm(struct bit_writer *writer, - int src_width, int src_height, - const uint8_t *src, int src_rowstride, - uint8_t endpoints[][4]) -{ - int index; - int y, x; - - /* If the endpoints have the same alpha then we'll just use index 0 for - * all of the texels */ - if (endpoints[0][3] == endpoints[1][3]) { - write_bits(writer, BLOCK_SIZE * BLOCK_SIZE * 3 - 1, 0); - return; - } - - for (y = 0; y < src_height; y++) { - for (x = 0; x < src_width; x++) { - index = (((int) src[3] - (int) endpoints[0][3]) * 7 / - ((int) endpoints[1][3] - endpoints[0][3])); - if (index < 0) - index = 0; - else if (index > 7) - index = 7; - - assert(x != 0 || y != 0 || index < 4); - - /* The first index has one less bit */ - write_bits(writer, (x == 0 && y == 0) ? 2 : 3, index); - - src += 4; - } - - /* Pad the indices out to the block size */ - if (src_width < BLOCK_SIZE) - write_bits(writer, 3 * (BLOCK_SIZE - src_width), 0); - - src += src_rowstride - src_width * 4; - } - - /* Pad the indices out to the block size */ - if (src_height < BLOCK_SIZE) - write_bits(writer, 3 * BLOCK_SIZE * (BLOCK_SIZE - src_height), 0); -} - -static void -compress_rgba_unorm_block(int src_width, int src_height, - const uint8_t *src, int src_rowstride, - uint8_t *dst) -{ - int average_luminance, average_alpha; - uint8_t endpoints[2][4]; - struct bit_writer writer; - int component, endpoint; - - get_average_luminance_alpha_unorm(src_width, src_height, src, src_rowstride, - &average_luminance, &average_alpha); - get_rgba_endpoints_unorm(src_width, src_height, src, src_rowstride, - average_luminance, average_alpha, - endpoints); - - writer.dst = dst; - writer.pos = 0; - writer.buf = 0; - - write_bits(&writer, 5, 0x10); /* mode 4 */ - write_bits(&writer, 2, 0); /* rotation 0 */ - write_bits(&writer, 1, 0); /* index selection bit */ - - /* Write the color endpoints */ - for (component = 0; component < 3; component++) - for (endpoint = 0; endpoint < 2; endpoint++) - write_bits(&writer, 5, endpoints[endpoint][component] >> 3); - - /* Write the alpha endpoints */ - for (endpoint = 0; endpoint < 2; endpoint++) - write_bits(&writer, 6, endpoints[endpoint][3] >> 2); - - write_rgb_indices_unorm(&writer, - src_width, src_height, - src, src_rowstride, - endpoints); - write_alpha_indices_unorm(&writer, - src_width, src_height, - src, src_rowstride, - endpoints); -} - -static void -compress_rgba_unorm(int width, int height, - const uint8_t *src, int src_rowstride, - uint8_t *dst, int dst_rowstride) -{ - int dst_row_diff; - int y, x; - - if (dst_rowstride >= width * 4) - dst_row_diff = dst_rowstride - ((width + 3) & ~3) * 4; - else - dst_row_diff = 0; - - for (y = 0; y < height; y += BLOCK_SIZE) { - for (x = 0; x < width; x += BLOCK_SIZE) { - compress_rgba_unorm_block(MIN2(width - x, BLOCK_SIZE), - MIN2(height - y, BLOCK_SIZE), - src + x * 4 + y * src_rowstride, - src_rowstride, - dst); - dst += BLOCK_BYTES; - } - dst += dst_row_diff; - } -} - GLboolean _mesa_texstore_bptc_rgba_unorm(TEXSTORE_PARAMS) { @@ -1317,272 +167,6 @@ _mesa_texstore_bptc_rgba_unorm(TEXSTORE_PARAMS) return GL_TRUE; } -static float -get_average_luminance_float(int width, int height, - const float *src, int src_rowstride) -{ - float luminance_sum = 0; - int y, x; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - luminance_sum += src[0] + src[1] + src[2]; - src += 3; - } - src += (src_rowstride - width * 3 * sizeof (float)) / sizeof (float); - } - - return luminance_sum / (width * height); -} - -static float -clamp_value(float value, bool is_signed) -{ - if (value > 65504.0f) - return 65504.0f; - - if (is_signed) { - if (value < -65504.0f) - return -65504.0f; - else - return value; - } - - if (value < 0.0f) - return 0.0f; - - return value; -} - -static void -get_endpoints_float(int width, int height, - const float *src, int src_rowstride, - float average_luminance, float endpoints[][3], - bool is_signed) -{ - float endpoint_luminances[2]; - float midpoint; - float sums[2][3]; - int endpoint, component; - float luminance; - float temp[3]; - const float *p = src; - int left_endpoint_count = 0; - int y, x, i; - - memset(sums, 0, sizeof sums); - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - luminance = p[0] + p[1] + p[2]; - if (luminance < average_luminance) { - endpoint = 0; - left_endpoint_count++; - } else { - endpoint = 1; - } - for (i = 0; i < 3; i++) - sums[endpoint][i] += p[i]; - - p += 3; - } - - p += (src_rowstride - width * 3 * sizeof (float)) / sizeof (float); - } - - if (left_endpoint_count == 0 || - left_endpoint_count == width * height) { - for (i = 0; i < 3; i++) - endpoints[0][i] = endpoints[1][i] = - (sums[0][i] + sums[1][i]) / (width * height); - } else { - for (i = 0; i < 3; i++) { - endpoints[0][i] = sums[0][i] / left_endpoint_count; - endpoints[1][i] = sums[1][i] / (width * height - left_endpoint_count); - } - } - - /* Clamp the endpoints to the range of a half float and strip out - * infinities */ - for (endpoint = 0; endpoint < 2; endpoint++) { - for (component = 0; component < 3; component++) { - endpoints[endpoint][component] = - clamp_value(endpoints[endpoint][component], is_signed); - } - } - - /* We may need to swap the endpoints to ensure the most-significant bit of - * the first index is zero */ - - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoint_luminances[endpoint] = - endpoints[endpoint][0] + - endpoints[endpoint][1] + - endpoints[endpoint][2]; - } - midpoint = (endpoint_luminances[0] + endpoint_luminances[1]) / 2.0f; - - if ((src[0] + src[1] + src[2] <= midpoint) != - (endpoint_luminances[0] <= midpoint)) { - memcpy(temp, endpoints[0], sizeof temp); - memcpy(endpoints[0], endpoints[1], sizeof temp); - memcpy(endpoints[1], temp, sizeof temp); - } -} - -static void -write_rgb_indices_float(struct bit_writer *writer, - int src_width, int src_height, - const float *src, int src_rowstride, - float endpoints[][3]) -{ - float luminance; - float endpoint_luminances[2]; - int endpoint; - int index; - int y, x; - - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoint_luminances[endpoint] = - endpoints[endpoint][0] + - endpoints[endpoint][1] + - endpoints[endpoint][2]; - } - - /* If the endpoints have the same luminance then we'll just use index 0 for - * all of the texels */ - if (endpoint_luminances[0] == endpoint_luminances[1]) { - write_bits(writer, BLOCK_SIZE * BLOCK_SIZE * 4 - 1, 0); - return; - } - - for (y = 0; y < src_height; y++) { - for (x = 0; x < src_width; x++) { - luminance = src[0] + src[1] + src[2]; - - index = ((luminance - endpoint_luminances[0]) * 15 / - (endpoint_luminances[1] - endpoint_luminances[0])); - if (index < 0) - index = 0; - else if (index > 15) - index = 15; - - assert(x != 0 || y != 0 || index < 8); - - write_bits(writer, (x == 0 && y == 0) ? 3 : 4, index); - - src += 3; - } - - /* Pad the indices out to the block size */ - if (src_width < BLOCK_SIZE) - write_bits(writer, 4 * (BLOCK_SIZE - src_width), 0); - - src += (src_rowstride - src_width * 3 * sizeof (float)) / sizeof (float); - } - - /* Pad the indices out to the block size */ - if (src_height < BLOCK_SIZE) - write_bits(writer, 4 * BLOCK_SIZE * (BLOCK_SIZE - src_height), 0); -} - -static int -get_endpoint_value(float value, bool is_signed) -{ - bool sign = false; - int half; - - if (is_signed) { - half = _mesa_float_to_half(value); - - if (half & 0x8000) { - half &= 0x7fff; - sign = true; - } - - half = (32 * half / 31) >> 6; - - if (sign) - half = -half & ((1 << 10) - 1); - - return half; - } else { - if (value <= 0.0f) - return 0; - - half = _mesa_float_to_half(value); - - return (64 * half / 31) >> 6; - } -} - -static void -compress_rgb_float_block(int src_width, int src_height, - const float *src, int src_rowstride, - uint8_t *dst, - bool is_signed) -{ - float average_luminance; - float endpoints[2][3]; - struct bit_writer writer; - int component, endpoint; - int endpoint_value; - - average_luminance = - get_average_luminance_float(src_width, src_height, src, src_rowstride); - get_endpoints_float(src_width, src_height, src, src_rowstride, - average_luminance, endpoints, is_signed); - - writer.dst = dst; - writer.pos = 0; - writer.buf = 0; - - write_bits(&writer, 5, 3); /* mode 3 */ - - /* Write the endpoints */ - for (endpoint = 0; endpoint < 2; endpoint++) { - for (component = 0; component < 3; component++) { - endpoint_value = - get_endpoint_value(endpoints[endpoint][component], is_signed); - write_bits(&writer, 10, endpoint_value); - } - } - - write_rgb_indices_float(&writer, - src_width, src_height, - src, src_rowstride, - endpoints); -} - -static void -compress_rgb_float(int width, int height, - const float *src, int src_rowstride, - uint8_t *dst, int dst_rowstride, - bool is_signed) -{ - int dst_row_diff; - int y, x; - - if (dst_rowstride >= width * 4) - dst_row_diff = dst_rowstride - ((width + 3) & ~3) * 4; - else - dst_row_diff = 0; - - for (y = 0; y < height; y += BLOCK_SIZE) { - for (x = 0; x < width; x += BLOCK_SIZE) { - compress_rgb_float_block(MIN2(width - x, BLOCK_SIZE), - MIN2(height - y, BLOCK_SIZE), - src + x * 3 + - y * src_rowstride / sizeof (float), - src_rowstride, - dst, - is_signed); - dst += BLOCK_BYTES; - } - dst += dst_row_diff; - } -} - static GLboolean texstore_bptc_rgb_float(TEXSTORE_PARAMS, bool is_signed) diff --git a/lib/mesa/src/mesa/main/texcompress_bptc_tmp.h b/lib/mesa/src/mesa/main/texcompress_bptc_tmp.h new file mode 100644 index 000000000..90837d6af --- /dev/null +++ b/lib/mesa/src/mesa/main/texcompress_bptc_tmp.h @@ -0,0 +1,1748 @@ +/* + * Copyright (C) 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* + * Included by texcompress_bptc and gallium to define BPTC decoding routines. + */ + +#ifndef TEXCOMPRESS_BPTC_TMP_H +#define TEXCOMPRESS_BPTC_TMP_H + +#include "util/format_srgb.h" +#include "util/half_float.h" +#include "macros.h" + +#define BLOCK_SIZE 4 +#define N_PARTITIONS 64 +#define BLOCK_BYTES 16 + +struct bptc_unorm_mode { + int n_subsets; + int n_partition_bits; + bool has_rotation_bits; + bool has_index_selection_bit; + int n_color_bits; + int n_alpha_bits; + bool has_endpoint_pbits; + bool has_shared_pbits; + int n_index_bits; + int n_secondary_index_bits; +}; + +struct bptc_float_bitfield { + int8_t endpoint; + uint8_t component; + uint8_t offset; + uint8_t n_bits; + bool reverse; +}; + +struct bptc_float_mode { + bool reserved; + bool transformed_endpoints; + int n_partition_bits; + int n_endpoint_bits; + int n_index_bits; + int n_delta_bits[3]; + struct bptc_float_bitfield bitfields[24]; +}; + +struct bit_writer { + uint8_t buf; + int pos; + uint8_t *dst; +}; + +static const struct bptc_unorm_mode +bptc_unorm_modes[] = { + /* 0 */ { 3, 4, false, false, 4, 0, true, false, 3, 0 }, + /* 1 */ { 2, 6, false, false, 6, 0, false, true, 3, 0 }, + /* 2 */ { 3, 6, false, false, 5, 0, false, false, 2, 0 }, + /* 3 */ { 2, 6, false, false, 7, 0, true, false, 2, 0 }, + /* 4 */ { 1, 0, true, true, 5, 6, false, false, 2, 3 }, + /* 5 */ { 1, 0, true, false, 7, 8, false, false, 2, 2 }, + /* 6 */ { 1, 0, false, false, 7, 7, true, false, 4, 0 }, + /* 7 */ { 2, 6, false, false, 5, 5, true, false, 2, 0 } +}; + +static const struct bptc_float_mode +bptc_float_modes[] = { + /* 00 */ + { false, true, 5, 10, 3, { 5, 5, 5 }, + { { 2, 1, 4, 1, false }, { 2, 2, 4, 1, false }, { 3, 2, 4, 1, false }, + { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, + { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, + { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, + { 1, 2, 0, 5, false }, { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, + { 2, 0, 0, 5, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, + { 3, 2, 3, 1, false }, + { -1 } } + }, + /* 01 */ + { false, true, 5, 7, 3, { 6, 6, 6 }, + { { 2, 1, 5, 1, false }, { 3, 1, 4, 1, false }, { 3, 1, 5, 1, false }, + { 0, 0, 0, 7, false }, { 3, 2, 0, 1, false }, { 3, 2, 1, 1, false }, + { 2, 2, 4, 1, false }, { 0, 1, 0, 7, false }, { 2, 2, 5, 1, false }, + { 3, 2, 2, 1, false }, { 2, 1, 4, 1, false }, { 0, 2, 0, 7, false }, + { 3, 2, 3, 1, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false }, + { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 6, false }, + { 3, 1, 0, 4, false }, { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, + { 2, 0, 0, 6, false }, + { 3, 0, 0, 6, false }, + { -1 } } + }, + /* 00010 */ + { false, true, 5, 11, 3, { 5, 4, 4 }, + { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, + { 1, 0, 0, 5, false }, { 0, 0, 10, 1, false }, { 2, 1, 0, 4, false }, + { 1, 1, 0, 4, false }, { 0, 1, 10, 1, false }, { 3, 2, 0, 1, false }, + { 3, 1, 0, 4, false }, { 1, 2, 0, 4, false }, { 0, 2, 10, 1, false }, + { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false }, + { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false }, + { -1 } } + }, + /* 00011 */ + { false, false, 0, 10, 4, { 10, 10, 10 }, + { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, + { 1, 0, 0, 10, false }, { 1, 1, 0, 10, false }, { 1, 2, 0, 10, false }, + { -1 } } + }, + /* 00110 */ + { false, true, 5, 11, 3, { 4, 5, 4 }, + { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, + { 1, 0, 0, 4, false }, { 0, 0, 10, 1, false }, { 3, 1, 4, 1, false }, + { 2, 1, 0, 4, false }, { 1, 1, 0, 5, false }, { 0, 1, 10, 1, false }, + { 3, 1, 0, 4, false }, { 1, 2, 0, 4, false }, { 0, 2, 10, 1, false }, + { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 4, false }, + { 3, 2, 0, 1, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 4, false }, + { 2, 1, 4, 1, false }, { 3, 2, 3, 1, false }, + { -1 } } + }, + /* 00111 */ + { false, true, 0, 11, 4, { 9, 9, 9 }, + { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, + { 1, 0, 0, 9, false }, { 0, 0, 10, 1, false }, { 1, 1, 0, 9, false }, + { 0, 1, 10, 1, false }, { 1, 2, 0, 9, false }, { 0, 2, 10, 1, false }, + { -1 } } + }, + /* 01010 */ + { false, true, 5, 11, 3, { 4, 4, 5 }, + { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, + { 1, 0, 0, 4, false }, { 0, 0, 10, 1, false }, { 2, 2, 4, 1, false }, + { 2, 1, 0, 4, false }, { 1, 1, 0, 4, false }, { 0, 1, 10, 1, false }, + { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false }, + { 0, 2, 10, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 4, false }, + { 3, 2, 1, 1, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 4, false }, + { 3, 2, 4, 1, false }, { 3, 2, 3, 1, false }, + { -1 } } + }, + /* 01011 */ + { false, true, 0, 12, 4, { 8, 8, 8 }, + { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, + { 1, 0, 0, 8, false }, { 0, 0, 10, 2, true }, { 1, 1, 0, 8, false }, + { 0, 1, 10, 2, true }, { 1, 2, 0, 8, false }, { 0, 2, 10, 2, true }, + { -1 } } + }, + /* 01110 */ + { false, true, 5, 9, 3, { 5, 5, 5 }, + { { 0, 0, 0, 9, false }, { 2, 2, 4, 1, false }, { 0, 1, 0, 9, false }, + { 2, 1, 4, 1, false }, { 0, 2, 0, 9, false }, { 3, 2, 4, 1, false }, + { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, + { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, + { 1, 2, 0, 5, false }, { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, + { 2, 0, 0, 5, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, + { 3, 2, 3, 1, false }, + { -1 } } + }, + /* 01111 */ + { false, true, 0, 16, 4, { 4, 4, 4 }, + { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, + { 1, 0, 0, 4, false }, { 0, 0, 10, 6, true }, { 1, 1, 0, 4, false }, + { 0, 1, 10, 6, true }, { 1, 2, 0, 4, false }, { 0, 2, 10, 6, true }, + { -1 } } + }, + /* 10010 */ + { false, true, 5, 8, 3, { 6, 5, 5 }, + { { 0, 0, 0, 8, false }, { 3, 1, 4, 1, false }, { 2, 2, 4, 1, false }, + { 0, 1, 0, 8, false }, { 3, 2, 2, 1, false }, { 2, 1, 4, 1, false }, + { 0, 2, 0, 8, false }, { 3, 2, 3, 1, false }, { 3, 2, 4, 1, false }, + { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 5, false }, + { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false }, + { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 6, false }, + { 3, 0, 0, 6, false }, + { -1 } } + }, + /* 10011 */ + { true /* reserved */ }, + /* 10110 */ + { false, true, 5, 8, 3, { 5, 6, 5 }, + { { 0, 0, 0, 8, false }, { 3, 2, 0, 1, false }, { 2, 2, 4, 1, false }, + { 0, 1, 0, 8, false }, { 2, 1, 5, 1, false }, { 2, 1, 4, 1, false }, + { 0, 2, 0, 8, false }, { 3, 1, 5, 1, false }, { 3, 2, 4, 1, false }, + { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, + { 1, 1, 0, 6, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false }, + { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false }, + { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false }, + { -1 } } + }, + /* 10111 */ + { true /* reserved */ }, + /* 11010 */ + { false, true, 5, 8, 3, { 5, 5, 6 }, + { { 0, 0, 0, 8, false }, { 3, 2, 1, 1, false }, { 2, 2, 4, 1, false }, + { 0, 1, 0, 8, false }, { 2, 2, 5, 1, false }, { 2, 1, 4, 1, false }, + { 0, 2, 0, 8, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false }, + { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, + { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, + { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false }, + { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false }, + { -1 } } + }, + /* 11011 */ + { true /* reserved */ }, + /* 11110 */ + { false, false, 5, 6, 3, { 6, 6, 6 }, + { { 0, 0, 0, 6, false }, { 3, 1, 4, 1, false }, { 3, 2, 0, 1, false }, + { 3, 2, 1, 1, false }, { 2, 2, 4, 1, false }, { 0, 1, 0, 6, false }, + { 2, 1, 5, 1, false }, { 2, 2, 5, 1, false }, { 3, 2, 2, 1, false }, + { 2, 1, 4, 1, false }, { 0, 2, 0, 6, false }, { 3, 1, 5, 1, false }, + { 3, 2, 3, 1, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false }, + { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 6, false }, + { 3, 1, 0, 4, false }, { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, + { 2, 0, 0, 6, false }, { 3, 0, 0, 6, false }, + { -1 } } + }, + /* 11111 */ + { true /* reserved */ }, +}; + +/* This partition table is used when the mode has two subsets. Each + * partition is represented by a 32-bit value which gives 2 bits per texel + * within the block. The value of the two bits represents which subset to use + * (0 or 1). + */ +static const uint32_t +partition_table1[N_PARTITIONS] = { + 0x50505050U, 0x40404040U, 0x54545454U, 0x54505040U, + 0x50404000U, 0x55545450U, 0x55545040U, 0x54504000U, + 0x50400000U, 0x55555450U, 0x55544000U, 0x54400000U, + 0x55555440U, 0x55550000U, 0x55555500U, 0x55000000U, + 0x55150100U, 0x00004054U, 0x15010000U, 0x00405054U, + 0x00004050U, 0x15050100U, 0x05010000U, 0x40505054U, + 0x00404050U, 0x05010100U, 0x14141414U, 0x05141450U, + 0x01155440U, 0x00555500U, 0x15014054U, 0x05414150U, + 0x44444444U, 0x55005500U, 0x11441144U, 0x05055050U, + 0x05500550U, 0x11114444U, 0x41144114U, 0x44111144U, + 0x15055054U, 0x01055040U, 0x05041050U, 0x05455150U, + 0x14414114U, 0x50050550U, 0x41411414U, 0x00141400U, + 0x00041504U, 0x00105410U, 0x10541000U, 0x04150400U, + 0x50410514U, 0x41051450U, 0x05415014U, 0x14054150U, + 0x41050514U, 0x41505014U, 0x40011554U, 0x54150140U, + 0x50505500U, 0x00555050U, 0x15151010U, 0x54540404U, +}; + +/* This partition table is used when the mode has three subsets. In this case + * the values can be 0, 1 or 2. + */ +static const uint32_t +partition_table2[N_PARTITIONS] = { + 0xaa685050U, 0x6a5a5040U, 0x5a5a4200U, 0x5450a0a8U, + 0xa5a50000U, 0xa0a05050U, 0x5555a0a0U, 0x5a5a5050U, + 0xaa550000U, 0xaa555500U, 0xaaaa5500U, 0x90909090U, + 0x94949494U, 0xa4a4a4a4U, 0xa9a59450U, 0x2a0a4250U, + 0xa5945040U, 0x0a425054U, 0xa5a5a500U, 0x55a0a0a0U, + 0xa8a85454U, 0x6a6a4040U, 0xa4a45000U, 0x1a1a0500U, + 0x0050a4a4U, 0xaaa59090U, 0x14696914U, 0x69691400U, + 0xa08585a0U, 0xaa821414U, 0x50a4a450U, 0x6a5a0200U, + 0xa9a58000U, 0x5090a0a8U, 0xa8a09050U, 0x24242424U, + 0x00aa5500U, 0x24924924U, 0x24499224U, 0x50a50a50U, + 0x500aa550U, 0xaaaa4444U, 0x66660000U, 0xa5a0a5a0U, + 0x50a050a0U, 0x69286928U, 0x44aaaa44U, 0x66666600U, + 0xaa444444U, 0x54a854a8U, 0x95809580U, 0x96969600U, + 0xa85454a8U, 0x80959580U, 0xaa141414U, 0x96960000U, + 0xaaaa1414U, 0xa05050a0U, 0xa0a5a5a0U, 0x96000000U, + 0x40804080U, 0xa9a8a9a8U, 0xaaaaaa44U, 0x2a4a5254U +}; + +static const uint8_t +anchor_indices[][N_PARTITIONS] = { + /* Anchor index values for the second subset of two-subset partitioning */ + { + 0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf, + 0xf,0x2,0x8,0x2,0x2,0x8,0x8,0xf,0x2,0x8,0x2,0x2,0x8,0x8,0x2,0x2, + 0xf,0xf,0x6,0x8,0x2,0x8,0xf,0xf,0x2,0x8,0x2,0x2,0x2,0xf,0xf,0x6, + 0x6,0x2,0x6,0x8,0xf,0xf,0x2,0x2,0xf,0xf,0xf,0xf,0xf,0x2,0x2,0xf + }, + + /* Anchor index values for the second subset of three-subset partitioning */ + { + 0x3,0x3,0xf,0xf,0x8,0x3,0xf,0xf,0x8,0x8,0x6,0x6,0x6,0x5,0x3,0x3, + 0x3,0x3,0x8,0xf,0x3,0x3,0x6,0xa,0x5,0x8,0x8,0x6,0x8,0x5,0xf,0xf, + 0x8,0xf,0x3,0x5,0x6,0xa,0x8,0xf,0xf,0x3,0xf,0x5,0xf,0xf,0xf,0xf, + 0x3,0xf,0x5,0x5,0x5,0x8,0x5,0xa,0x5,0xa,0x8,0xd,0xf,0xc,0x3,0x3 + }, + + /* Anchor index values for the third subset of three-subset + * partitioning + */ + { + 0xf,0x8,0x8,0x3,0xf,0xf,0x3,0x8,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x8, + 0xf,0x8,0xf,0x3,0xf,0x8,0xf,0x8,0x3,0xf,0x6,0xa,0xf,0xf,0xa,0x8, + 0xf,0x3,0xf,0xa,0xa,0x8,0x9,0xa,0x6,0xf,0x8,0xf,0x3,0x6,0x6,0x8, + 0xf,0x3,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x3,0xf,0xf,0x8 + } +}; + +static int +extract_bits(const uint8_t *block, + int offset, + int n_bits) +{ + int byte_index = offset / 8; + int bit_index = offset % 8; + int n_bits_in_byte = MIN2(n_bits, 8 - bit_index); + int result = 0; + int bit = 0; + + while (true) { + result |= ((block[byte_index] >> bit_index) & + ((1 << n_bits_in_byte) - 1)) << bit; + + n_bits -= n_bits_in_byte; + + if (n_bits <= 0) + return result; + + bit += n_bits_in_byte; + byte_index++; + bit_index = 0; + n_bits_in_byte = MIN2(n_bits, 8); + } +} + +static uint8_t +expand_component(uint8_t byte, + int n_bits) +{ + /* Expands a n-bit quantity into a byte by copying the most-significant + * bits into the unused least-significant bits. + */ + return byte << (8 - n_bits) | (byte >> (2 * n_bits - 8)); +} + +static int +extract_unorm_endpoints(const struct bptc_unorm_mode *mode, + const uint8_t *block, + int bit_offset, + uint8_t endpoints[][4]) +{ + int component; + int subset; + int endpoint; + int pbit; + int n_components; + + /* Extract each color component */ + for (component = 0; component < 3; component++) { + for (subset = 0; subset < mode->n_subsets; subset++) { + for (endpoint = 0; endpoint < 2; endpoint++) { + endpoints[subset * 2 + endpoint][component] = + extract_bits(block, bit_offset, mode->n_color_bits); + bit_offset += mode->n_color_bits; + } + } + } + + /* Extract the alpha values */ + if (mode->n_alpha_bits > 0) { + for (subset = 0; subset < mode->n_subsets; subset++) { + for (endpoint = 0; endpoint < 2; endpoint++) { + endpoints[subset * 2 + endpoint][3] = + extract_bits(block, bit_offset, mode->n_alpha_bits); + bit_offset += mode->n_alpha_bits; + } + } + + n_components = 4; + } else { + for (subset = 0; subset < mode->n_subsets; subset++) + for (endpoint = 0; endpoint < 2; endpoint++) + endpoints[subset * 2 + endpoint][3] = 255; + + n_components = 3; + } + + /* Add in the p-bits */ + if (mode->has_endpoint_pbits) { + for (subset = 0; subset < mode->n_subsets; subset++) { + for (endpoint = 0; endpoint < 2; endpoint++) { + pbit = extract_bits(block, bit_offset, 1); + bit_offset += 1; + + for (component = 0; component < n_components; component++) { + endpoints[subset * 2 + endpoint][component] <<= 1; + endpoints[subset * 2 + endpoint][component] |= pbit; + } + } + } + } else if (mode->has_shared_pbits) { + for (subset = 0; subset < mode->n_subsets; subset++) { + pbit = extract_bits(block, bit_offset, 1); + bit_offset += 1; + + for (endpoint = 0; endpoint < 2; endpoint++) { + for (component = 0; component < n_components; component++) { + endpoints[subset * 2 + endpoint][component] <<= 1; + endpoints[subset * 2 + endpoint][component] |= pbit; + } + } + } + } + + /* Expand the n-bit values to a byte */ + for (subset = 0; subset < mode->n_subsets; subset++) { + for (endpoint = 0; endpoint < 2; endpoint++) { + for (component = 0; component < 3; component++) { + endpoints[subset * 2 + endpoint][component] = + expand_component(endpoints[subset * 2 + endpoint][component], + mode->n_color_bits + + mode->has_endpoint_pbits + + mode->has_shared_pbits); + } + + if (mode->n_alpha_bits > 0) { + endpoints[subset * 2 + endpoint][3] = + expand_component(endpoints[subset * 2 + endpoint][3], + mode->n_alpha_bits + + mode->has_endpoint_pbits + + mode->has_shared_pbits); + } + } + } + + return bit_offset; +} + +static bool +is_anchor(int n_subsets, + int partition_num, + int texel) +{ + if (texel == 0) + return true; + + switch (n_subsets) { + case 1: + return false; + case 2: + return anchor_indices[0][partition_num] == texel; + case 3: + return (anchor_indices[1][partition_num] == texel || + anchor_indices[2][partition_num] == texel); + default: + assert(false); + return false; + } +} + +static int +count_anchors_before_texel(int n_subsets, + int partition_num, + int texel) +{ + int count = 1; + + if (texel == 0) + return 0; + + switch (n_subsets) { + case 1: + break; + case 2: + if (texel > anchor_indices[0][partition_num]) + count++; + break; + case 3: + if (texel > anchor_indices[1][partition_num]) + count++; + if (texel > anchor_indices[2][partition_num]) + count++; + break; + default: + assert(false); + return 0; + } + + return count; +} + +static int32_t +interpolate(int32_t a, int32_t b, + int index, + int index_bits) +{ + static const uint8_t weights2[] = { 0, 21, 43, 64 }; + static const uint8_t weights3[] = { 0, 9, 18, 27, 37, 46, 55, 64 }; + static const uint8_t weights4[] = + { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; + static const uint8_t *weights[] = { + NULL, NULL, weights2, weights3, weights4 + }; + int weight; + + weight = weights[index_bits][index]; + + return ((64 - weight) * a + weight * b + 32) >> 6; +} + +static void +apply_rotation(int rotation, + uint8_t *result) +{ + uint8_t t; + + if (rotation == 0) + return; + + rotation--; + + t = result[rotation]; + result[rotation] = result[3]; + result[3] = t; +} + +static void +fetch_rgba_unorm_from_block(const uint8_t *block, + uint8_t *result, + int texel) +{ + int mode_num = ffs(block[0]); + const struct bptc_unorm_mode *mode; + int bit_offset, secondary_bit_offset; + int partition_num; + int subset_num; + int rotation; + int index_selection; + int index_bits; + int indices[2]; + int index; + int anchors_before_texel; + bool anchor; + uint8_t endpoints[3 * 2][4]; + uint32_t subsets; + int component; + + if (mode_num == 0) { + /* According to the spec this mode is reserved and shouldn't be used. */ + memset(result, 0, 3); + result[3] = 0xff; + return; + } + + mode = bptc_unorm_modes + mode_num - 1; + bit_offset = mode_num; + + partition_num = extract_bits(block, bit_offset, mode->n_partition_bits); + bit_offset += mode->n_partition_bits; + + switch (mode->n_subsets) { + case 1: + subsets = 0; + break; + case 2: + subsets = partition_table1[partition_num]; + break; + case 3: + subsets = partition_table2[partition_num]; + break; + default: + assert(false); + return; + } + + if (mode->has_rotation_bits) { + rotation = extract_bits(block, bit_offset, 2); + bit_offset += 2; + } else { + rotation = 0; + } + + if (mode->has_index_selection_bit) { + index_selection = extract_bits(block, bit_offset, 1); + bit_offset++; + } else { + index_selection = 0; + } + + bit_offset = extract_unorm_endpoints(mode, block, bit_offset, endpoints); + + anchors_before_texel = count_anchors_before_texel(mode->n_subsets, + partition_num, texel); + + /* Calculate the offset to the secondary index */ + secondary_bit_offset = (bit_offset + + BLOCK_SIZE * BLOCK_SIZE * mode->n_index_bits - + mode->n_subsets + + mode->n_secondary_index_bits * texel - + anchors_before_texel); + + /* Calculate the offset to the primary index for this texel */ + bit_offset += mode->n_index_bits * texel - anchors_before_texel; + + subset_num = (subsets >> (texel * 2)) & 3; + + anchor = is_anchor(mode->n_subsets, partition_num, texel); + + index_bits = mode->n_index_bits; + if (anchor) + index_bits--; + indices[0] = extract_bits(block, bit_offset, index_bits); + + if (mode->n_secondary_index_bits) { + index_bits = mode->n_secondary_index_bits; + if (anchor) + index_bits--; + indices[1] = extract_bits(block, secondary_bit_offset, index_bits); + } + + index = indices[index_selection]; + index_bits = (index_selection ? + mode->n_secondary_index_bits : + mode->n_index_bits); + + for (component = 0; component < 3; component++) + result[component] = interpolate(endpoints[subset_num * 2][component], + endpoints[subset_num * 2 + 1][component], + index, + index_bits); + + /* Alpha uses the opposite index from the color components */ + if (mode->n_secondary_index_bits && !index_selection) { + index = indices[1]; + index_bits = mode->n_secondary_index_bits; + } else { + index = indices[0]; + index_bits = mode->n_index_bits; + } + + result[3] = interpolate(endpoints[subset_num * 2][3], + endpoints[subset_num * 2 + 1][3], + index, + index_bits); + + apply_rotation(rotation, result); +} + +#ifdef BPTC_BLOCK_DECODE +static void +decompress_rgba_unorm_block(int src_width, int src_height, + const uint8_t *block, + uint8_t *dst_row, int dst_rowstride) +{ + int mode_num = ffs(block[0]); + const struct bptc_unorm_mode *mode; + int bit_offset, secondary_bit_offset; + int partition_num; + int subset_num; + int rotation; + int index_selection; + int index_bits; + int indices[2]; + int index; + int anchors_before_texel; + bool anchor; + uint8_t endpoints[3 * 2][4]; + uint32_t subsets; + int component; + unsigned x, y; + + if (mode_num == 0) { + /* According to the spec this mode is reserved and shouldn't be used. */ + for(y = 0; y < src_height; y += 1) { + uint8_t *result = dst_row; + memset(result, 0, 4 * src_width); + for(x = 0; x < src_width; x += 1) { + result[3] = 0xff; + result += 4; + } + dst_row += dst_rowstride; + } + return; + } + + mode = bptc_unorm_modes + mode_num - 1; + bit_offset = mode_num; + + partition_num = extract_bits(block, bit_offset, mode->n_partition_bits); + bit_offset += mode->n_partition_bits; + + switch (mode->n_subsets) { + case 1: + subsets = 0; + break; + case 2: + subsets = partition_table1[partition_num]; + break; + case 3: + subsets = partition_table2[partition_num]; + break; + default: + assert(false); + return; + } + + if (mode->has_rotation_bits) { + rotation = extract_bits(block, bit_offset, 2); + bit_offset += 2; + } else { + rotation = 0; + } + + if (mode->has_index_selection_bit) { + index_selection = extract_bits(block, bit_offset, 1); + bit_offset++; + } else { + index_selection = 0; + } + + bit_offset = extract_unorm_endpoints(mode, block, bit_offset, endpoints); + + for(y = 0; y < src_height; y += 1) { + uint8_t *result = dst_row; + for(x = 0; x < src_width; x += 1) { + int texel; + texel = x + y * 4; + + anchors_before_texel = count_anchors_before_texel(mode->n_subsets, + partition_num, + texel); + + /* Calculate the offset to the secondary index */ + secondary_bit_offset = (bit_offset + + BLOCK_SIZE * BLOCK_SIZE * mode->n_index_bits - + mode->n_subsets + + mode->n_secondary_index_bits * texel - + anchors_before_texel); + + /* Calculate the offset to the primary index for this texel */ + bit_offset += mode->n_index_bits * texel - anchors_before_texel; + + subset_num = (subsets >> (texel * 2)) & 3; + + anchor = is_anchor(mode->n_subsets, partition_num, texel); + + index_bits = mode->n_index_bits; + if (anchor) + index_bits--; + indices[0] = extract_bits(block, bit_offset, index_bits); + + if (mode->n_secondary_index_bits) { + index_bits = mode->n_secondary_index_bits; + if (anchor) + index_bits--; + indices[1] = extract_bits(block, secondary_bit_offset, index_bits); + } + + index = indices[index_selection]; + index_bits = (index_selection ? + mode->n_secondary_index_bits : + mode->n_index_bits); + + for (component = 0; component < 3; component++) + result[component] = interpolate(endpoints[subset_num * 2][component], + endpoints[subset_num * 2 + 1][component], + index, + index_bits); + + /* Alpha uses the opposite index from the color components */ + if (mode->n_secondary_index_bits && !index_selection) { + index = indices[1]; + index_bits = mode->n_secondary_index_bits; + } else { + index = indices[0]; + index_bits = mode->n_index_bits; + } + + result[3] = interpolate(endpoints[subset_num * 2][3], + endpoints[subset_num * 2 + 1][3], + index, + index_bits); + + apply_rotation(rotation, result); + result += 4; + } + dst_row += dst_rowstride; + } +} + +static void +decompress_rgba_unorm(int width, int height, + const uint8_t *src, int src_rowstride, + uint8_t *dst, int dst_rowstride) +{ + int src_row_diff; + int y, x; + + if (src_rowstride >= width * 4) + src_row_diff = src_rowstride - ((width + 3) & ~3) * 4; + else + src_row_diff = 0; + + for (y = 0; y < height; y += BLOCK_SIZE) { + for (x = 0; x < width; x += BLOCK_SIZE) { + decompress_rgba_unorm_block(MIN2(width - x, BLOCK_SIZE), + MIN2(height - y, BLOCK_SIZE), + src, + dst + x * 4 + y * dst_rowstride, + dst_rowstride); + src += BLOCK_BYTES; + } + src += src_row_diff; + } +} +#endif // BPTC_BLOCK_DECODE + +static int32_t +sign_extend(int32_t value, + int n_bits) +{ + if ((value & (1 << (n_bits - 1)))) { + value |= (~(int32_t) 0) << n_bits; + } + + return value; +} + +static int +signed_unquantize(int value, int n_endpoint_bits) +{ + bool sign; + + if (n_endpoint_bits >= 16) + return value; + + if (value == 0) + return 0; + + sign = false; + + if (value < 0) { + sign = true; + value = -value; + } + + if (value >= (1 << (n_endpoint_bits - 1)) - 1) + value = 0x7fff; + else + value = ((value << 15) + 0x4000) >> (n_endpoint_bits - 1); + + if (sign) + value = -value; + + return value; +} + +static int +unsigned_unquantize(int value, int n_endpoint_bits) +{ + if (n_endpoint_bits >= 15) + return value; + + if (value == 0) + return 0; + + if (value == (1 << n_endpoint_bits) - 1) + return 0xffff; + + return ((value << 15) + 0x4000) >> (n_endpoint_bits - 1); +} + +static int +extract_float_endpoints(const struct bptc_float_mode *mode, + const uint8_t *block, + int bit_offset, + int32_t endpoints[][3], + bool is_signed) +{ + const struct bptc_float_bitfield *bitfield; + int endpoint, component; + int n_endpoints; + int value; + int i; + + if (mode->n_partition_bits) + n_endpoints = 4; + else + n_endpoints = 2; + + memset(endpoints, 0, sizeof endpoints[0][0] * n_endpoints * 3); + + for (bitfield = mode->bitfields; bitfield->endpoint != -1; bitfield++) { + value = extract_bits(block, bit_offset, bitfield->n_bits); + bit_offset += bitfield->n_bits; + + if (bitfield->reverse) { + for (i = 0; i < bitfield->n_bits; i++) { + if (value & (1 << i)) + endpoints[bitfield->endpoint][bitfield->component] |= + 1 << ((bitfield->n_bits - 1 - i) + bitfield->offset); + } + } else { + endpoints[bitfield->endpoint][bitfield->component] |= + value << bitfield->offset; + } + } + + if (mode->transformed_endpoints) { + /* The endpoints are specified as signed offsets from e0 */ + for (endpoint = 1; endpoint < n_endpoints; endpoint++) { + for (component = 0; component < 3; component++) { + value = sign_extend(endpoints[endpoint][component], + mode->n_delta_bits[component]); + endpoints[endpoint][component] = + ((endpoints[0][component] + value) & + ((1 << mode->n_endpoint_bits) - 1)); + } + } + } + + if (is_signed) { + for (endpoint = 0; endpoint < n_endpoints; endpoint++) { + for (component = 0; component < 3; component++) { + value = sign_extend(endpoints[endpoint][component], + mode->n_endpoint_bits); + endpoints[endpoint][component] = + signed_unquantize(value, mode->n_endpoint_bits); + } + } + } else { + for (endpoint = 0; endpoint < n_endpoints; endpoint++) { + for (component = 0; component < 3; component++) { + endpoints[endpoint][component] = + unsigned_unquantize(endpoints[endpoint][component], + mode->n_endpoint_bits); + } + } + } + + return bit_offset; +} + +static int32_t +finish_unsigned_unquantize(int32_t value) +{ + return value * 31 / 64; +} + +static int32_t +finish_signed_unquantize(int32_t value) +{ + if (value < 0) + return (-value * 31 / 32) | 0x8000; + else + return value * 31 / 32; +} + +static void +fetch_rgb_float_from_block(const uint8_t *block, + float *result, + int texel, + bool is_signed) +{ + int mode_num; + const struct bptc_float_mode *mode; + int bit_offset; + int partition_num; + int subset_num; + int index_bits; + int index; + int anchors_before_texel; + int32_t endpoints[2 * 2][3]; + uint32_t subsets; + int n_subsets; + int component; + int32_t value; + + if (block[0] & 0x2) { + mode_num = (((block[0] >> 1) & 0xe) | (block[0] & 1)) + 2; + bit_offset = 5; + } else { + mode_num = block[0] & 3; + bit_offset = 2; + } + + mode = bptc_float_modes + mode_num; + + if (mode->reserved) { + memset(result, 0, sizeof result[0] * 3); + result[3] = 1.0f; + return; + } + + bit_offset = extract_float_endpoints(mode, block, bit_offset, + endpoints, is_signed); + + if (mode->n_partition_bits) { + partition_num = extract_bits(block, bit_offset, mode->n_partition_bits); + bit_offset += mode->n_partition_bits; + + subsets = partition_table1[partition_num]; + n_subsets = 2; + } else { + partition_num = 0; + subsets = 0; + n_subsets = 1; + } + + anchors_before_texel = + count_anchors_before_texel(n_subsets, partition_num, texel); + + /* Calculate the offset to the primary index for this texel */ + bit_offset += mode->n_index_bits * texel - anchors_before_texel; + + subset_num = (subsets >> (texel * 2)) & 3; + + index_bits = mode->n_index_bits; + if (is_anchor(n_subsets, partition_num, texel)) + index_bits--; + index = extract_bits(block, bit_offset, index_bits); + + for (component = 0; component < 3; component++) { + value = interpolate(endpoints[subset_num * 2][component], + endpoints[subset_num * 2 + 1][component], + index, + mode->n_index_bits); + + if (is_signed) + value = finish_signed_unquantize(value); + else + value = finish_unsigned_unquantize(value); + + result[component] = _mesa_half_to_float(value); + } + + result[3] = 1.0f; +} + +#ifdef BPTC_BLOCK_DECODE +static void +decompress_rgb_float_block(unsigned src_width, unsigned src_height, + const uint8_t *block, + float *dst_row, unsigned dst_rowstride, + bool is_signed) +{ + int mode_num; + const struct bptc_float_mode *mode; + int bit_offset; + int partition_num; + int subset_num; + int index_bits; + int index; + int anchors_before_texel; + int32_t endpoints[2 * 2][3]; + uint32_t subsets; + int n_subsets; + int component; + int32_t value; + unsigned x, y; + + if (block[0] & 0x2) { + mode_num = (((block[0] >> 1) & 0xe) | (block[0] & 1)) + 2; + bit_offset = 5; + } else { + mode_num = block[0] & 3; + bit_offset = 2; + } + + mode = bptc_float_modes + mode_num; + + if (mode->reserved) { + for(y = 0; y < src_height; y += 1) { + float *result = dst_row; + memset(result, 0, sizeof result[0] * 4 * src_width); + for(x = 0; x < src_width; x += 1) { + result[3] = 1.0f; + result += 4; + } + dst_row += dst_rowstride / sizeof dst_row[0]; + } + return; + } + + bit_offset = extract_float_endpoints(mode, block, bit_offset, + endpoints, is_signed); + + if (mode->n_partition_bits) { + partition_num = extract_bits(block, bit_offset, mode->n_partition_bits); + bit_offset += mode->n_partition_bits; + + subsets = partition_table1[partition_num]; + n_subsets = 2; + } else { + partition_num = 0; + subsets = 0; + n_subsets = 1; + } + + for(y = 0; y < src_height; y += 1) { + float *result = dst_row; + for(x = 0; x < src_width; x += 1) { + int texel; + + texel = x + y * 4; + + anchors_before_texel = + count_anchors_before_texel(n_subsets, partition_num, texel); + + /* Calculate the offset to the primary index for this texel */ + bit_offset += mode->n_index_bits * texel - anchors_before_texel; + + subset_num = (subsets >> (texel * 2)) & 3; + + index_bits = mode->n_index_bits; + if (is_anchor(n_subsets, partition_num, texel)) + index_bits--; + index = extract_bits(block, bit_offset, index_bits); + + for (component = 0; component < 3; component++) { + value = interpolate(endpoints[subset_num * 2][component], + endpoints[subset_num * 2 + 1][component], + index, + mode->n_index_bits); + + if (is_signed) + value = finish_signed_unquantize(value); + else + value = finish_unsigned_unquantize(value); + + result[component] = _mesa_half_to_float(value); + } + + result[3] = 1.0f; + result += 4; + } + dst_row += dst_rowstride / sizeof dst_row[0]; + } +} + +static void +decompress_rgb_float(int width, int height, + const uint8_t *src, int src_rowstride, + float *dst, int dst_rowstride, bool is_signed) +{ + int src_row_diff; + int y, x; + + if (src_rowstride >= width * 4) + src_row_diff = src_rowstride - ((width + 3) & ~3) * 4; + else + src_row_diff = 0; + + for (y = 0; y < height; y += BLOCK_SIZE) { + for (x = 0; x < width; x += BLOCK_SIZE) { + decompress_rgb_float_block(MIN2(width - x, BLOCK_SIZE), + MIN2(height - y, BLOCK_SIZE), + src, + (dst + x * 4 + + (y * dst_rowstride / sizeof dst[0])), + dst_rowstride, is_signed); + src += BLOCK_BYTES; + } + src += src_row_diff; + } +} +#endif // BPTC_BLOCK_DECODE + +static void +write_bits(struct bit_writer *writer, int n_bits, int value) +{ + do { + if (n_bits + writer->pos >= 8) { + *(writer->dst++) = writer->buf | (value << writer->pos); + writer->buf = 0; + value >>= (8 - writer->pos); + n_bits -= (8 - writer->pos); + writer->pos = 0; + } else { + writer->buf |= value << writer->pos; + writer->pos += n_bits; + break; + } + } while (n_bits > 0); +} + +static void +get_average_luminance_alpha_unorm(int width, int height, + const uint8_t *src, int src_rowstride, + int *average_luminance, int *average_alpha) +{ + int luminance_sum = 0, alpha_sum = 0; + int y, x; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + luminance_sum += src[0] + src[1] + src[2]; + alpha_sum += src[3]; + src += 4; + } + src += src_rowstride - width * 4; + } + + *average_luminance = luminance_sum / (width * height); + *average_alpha = alpha_sum / (width * height); +} + +static void +get_rgba_endpoints_unorm(int width, int height, + const uint8_t *src, int src_rowstride, + int average_luminance, int average_alpha, + uint8_t endpoints[][4]) +{ + int endpoint_luminances[2]; + int midpoint; + int sums[2][4]; + int endpoint; + int luminance; + uint8_t temp[3]; + const uint8_t *p = src; + int rgb_left_endpoint_count = 0; + int alpha_left_endpoint_count = 0; + int y, x, i; + + memset(sums, 0, sizeof sums); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + luminance = p[0] + p[1] + p[2]; + if (luminance < average_luminance) { + endpoint = 0; + rgb_left_endpoint_count++; + } else { + endpoint = 1; + } + for (i = 0; i < 3; i++) + sums[endpoint][i] += p[i]; + + if (p[2] < average_alpha) { + endpoint = 0; + alpha_left_endpoint_count++; + } else { + endpoint = 1; + } + sums[endpoint][3] += p[3]; + + p += 4; + } + + p += src_rowstride - width * 4; + } + + if (rgb_left_endpoint_count == 0 || + rgb_left_endpoint_count == width * height) { + for (i = 0; i < 3; i++) + endpoints[0][i] = endpoints[1][i] = + (sums[0][i] + sums[1][i]) / (width * height); + } else { + for (i = 0; i < 3; i++) { + endpoints[0][i] = sums[0][i] / rgb_left_endpoint_count; + endpoints[1][i] = (sums[1][i] / + (width * height - rgb_left_endpoint_count)); + } + } + + if (alpha_left_endpoint_count == 0 || + alpha_left_endpoint_count == width * height) { + endpoints[0][3] = endpoints[1][3] = + (sums[0][3] + sums[1][3]) / (width * height); + } else { + endpoints[0][3] = sums[0][3] / alpha_left_endpoint_count; + endpoints[1][3] = (sums[1][3] / + (width * height - alpha_left_endpoint_count)); + } + + /* We may need to swap the endpoints to ensure the most-significant bit of + * the first index is zero */ + + for (endpoint = 0; endpoint < 2; endpoint++) { + endpoint_luminances[endpoint] = + endpoints[endpoint][0] + + endpoints[endpoint][1] + + endpoints[endpoint][2]; + } + midpoint = (endpoint_luminances[0] + endpoint_luminances[1]) / 2; + + if ((src[0] + src[1] + src[2] <= midpoint) != + (endpoint_luminances[0] <= midpoint)) { + memcpy(temp, endpoints[0], 3); + memcpy(endpoints[0], endpoints[1], 3); + memcpy(endpoints[1], temp, 3); + } + + /* Same for the alpha endpoints */ + + midpoint = (endpoints[0][3] + endpoints[1][3]) / 2; + + if ((src[3] <= midpoint) != (endpoints[0][3] <= midpoint)) { + temp[0] = endpoints[0][3]; + endpoints[0][3] = endpoints[1][3]; + endpoints[1][3] = temp[0]; + } +} + +static void +write_rgb_indices_unorm(struct bit_writer *writer, + int src_width, int src_height, + const uint8_t *src, int src_rowstride, + uint8_t endpoints[][4]) +{ + int luminance; + int endpoint_luminances[2]; + int endpoint; + int index; + int y, x; + + for (endpoint = 0; endpoint < 2; endpoint++) { + endpoint_luminances[endpoint] = + endpoints[endpoint][0] + + endpoints[endpoint][1] + + endpoints[endpoint][2]; + } + + /* If the endpoints have the same luminance then we'll just use index 0 for + * all of the texels */ + if (endpoint_luminances[0] == endpoint_luminances[1]) { + write_bits(writer, BLOCK_SIZE * BLOCK_SIZE * 2 - 1, 0); + return; + } + + for (y = 0; y < src_height; y++) { + for (x = 0; x < src_width; x++) { + luminance = src[0] + src[1] + src[2]; + + index = ((luminance - endpoint_luminances[0]) * 3 / + (endpoint_luminances[1] - endpoint_luminances[0])); + if (index < 0) + index = 0; + else if (index > 3) + index = 3; + + assert(x != 0 || y != 0 || index < 2); + + write_bits(writer, (x == 0 && y == 0) ? 1 : 2, index); + + src += 4; + } + + /* Pad the indices out to the block size */ + if (src_width < BLOCK_SIZE) + write_bits(writer, 2 * (BLOCK_SIZE - src_width), 0); + + src += src_rowstride - src_width * 4; + } + + /* Pad the indices out to the block size */ + if (src_height < BLOCK_SIZE) + write_bits(writer, 2 * BLOCK_SIZE * (BLOCK_SIZE - src_height), 0); +} + +static void +write_alpha_indices_unorm(struct bit_writer *writer, + int src_width, int src_height, + const uint8_t *src, int src_rowstride, + uint8_t endpoints[][4]) +{ + int index; + int y, x; + + /* If the endpoints have the same alpha then we'll just use index 0 for + * all of the texels */ + if (endpoints[0][3] == endpoints[1][3]) { + write_bits(writer, BLOCK_SIZE * BLOCK_SIZE * 3 - 1, 0); + return; + } + + for (y = 0; y < src_height; y++) { + for (x = 0; x < src_width; x++) { + index = (((int) src[3] - (int) endpoints[0][3]) * 7 / + ((int) endpoints[1][3] - endpoints[0][3])); + if (index < 0) + index = 0; + else if (index > 7) + index = 7; + + assert(x != 0 || y != 0 || index < 4); + + /* The first index has one less bit */ + write_bits(writer, (x == 0 && y == 0) ? 2 : 3, index); + + src += 4; + } + + /* Pad the indices out to the block size */ + if (src_width < BLOCK_SIZE) + write_bits(writer, 3 * (BLOCK_SIZE - src_width), 0); + + src += src_rowstride - src_width * 4; + } + + /* Pad the indices out to the block size */ + if (src_height < BLOCK_SIZE) + write_bits(writer, 3 * BLOCK_SIZE * (BLOCK_SIZE - src_height), 0); +} + +static void +compress_rgba_unorm_block(int src_width, int src_height, + const uint8_t *src, int src_rowstride, + uint8_t *dst) +{ + int average_luminance, average_alpha; + uint8_t endpoints[2][4]; + struct bit_writer writer; + int component, endpoint; + + get_average_luminance_alpha_unorm(src_width, src_height, src, src_rowstride, + &average_luminance, &average_alpha); + get_rgba_endpoints_unorm(src_width, src_height, src, src_rowstride, + average_luminance, average_alpha, + endpoints); + + writer.dst = dst; + writer.pos = 0; + writer.buf = 0; + + write_bits(&writer, 5, 0x10); /* mode 4 */ + write_bits(&writer, 2, 0); /* rotation 0 */ + write_bits(&writer, 1, 0); /* index selection bit */ + + /* Write the color endpoints */ + for (component = 0; component < 3; component++) + for (endpoint = 0; endpoint < 2; endpoint++) + write_bits(&writer, 5, endpoints[endpoint][component] >> 3); + + /* Write the alpha endpoints */ + for (endpoint = 0; endpoint < 2; endpoint++) + write_bits(&writer, 6, endpoints[endpoint][3] >> 2); + + write_rgb_indices_unorm(&writer, + src_width, src_height, + src, src_rowstride, + endpoints); + write_alpha_indices_unorm(&writer, + src_width, src_height, + src, src_rowstride, + endpoints); +} + +static void +compress_rgba_unorm(int width, int height, + const uint8_t *src, int src_rowstride, + uint8_t *dst, int dst_rowstride) +{ + int dst_row_diff; + int y, x; + + if (dst_rowstride >= width * 4) + dst_row_diff = dst_rowstride - ((width + 3) & ~3) * 4; + else + dst_row_diff = 0; + + for (y = 0; y < height; y += BLOCK_SIZE) { + for (x = 0; x < width; x += BLOCK_SIZE) { + compress_rgba_unorm_block(MIN2(width - x, BLOCK_SIZE), + MIN2(height - y, BLOCK_SIZE), + src + x * 4 + y * src_rowstride, + src_rowstride, + dst); + dst += BLOCK_BYTES; + } + dst += dst_row_diff; + } +} + +static float +get_average_luminance_float(int width, int height, + const float *src, int src_rowstride) +{ + float luminance_sum = 0; + int y, x; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + luminance_sum += src[0] + src[1] + src[2]; + src += 3; + } + src += (src_rowstride - width * 3 * sizeof (float)) / sizeof (float); + } + + return luminance_sum / (width * height); +} + +static float +clamp_value(float value, bool is_signed) +{ + if (value > 65504.0f) + return 65504.0f; + + if (is_signed) { + if (value < -65504.0f) + return -65504.0f; + else + return value; + } + + if (value < 0.0f) + return 0.0f; + + return value; +} + +static void +get_endpoints_float(int width, int height, + const float *src, int src_rowstride, + float average_luminance, float endpoints[][3], + bool is_signed) +{ + float endpoint_luminances[2]; + float midpoint; + float sums[2][3]; + int endpoint, component; + float luminance; + float temp[3]; + const float *p = src; + int left_endpoint_count = 0; + int y, x, i; + + memset(sums, 0, sizeof sums); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + luminance = p[0] + p[1] + p[2]; + if (luminance < average_luminance) { + endpoint = 0; + left_endpoint_count++; + } else { + endpoint = 1; + } + for (i = 0; i < 3; i++) + sums[endpoint][i] += p[i]; + + p += 3; + } + + p += (src_rowstride - width * 3 * sizeof (float)) / sizeof (float); + } + + if (left_endpoint_count == 0 || + left_endpoint_count == width * height) { + for (i = 0; i < 3; i++) + endpoints[0][i] = endpoints[1][i] = + (sums[0][i] + sums[1][i]) / (width * height); + } else { + for (i = 0; i < 3; i++) { + endpoints[0][i] = sums[0][i] / left_endpoint_count; + endpoints[1][i] = sums[1][i] / (width * height - left_endpoint_count); + } + } + + /* Clamp the endpoints to the range of a half float and strip out + * infinities */ + for (endpoint = 0; endpoint < 2; endpoint++) { + for (component = 0; component < 3; component++) { + endpoints[endpoint][component] = + clamp_value(endpoints[endpoint][component], is_signed); + } + } + + /* We may need to swap the endpoints to ensure the most-significant bit of + * the first index is zero */ + + for (endpoint = 0; endpoint < 2; endpoint++) { + endpoint_luminances[endpoint] = + endpoints[endpoint][0] + + endpoints[endpoint][1] + + endpoints[endpoint][2]; + } + midpoint = (endpoint_luminances[0] + endpoint_luminances[1]) / 2.0f; + + if ((src[0] + src[1] + src[2] <= midpoint) != + (endpoint_luminances[0] <= midpoint)) { + memcpy(temp, endpoints[0], sizeof temp); + memcpy(endpoints[0], endpoints[1], sizeof temp); + memcpy(endpoints[1], temp, sizeof temp); + } +} + +static void +write_rgb_indices_float(struct bit_writer *writer, + int src_width, int src_height, + const float *src, int src_rowstride, + float endpoints[][3]) +{ + float luminance; + float endpoint_luminances[2]; + int endpoint; + int index; + int y, x; + + for (endpoint = 0; endpoint < 2; endpoint++) { + endpoint_luminances[endpoint] = + endpoints[endpoint][0] + + endpoints[endpoint][1] + + endpoints[endpoint][2]; + } + + /* If the endpoints have the same luminance then we'll just use index 0 for + * all of the texels */ + if (endpoint_luminances[0] == endpoint_luminances[1]) { + write_bits(writer, BLOCK_SIZE * BLOCK_SIZE * 4 - 1, 0); + return; + } + + for (y = 0; y < src_height; y++) { + for (x = 0; x < src_width; x++) { + luminance = src[0] + src[1] + src[2]; + + index = ((luminance - endpoint_luminances[0]) * 15 / + (endpoint_luminances[1] - endpoint_luminances[0])); + if (index < 0) + index = 0; + else if (index > 15) + index = 15; + + assert(x != 0 || y != 0 || index < 8); + + write_bits(writer, (x == 0 && y == 0) ? 3 : 4, index); + + src += 3; + } + + /* Pad the indices out to the block size */ + if (src_width < BLOCK_SIZE) + write_bits(writer, 4 * (BLOCK_SIZE - src_width), 0); + + src += (src_rowstride - src_width * 3 * sizeof (float)) / sizeof (float); + } + + /* Pad the indices out to the block size */ + if (src_height < BLOCK_SIZE) + write_bits(writer, 4 * BLOCK_SIZE * (BLOCK_SIZE - src_height), 0); +} + +static int +get_endpoint_value(float value, bool is_signed) +{ + bool sign = false; + int half; + + if (is_signed) { + half = _mesa_float_to_half(value); + + if (half & 0x8000) { + half &= 0x7fff; + sign = true; + } + + half = (32 * half / 31) >> 6; + + if (sign) + half = -half & ((1 << 10) - 1); + + return half; + } else { + if (value <= 0.0f) + return 0; + + half = _mesa_float_to_half(value); + + return (64 * half / 31) >> 6; + } +} + +static void +compress_rgb_float_block(int src_width, int src_height, + const float *src, int src_rowstride, + uint8_t *dst, + bool is_signed) +{ + float average_luminance; + float endpoints[2][3]; + struct bit_writer writer; + int component, endpoint; + int endpoint_value; + + average_luminance = + get_average_luminance_float(src_width, src_height, src, src_rowstride); + get_endpoints_float(src_width, src_height, src, src_rowstride, + average_luminance, endpoints, is_signed); + + writer.dst = dst; + writer.pos = 0; + writer.buf = 0; + + write_bits(&writer, 5, 3); /* mode 3 */ + + /* Write the endpoints */ + for (endpoint = 0; endpoint < 2; endpoint++) { + for (component = 0; component < 3; component++) { + endpoint_value = + get_endpoint_value(endpoints[endpoint][component], is_signed); + write_bits(&writer, 10, endpoint_value); + } + } + + write_rgb_indices_float(&writer, + src_width, src_height, + src, src_rowstride, + endpoints); +} + +static void +compress_rgb_float(int width, int height, + const float *src, int src_rowstride, + uint8_t *dst, int dst_rowstride, + bool is_signed) +{ + int dst_row_diff; + int y, x; + + if (dst_rowstride >= width * 4) + dst_row_diff = dst_rowstride - ((width + 3) & ~3) * 4; + else + dst_row_diff = 0; + + for (y = 0; y < height; y += BLOCK_SIZE) { + for (x = 0; x < width; x += BLOCK_SIZE) { + compress_rgb_float_block(MIN2(width - x, BLOCK_SIZE), + MIN2(height - y, BLOCK_SIZE), + src + x * 3 + + y * src_rowstride / sizeof (float), + src_rowstride, + dst, + is_signed); + dst += BLOCK_BYTES; + } + dst += dst_row_diff; + } +} + +#endif diff --git a/lib/mesa/src/mesa/main/texcompress_etc.c b/lib/mesa/src/mesa/main/texcompress_etc.c index d46501098..b39ab33d3 100644 --- a/lib/mesa/src/mesa/main/texcompress_etc.c +++ b/lib/mesa/src/mesa/main/texcompress_etc.c @@ -41,6 +41,7 @@ #include "texcompress.h" #include "texcompress_etc.h" #include "texstore.h" +#include "config.h" #include "macros.h" #include "format_unpack.h" #include "util/format_srgb.h" @@ -105,7 +106,7 @@ static const int etc2_modifier_tables_non_opaque[8][4] = { #undef UINT8_TYPE GLboolean -_mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS) +_mesa_texstore_etc1_rgb8(UNUSED_TEXSTORE_PARAMS) { /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */ assert(0); @@ -718,7 +719,8 @@ etc2_unpack_srgb8(uint8_t *dst_row, const uint8_t *src_row, unsigned src_stride, unsigned width, - unsigned height) + unsigned height, + bool bgra) { const unsigned bw = 4, bh = 4, bs = 8, comps = 4; struct etc2_block block; @@ -740,11 +742,14 @@ etc2_unpack_srgb8(uint8_t *dst_row, for (i = 0; i < w; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, false /* punchthrough_alpha */); - /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ - tmp = dst[0]; - dst[0] = dst[2]; - dst[2] = tmp; - dst[3] = 255; + + if (bgra) { + /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ + tmp = dst[0]; + dst[0] = dst[2]; + dst[2] = tmp; + dst[3] = 255; + } dst += comps; } @@ -800,7 +805,8 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row, const uint8_t *src_row, unsigned src_stride, unsigned width, - unsigned height) + unsigned height, + bool bgra) { /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block * of RGBA8888 information is compressed to 128 bits. To decode a block, the @@ -824,11 +830,13 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row, for (i = 0; i < w; i++) { etc2_rgba8_fetch_texel(&block, i, j, dst); - /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ - tmp = dst[0]; - dst[0] = dst[2]; - dst[2] = tmp; - dst[3] = dst[3]; + if (bgra) { + /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ + tmp = dst[0]; + dst[0] = dst[2]; + dst[2] = tmp; + dst[3] = dst[3]; + } dst += comps; } @@ -1057,7 +1065,8 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row, const uint8_t *src_row, unsigned src_stride, unsigned width, - unsigned height) + unsigned height, + bool bgra) { const unsigned bw = 4, bh = 4, bs = 8, comps = 4; struct etc2_block block; @@ -1077,11 +1086,14 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row, for (i = 0; i < w; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, true /* punchthrough_alpha */); - /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ - tmp = dst[0]; - dst[0] = dst[2]; - dst[2] = tmp; - dst[3] = dst[3]; + + if (bgra) { + /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ + tmp = dst[0]; + dst[0] = dst[2]; + dst[2] = tmp; + dst[3] = dst[3]; + } dst += comps; } @@ -1097,7 +1109,7 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row, /* ETC2 texture formats are valid in glCompressedTexImage2D and * glCompressedTexSubImage2D functions */ GLboolean -_mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS) +_mesa_texstore_etc2_rgb8(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1105,7 +1117,7 @@ _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS) } GLboolean -_mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS) +_mesa_texstore_etc2_srgb8(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1113,7 +1125,7 @@ _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS) } GLboolean -_mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS) +_mesa_texstore_etc2_rgba8_eac(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1121,7 +1133,7 @@ _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS) } GLboolean -_mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS) +_mesa_texstore_etc2_srgb8_alpha8_eac(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1129,7 +1141,7 @@ _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS) } GLboolean -_mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS) +_mesa_texstore_etc2_r11_eac(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1137,7 +1149,7 @@ _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS) } GLboolean -_mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS) +_mesa_texstore_etc2_signed_r11_eac(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1145,7 +1157,7 @@ _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS) } GLboolean -_mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS) +_mesa_texstore_etc2_rg11_eac(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1153,7 +1165,7 @@ _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS) } GLboolean -_mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS) +_mesa_texstore_etc2_signed_rg11_eac(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1161,7 +1173,7 @@ _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS) } GLboolean -_mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS) +_mesa_texstore_etc2_rgb8_punchthrough_alpha1(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1169,7 +1181,7 @@ _mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS) } GLboolean -_mesa_texstore_etc2_srgb8_punchthrough_alpha1(TEXSTORE_PARAMS) +_mesa_texstore_etc2_srgb8_punchthrough_alpha1(UNUSED_TEXSTORE_PARAMS) { assert(0); @@ -1205,7 +1217,8 @@ _mesa_unpack_etc2_format(uint8_t *dst_row, unsigned src_stride, unsigned src_width, unsigned src_height, - mesa_format format) + mesa_format format, + bool bgra) { if (format == MESA_FORMAT_ETC2_RGB8) etc2_unpack_rgb8(dst_row, dst_stride, @@ -1214,7 +1227,7 @@ _mesa_unpack_etc2_format(uint8_t *dst_row, else if (format == MESA_FORMAT_ETC2_SRGB8) etc2_unpack_srgb8(dst_row, dst_stride, src_row, src_stride, - src_width, src_height); + src_width, src_height, bgra); else if (format == MESA_FORMAT_ETC2_RGBA8_EAC) etc2_unpack_rgba8(dst_row, dst_stride, src_row, src_stride, @@ -1222,7 +1235,7 @@ _mesa_unpack_etc2_format(uint8_t *dst_row, else if (format == MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC) etc2_unpack_srgb8_alpha8(dst_row, dst_stride, src_row, src_stride, - src_width, src_height); + src_width, src_height, bgra); else if (format == MESA_FORMAT_ETC2_R11_EAC) etc2_unpack_r11(dst_row, dst_stride, src_row, src_stride, @@ -1246,7 +1259,7 @@ _mesa_unpack_etc2_format(uint8_t *dst_row, else if (format == MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1) etc2_unpack_srgb8_punchthrough_alpha1(dst_row, dst_stride, src_row, src_stride, - src_width, src_height); + src_width, src_height, bgra); } diff --git a/lib/mesa/src/mesa/main/texcompress_etc.h b/lib/mesa/src/mesa/main/texcompress_etc.h index 319b7bea7..2c764b88b 100644 --- a/lib/mesa/src/mesa/main/texcompress_etc.h +++ b/lib/mesa/src/mesa/main/texcompress_etc.h @@ -77,7 +77,8 @@ _mesa_unpack_etc2_format(uint8_t *dst_row, unsigned src_stride, unsigned src_width, unsigned src_height, - mesa_format format); + mesa_format format, + bool bgra); compressed_fetch_func _mesa_get_etc_fetch_func(mesa_format format); diff --git a/lib/mesa/src/mesa/main/texcompress_fxt1.c b/lib/mesa/src/mesa/main/texcompress_fxt1.c index c5646fbd7..19df6baf3 100644 --- a/lib/mesa/src/mesa/main/texcompress_fxt1.c +++ b/lib/mesa/src/mesa/main/texcompress_fxt1.c @@ -29,6 +29,7 @@ */ +#include "errors.h" #include "glheader.h" #include "imports.h" #include "image.h" @@ -37,6 +38,7 @@ #include "texcompress.h" #include "texcompress_fxt1.h" #include "texstore.h" +#include "mtypes.h" static void diff --git a/lib/mesa/src/mesa/main/texcompress_rgtc.c b/lib/mesa/src/mesa/main/texcompress_rgtc.c index 8cab7a56b..843b42e54 100644 --- a/lib/mesa/src/mesa/main/texcompress_rgtc.c +++ b/lib/mesa/src/mesa/main/texcompress_rgtc.c @@ -33,6 +33,7 @@ */ +#include "config.h" #include "glheader.h" #include "imports.h" #include "image.h" diff --git a/lib/mesa/src/mesa/main/texcompress_s3tc_tmp.h b/lib/mesa/src/mesa/main/texcompress_s3tc_tmp.h index 61630f247..dbf8c871b 100644 --- a/lib/mesa/src/mesa/main/texcompress_s3tc_tmp.h +++ b/lib/mesa/src/mesa/main/texcompress_s3tc_tmp.h @@ -22,6 +22,9 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifndef TEXCOMPRESS_S3TC_TMP_H +#define TEXCOMPRESS_S3TC_TMP_H + #ifdef __APPLE__ #include <OpenGL/gl.h> #else @@ -182,8 +185,8 @@ static void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata, #define ALPHACUT 127 -static void fancybasecolorsearch( GLubyte *blkaddr, GLubyte srccolors[4][4][4], GLubyte *bestcolor[2], - GLint numxpixels, GLint numypixels, GLint type, GLboolean haveAlpha) +static void fancybasecolorsearch( UNUSED GLubyte *blkaddr, GLubyte srccolors[4][4][4], GLubyte *bestcolor[2], + GLint numxpixels, GLint numypixels, UNUSED GLint type, UNUSED GLboolean haveAlpha) { /* use same luminance-weighted distance metric to determine encoding as for finding the base colors */ @@ -987,3 +990,5 @@ static void tx_compress_dxtn(GLint srccomps, GLint width, GLint height, const GL return; } } + +#endif diff --git a/lib/mesa/src/mesa/main/texgetimage.h b/lib/mesa/src/mesa/main/texgetimage.h index 63c75eb93..3928e7abb 100644 --- a/lib/mesa/src/mesa/main/texgetimage.h +++ b/lib/mesa/src/mesa/main/texgetimage.h @@ -44,14 +44,6 @@ _mesa_GetTexSubImage_sw(struct gl_context *ctx, struct gl_texture_image *texImage); extern void -_mesa_GetCompressedTexSubImage_sw(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, - GLint height, GLint depth, - GLvoid *data); - -extern void _mesa_get_compressed_texture_image( struct gl_context *ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage, diff --git a/lib/mesa/src/mesa/main/texstore.h b/lib/mesa/src/mesa/main/texstore.h index f08dc08ed..2fef7ba7d 100644 --- a/lib/mesa/src/mesa/main/texstore.h +++ b/lib/mesa/src/mesa/main/texstore.h @@ -36,9 +36,13 @@ #define TEXSTORE_H -#include "mtypes.h" +#include "glheader.h" #include "formats.h" +#include "util/macros.h" +struct gl_context; +struct gl_pixelstore_attrib; +struct gl_texture_image; /** * This macro defines the (many) parameters to the texstore functions. @@ -56,8 +60,8 @@ */ #define TEXSTORE_PARAMS \ struct gl_context *ctx, GLuint dims, \ - GLenum baseInternalFormat, \ - mesa_format dstFormat, \ + MAYBE_UNUSED GLenum baseInternalFormat, \ + MAYBE_UNUSED mesa_format dstFormat, \ GLint dstRowStride, \ GLubyte **dstSlices, \ GLint srcWidth, GLint srcHeight, GLint srcDepth, \ @@ -65,6 +69,20 @@ const GLvoid *srcAddr, \ const struct gl_pixelstore_attrib *srcPacking +/* This macro must be kept in sync with TEXSTORE_PARAMS. It is used in the + * few places where none of the parameters are used (i.e., the ETC texstore + * functions). + */ +#define UNUSED_TEXSTORE_PARAMS \ + UNUSED struct gl_context *ctx, UNUSED GLuint dims, \ + UNUSED GLenum baseInternalFormat, \ + UNUSED mesa_format dstFormat, \ + UNUSED GLint dstRowStride, \ + UNUSED GLubyte **dstSlices, \ + UNUSED GLint srcWidth, UNUSED GLint srcHeight, UNUSED GLint srcDepth, \ + UNUSED GLenum srcFormat, UNUSED GLenum srcType, \ + UNUSED const GLvoid *srcAddr, \ + UNUSED const struct gl_pixelstore_attrib *srcPacking extern GLboolean _mesa_texstore(TEXSTORE_PARAMS); diff --git a/lib/mesa/src/mesa/main/version.h b/lib/mesa/src/mesa/main/version.h index adfec6f82..4469509c0 100644 --- a/lib/mesa/src/mesa/main/version.h +++ b/lib/mesa/src/mesa/main/version.h @@ -27,8 +27,13 @@ #ifndef VERSION_H #define VERSION_H -#include "mtypes.h" +#include <stdbool.h> +#include "glheader.h" +#include "menums.h" +struct gl_context; +struct gl_constants; +struct gl_extensions; extern GLuint _mesa_get_version(const struct gl_extensions *extensions, diff --git a/lib/mesa/src/mesa/main/vtxfmt.h b/lib/mesa/src/mesa/main/vtxfmt.h index 4f8bc9cdf..20fc46670 100644 --- a/lib/mesa/src/mesa/main/vtxfmt.h +++ b/lib/mesa/src/mesa/main/vtxfmt.h @@ -33,12 +33,14 @@ #ifndef _VTXFMT_H_ #define _VTXFMT_H_ -#include "mtypes.h" +#include "dd.h" #ifdef __cplusplus extern "C" { #endif +struct gl_context; + extern void _mesa_install_exec_vtxfmt( struct gl_context *ctx, const GLvertexformat *vfmt ); extern void _mesa_install_save_vtxfmt( struct gl_context *ctx, const GLvertexformat *vfmt ); extern void _mesa_initialize_vbo_vtxfmt(struct gl_context *ctx); diff --git a/lib/mesa/src/mesa/meson.build b/lib/mesa/src/mesa/meson.build new file mode 100644 index 000000000..27c8c401c --- /dev/null +++ b/lib/mesa/src/mesa/meson.build @@ -0,0 +1,754 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +subdir('program') +subdir('main') + +# files shared between classic mesa and gallium mesa +files_libmesa_common = files( + 'program/arbprogparse.c', + 'program/arbprogparse.h', + 'program/ir_to_mesa.cpp', + 'program/ir_to_mesa.h', + 'program/prog_cache.c', + 'program/prog_cache.h', + 'program/prog_execute.c', + 'program/prog_execute.h', + 'program/prog_instruction.c', + 'program/prog_instruction.h', + 'program/prog_noise.c', + 'program/prog_noise.h', + 'program/prog_opt_constant_fold.c', + 'program/prog_optimize.c', + 'program/prog_optimize.h', + 'program/prog_parameter.c', + 'program/prog_parameter.h', + 'program/prog_parameter_layout.c', + 'program/prog_parameter_layout.h', + 'program/prog_print.c', + 'program/prog_print.h', + 'program/program.c', + 'program/program.h', + 'program/programopt.c', + 'program/programopt.h', + 'program/program_parse_extra.c', + 'program/program_parser.h', + 'program/prog_statevars.c', + 'program/prog_statevars.h', + 'program/symbol_table.c', + 'program/symbol_table.h', + 'program/prog_to_nir.c', + 'program/prog_to_nir.h', + 'main/accum.c', + 'main/accum.h', + 'main/api_arrayelt.c', + 'main/api_arrayelt.h', + 'main/api_exec.h', + 'main/api_loopback.c', + 'main/api_loopback.h', + 'main/arbprogram.c', + 'main/arbprogram.h', + 'main/arrayobj.c', + 'main/arrayobj.h', + 'main/atifragshader.c', + 'main/atifragshader.h', + 'main/attrib.c', + 'main/attrib.h', + 'main/barrier.c', + 'main/barrier.h', + 'main/bbox.c', + 'main/bbox.h', + 'main/blend.c', + 'main/blend.h', + 'main/blit.c', + 'main/blit.h', + 'main/bufferobj.c', + 'main/bufferobj.h', + 'main/buffers.c', + 'main/buffers.h', + 'main/clear.c', + 'main/clear.h', + 'main/clip.c', + 'main/clip.h', + 'main/colormac.h', + 'main/colortab.c', + 'main/colortab.h', + 'main/compute.c', + 'main/compute.h', + 'main/compiler.h', + 'main/condrender.c', + 'main/condrender.h', + 'main/config.h', + 'main/conservativeraster.c', + 'main/conservativeraster.h', + 'main/context.c', + 'main/context.h', + 'main/convolve.c', + 'main/convolve.h', + 'main/copyimage.c', + 'main/copyimage.h', + 'main/cpuinfo.c', + 'main/cpuinfo.h', + 'main/dd.h', + 'main/debug.c', + 'main/debug.h', + 'main/debug_output.c', + 'main/debug_output.h', + 'main/depth.c', + 'main/depth.h', + 'main/dlist.c', + 'main/dlist.h', + 'main/draw.c', + 'main/draw.h', + 'main/drawpix.c', + 'main/drawpix.h', + 'main/drawtex.c', + 'main/drawtex.h', + 'main/draw_validate.c', + 'main/draw_validate.h', + 'main/enable.c', + 'main/enable.h', + 'main/enums.h', + 'main/errors.c', + 'main/errors.h', + 'main/eval.c', + 'main/eval.h', + 'main/execmem.c', + 'main/extensions.c', + 'main/extensions.h', + 'main/extensions_table.c', + 'main/extensions_table.h', + 'main/externalobjects.c', + 'main/externalobjects.h', + 'main/fbobject.c', + 'main/fbobject.h', + 'main/feedback.c', + 'main/feedback.h', + 'main/ff_fragment_shader.cpp', + 'main/ffvertex_prog.c', + 'main/ffvertex_prog.h', + 'main/fog.c', + 'main/fog.h', + 'main/format_pack.h', + 'main/format_unpack.h', + 'main/formatquery.c', + 'main/formatquery.h', + 'main/formats.c', + 'main/formats.h', + 'main/format_utils.c', + 'main/format_utils.h', + 'main/framebuffer.c', + 'main/framebuffer.h', + 'main/get.c', + 'main/get.h', + 'main/genmipmap.c', + 'main/genmipmap.h', + 'main/getstring.c', + 'main/glformats.c', + 'main/glformats.h', + 'main/glspirv.c', + 'main/glspirv.h', + 'main/glthread.c', + 'main/glthread.h', + 'main/glheader.h', + 'main/hash.c', + 'main/hash.h', + 'main/hint.c', + 'main/hint.h', + 'main/histogram.c', + 'main/histogram.h', + 'main/image.c', + 'main/image.h', + 'main/imports.c', + 'main/imports.h', + 'main/light.c', + 'main/light.h', + 'main/lines.c', + 'main/lines.h', + 'main/macros.h', + 'main/marshal.c', + 'main/marshal.h', + 'main/matrix.c', + 'main/matrix.h', + 'main/mipmap.c', + 'main/mipmap.h', + 'main/mm.c', + 'main/mm.h', + 'main/menums.h', + 'main/mtypes.h', + 'main/multisample.c', + 'main/multisample.h', + 'main/objectlabel.c', + 'main/objectlabel.h', + 'main/objectpurge.c', + 'main/objectpurge.h', + 'main/pack.c', + 'main/pack.h', + 'main/pbo.c', + 'main/pbo.h', + 'main/performance_monitor.c', + 'main/performance_monitor.h', + 'main/performance_query.c', + 'main/performance_query.h', + 'main/pipelineobj.c', + 'main/pipelineobj.h', + 'main/pixel.c', + 'main/pixel.h', + 'main/pixelstore.c', + 'main/pixelstore.h', + 'main/pixeltransfer.c', + 'main/pixeltransfer.h', + 'main/points.c', + 'main/points.h', + 'main/polygon.c', + 'main/polygon.h', + 'main/program_binary.c', + 'main/program_binary.h', + 'main/program_resource.c', + 'main/program_resource.h', + 'main/querymatrix.c', + 'main/querymatrix.h', + 'main/queryobj.c', + 'main/queryobj.h', + 'main/rastpos.c', + 'main/rastpos.h', + 'main/readpix.c', + 'main/readpix.h', + 'main/remap.c', + 'main/remap.h', + 'main/renderbuffer.c', + 'main/renderbuffer.h', + 'main/robustness.c', + 'main/samplerobj.c', + 'main/samplerobj.h', + 'main/scissor.c', + 'main/scissor.h', + 'main/shaderapi.c', + 'main/shaderapi.h', + 'main/shaderimage.c', + 'main/shaderimage.h', + 'main/shaderobj.c', + 'main/shaderobj.h', + 'main/shader_query.cpp', + 'main/shared.c', + 'main/shared.h', + 'main/state.c', + 'main/state.h', + 'main/stencil.c', + 'main/stencil.h', + 'main/syncobj.c', + 'main/syncobj.h', + 'main/texcompress.c', + 'main/texcompress_astc.cpp', + 'main/texcompress_astc.h', + 'main/texcompress_bptc.c', + 'main/texcompress_bptc.h', + 'main/texcompress_cpal.c', + 'main/texcompress_cpal.h', + 'main/texcompress_etc.c', + 'main/texcompress_etc.h', + 'main/texcompress_etc_tmp.h', + 'main/texcompress_fxt1.c', + 'main/texcompress_fxt1.h', + 'main/texcompress.h', + 'main/texcompress_rgtc.c', + 'main/texcompress_rgtc.h', + 'main/texcompress_s3tc.c', + 'main/texcompress_s3tc.h', + 'main/texenv.c', + 'main/texenv.h', + 'main/texenvprogram.h', + 'main/texformat.c', + 'main/texformat.h', + 'main/texgen.c', + 'main/texgen.h', + 'main/texgetimage.c', + 'main/texgetimage.h', + 'main/teximage.c', + 'main/teximage.h', + 'main/texobj.c', + 'main/texobj.h', + 'main/texparam.c', + 'main/texparam.h', + 'main/texstate.c', + 'main/texstate.h', + 'main/texstorage.c', + 'main/texstorage.h', + 'main/texstore.c', + 'main/texstore.h', + 'main/texturebindless.c', + 'main/texturebindless.h', + 'main/textureview.c', + 'main/textureview.h', + 'main/transformfeedback.c', + 'main/transformfeedback.h', + 'main/uniform_query.cpp', + 'main/uniforms.c', + 'main/uniforms.h', + 'main/varray.c', + 'main/varray.h', + 'main/vdpau.c', + 'main/vdpau.h', + 'main/version.c', + 'main/version.h', + 'main/viewport.c', + 'main/viewport.h', + 'main/vtxfmt.c', + 'main/vtxfmt.h', + 'main/es1_conversion.c', + 'main/es1_conversion.h', + 'math/m_debug.h', + 'math/m_debug_clip.c', + 'math/m_debug_norm.c', + 'math/m_debug_util.h', + 'math/m_debug_xform.c', + 'math/m_eval.c', + 'math/m_eval.h', + 'math/m_matrix.c', + 'math/m_matrix.h', + 'math/m_trans_tmp.h', + 'math/m_translate.c', + 'math/m_translate.h', + 'math/m_vector.c', + 'math/m_vector.h', + 'vbo/vbo_attrib.h', + 'vbo/vbo_attrib_tmp.h', + 'vbo/vbo_context.c', + 'vbo/vbo_exec_api.c', + 'vbo/vbo_exec.c', + 'vbo/vbo_exec_draw.c', + 'vbo/vbo_exec_eval.c', + 'vbo/vbo_exec.h', + 'vbo/vbo.h', + 'vbo/vbo_minmax_index.c', + 'vbo/vbo_noop.c', + 'vbo/vbo_noop.h', + 'vbo/vbo_primitive_restart.c', + 'vbo/vbo_save_api.c', + 'vbo/vbo_save.c', + 'vbo/vbo_save_draw.c', + 'vbo/vbo_save.h', + 'vbo/vbo_save_loopback.c', + 'x86/common_x86.c', +) + +# mesa files +files_libmesa_classic = files( + 'math/m_clip_tmp.h', + 'math/m_copy_tmp.h', + 'math/m_dotprod_tmp.h', + 'math/m_norm_tmp.h', + 'math/m_xform.c', + 'math/m_xform.h', + 'math/m_xform_tmp.h', + 'tnl/t_context.c', + 'tnl/t_context.h', + 'tnl/t_draw.c', + 'tnl/tnl.h', + 'tnl/t_pipeline.c', + 'tnl/t_pipeline.h', + 'tnl/t_rebase.c', + 'tnl/t_split.c', + 'tnl/t_split_copy.c', + 'tnl/t_split.h', + 'tnl/t_split_inplace.c', + 'tnl/t_vb_cliptmp.h', + 'tnl/t_vb_fog.c', + 'tnl/t_vb_light.c', + 'tnl/t_vb_lighttmp.h', + 'tnl/t_vb_normals.c', + 'tnl/t_vb_points.c', + 'tnl/t_vb_program.c', + 'tnl/t_vb_render.c', + 'tnl/t_vb_rendertmp.h', + 'tnl/t_vb_texgen.c', + 'tnl/t_vb_texmat.c', + 'tnl/t_vb_vertex.c', + 'tnl/t_vertex.c', + 'tnl/t_vertex_generic.c', + 'tnl/t_vertex.h', + 'tnl/t_vertex_sse.c', + 'tnl/t_vp_build.c', + 'tnl/t_vp_build.h', + 'swrast/s_aaline.c', + 'swrast/s_aaline.h', + 'swrast/s_aalinetemp.h', + 'swrast/s_aatriangle.c', + 'swrast/s_aatriangle.h', + 'swrast/s_aatritemp.h', + 'swrast/s_alpha.c', + 'swrast/s_alpha.h', + 'swrast/s_atifragshader.c', + 'swrast/s_atifragshader.h', + 'swrast/s_bitmap.c', + 'swrast/s_blend.c', + 'swrast/s_blend.h', + 'swrast/s_blit.c', + 'swrast/s_chan.h', + 'swrast/s_clear.c', + 'swrast/s_context.c', + 'swrast/s_context.h', + 'swrast/s_copypix.c', + 'swrast/s_depth.c', + 'swrast/s_depth.h', + 'swrast/s_drawpix.c', + 'swrast_setup/ss_tritmp.h', + 'swrast_setup/ss_vb.h', + 'swrast_setup/swrast_setup.h', + 'swrast/s_feedback.c', + 'swrast/s_feedback.h', + 'swrast/s_fog.c', + 'swrast/s_fog.h', + 'swrast/s_fragprog.c', + 'swrast/s_fragprog.h', + 'swrast/s_lines.c', + 'swrast/s_lines.h', + 'swrast/s_linetemp.h', + 'swrast/s_logic.c', + 'swrast/s_logic.h', + 'swrast/s_masking.c', + 'swrast/s_masking.h', + 'swrast/s_points.c', + 'swrast/s_points.h', + 'swrast/s_renderbuffer.c', + 'swrast/s_renderbuffer.h', + 'swrast/s_span.c', + 'swrast/s_span.h', + 'swrast/s_stencil.c', + 'swrast/s_stencil.h', + 'swrast/s_texcombine.c', + 'swrast/s_texcombine.h', + 'swrast/s_texfetch.c', + 'swrast/s_texfetch.h', + 'swrast/s_texfetch_tmp.h', + 'swrast/s_texfilter.c', + 'swrast/s_texfilter.h', + 'swrast/s_texrender.c', + 'swrast/s_texture.c', + 'swrast/s_triangle.c', + 'swrast/s_triangle.h', + 'swrast/s_tritemp.h', + 'swrast/swrast.h', + 'swrast/s_zoom.c', + 'swrast/s_zoom.h', + 'swrast_setup/ss_context.c', + 'swrast_setup/ss_context.h', + 'swrast_setup/ss_triangle.c', + 'swrast_setup/ss_triangle.h', + 'drivers/common/driverfuncs.c', + 'drivers/common/driverfuncs.h', + 'drivers/common/meta_blit.c', + 'drivers/common/meta_generate_mipmap.c', + 'drivers/common/meta.c', + 'drivers/common/meta.h', + 'x86/x86_xform.c', + 'x86/3dnow.c', + 'x86/sse.c', + 'x86/rtasm/x86sse.c', + 'x86/rtasm/x86sse.h', + 'sparc/sparc.c', + 'x86-64/x86-64.c', +) + +files_libmesa_gallium = files( + 'state_tracker/st_atifs_to_tgsi.c', + 'state_tracker/st_atifs_to_tgsi.h', + 'state_tracker/st_atom_array.c', + 'state_tracker/st_atom_atomicbuf.c', + 'state_tracker/st_atom_blend.c', + 'state_tracker/st_atom.c', + 'state_tracker/st_atom_clip.c', + 'state_tracker/st_atom_constbuf.c', + 'state_tracker/st_atom_constbuf.h', + 'state_tracker/st_atom_depth.c', + 'state_tracker/st_atom_framebuffer.c', + 'state_tracker/st_atom.h', + 'state_tracker/st_atom_list.h', + 'state_tracker/st_atom_image.c', + 'state_tracker/st_atom_msaa.c', + 'state_tracker/st_atom_pixeltransfer.c', + 'state_tracker/st_atom_rasterizer.c', + 'state_tracker/st_atom_sampler.c', + 'state_tracker/st_atom_scissor.c', + 'state_tracker/st_atom_shader.c', + 'state_tracker/st_atom_shader.h', + 'state_tracker/st_atom_stipple.c', + 'state_tracker/st_atom_storagebuf.c', + 'state_tracker/st_atom_tess.c', + 'state_tracker/st_atom_texture.c', + 'state_tracker/st_atom_viewport.c', + 'state_tracker/st_cb_bitmap.c', + 'state_tracker/st_cb_bitmap.h', + 'state_tracker/st_cb_bitmap_shader.c', + 'state_tracker/st_cb_blit.c', + 'state_tracker/st_cb_blit.h', + 'state_tracker/st_cb_bufferobjects.c', + 'state_tracker/st_cb_bufferobjects.h', + 'state_tracker/st_cb_clear.c', + 'state_tracker/st_cb_clear.h', + 'state_tracker/st_cb_compute.c', + 'state_tracker/st_cb_compute.h', + 'state_tracker/st_cb_condrender.c', + 'state_tracker/st_cb_condrender.h', + 'state_tracker/st_cb_copyimage.c', + 'state_tracker/st_cb_copyimage.h', + 'state_tracker/st_cb_drawpixels.c', + 'state_tracker/st_cb_drawpixels.h', + 'state_tracker/st_cb_drawpixels_shader.c', + 'state_tracker/st_cb_drawtex.c', + 'state_tracker/st_cb_drawtex.h', + 'state_tracker/st_cb_eglimage.c', + 'state_tracker/st_cb_eglimage.h', + 'state_tracker/st_cb_fbo.c', + 'state_tracker/st_cb_fbo.h', + 'state_tracker/st_cb_feedback.c', + 'state_tracker/st_cb_feedback.h', + 'state_tracker/st_cb_flush.c', + 'state_tracker/st_cb_flush.h', + 'state_tracker/st_cb_memoryobjects.c', + 'state_tracker/st_cb_memoryobjects.h', + 'state_tracker/st_cb_msaa.c', + 'state_tracker/st_cb_msaa.h', + 'state_tracker/st_cb_perfmon.c', + 'state_tracker/st_cb_perfmon.h', + 'state_tracker/st_cb_program.c', + 'state_tracker/st_cb_program.h', + 'state_tracker/st_cb_queryobj.c', + 'state_tracker/st_cb_queryobj.h', + 'state_tracker/st_cb_rasterpos.c', + 'state_tracker/st_cb_rasterpos.h', + 'state_tracker/st_cb_readpixels.c', + 'state_tracker/st_cb_readpixels.h', + 'state_tracker/st_cb_strings.c', + 'state_tracker/st_cb_strings.h', + 'state_tracker/st_cb_semaphoreobjects.c', + 'state_tracker/st_cb_semaphoreobjects.h', + 'state_tracker/st_cb_syncobj.c', + 'state_tracker/st_cb_syncobj.h', + 'state_tracker/st_cb_texturebarrier.c', + 'state_tracker/st_cb_texturebarrier.h', + 'state_tracker/st_cb_texture.c', + 'state_tracker/st_cb_texture.h', + 'state_tracker/st_cb_viewport.c', + 'state_tracker/st_cb_viewport.h', + 'state_tracker/st_cb_xformfb.c', + 'state_tracker/st_cb_xformfb.h', + 'state_tracker/st_context.c', + 'state_tracker/st_context.h', + 'state_tracker/st_copytex.c', + 'state_tracker/st_copytex.h', + 'state_tracker/st_debug.c', + 'state_tracker/st_debug.h', + 'state_tracker/st_draw.c', + 'state_tracker/st_draw_feedback.c', + 'state_tracker/st_draw.h', + 'state_tracker/st_extensions.c', + 'state_tracker/st_extensions.h', + 'state_tracker/st_format.c', + 'state_tracker/st_format.h', + 'state_tracker/st_gen_mipmap.c', + 'state_tracker/st_gen_mipmap.h', + 'state_tracker/st_gl_api.h', + 'state_tracker/st_glsl_to_nir.cpp', + 'state_tracker/st_glsl_to_tgsi.cpp', + 'state_tracker/st_glsl_to_tgsi.h', + 'state_tracker/st_glsl_to_tgsi_array_merge.cpp', + 'state_tracker/st_glsl_to_tgsi_array_merge.h', + 'state_tracker/st_glsl_to_tgsi_private.cpp', + 'state_tracker/st_glsl_to_tgsi_private.h', + 'state_tracker/st_glsl_to_tgsi_temprename.cpp', + 'state_tracker/st_glsl_to_tgsi_temprename.h', + 'state_tracker/st_glsl_types.cpp', + 'state_tracker/st_glsl_types.h', + 'state_tracker/st_manager.c', + 'state_tracker/st_manager.h', + 'state_tracker/st_mesa_to_tgsi.c', + 'state_tracker/st_mesa_to_tgsi.h', + 'state_tracker/st_nir.h', + 'state_tracker/st_nir_lower_builtin.c', + 'state_tracker/st_nir_lower_tex_src_plane.c', + 'state_tracker/st_nir_lower_uniforms_to_ubo.c', + 'state_tracker/st_pbo.c', + 'state_tracker/st_pbo.h', + 'state_tracker/st_program.c', + 'state_tracker/st_program.h', + 'state_tracker/st_sampler_view.c', + 'state_tracker/st_sampler_view.h', + 'state_tracker/st_scissor.c', + 'state_tracker/st_scissor.h', + 'state_tracker/st_shader_cache.c', + 'state_tracker/st_shader_cache.h', + 'state_tracker/st_texture.c', + 'state_tracker/st_texture.h', + 'state_tracker/st_tgsi_lower_yuv.c', + 'state_tracker/st_tgsi_lower_yuv.h', + 'state_tracker/st_vdpau.c', + 'state_tracker/st_vdpau.h', +) + +matypes_h = [] +if with_asm_arch == 'x86' or with_asm_arch == 'x86_64' + gen_matypes = executable( + 'gen_matypes', + 'x86/gen_matypes.c', + c_args : [c_vis_args, c_msvc_compat_args], + include_directories : inc_common, + ) + matypes_h = custom_target( + 'matypes.h', + output : 'matypes.h', + command : [gen_matypes], + capture : true, + ) +endif + +inc_libmesa_asm = [] +if with_asm_arch == 'x86' + files_libmesa_common += files( + 'x86/assyntax.h', + 'x86/clip_args.h', + 'x86/norm_args.h', + 'x86/xform_args.h', + 'x86/common_x86_asm.S', + 'x86/common_x86_asm.h', + 'x86/common_x86_features.h', + 'x86/x86_xform.h', + 'x86/x86_xform2.S', + 'x86/x86_xform3.S', + 'x86/x86_xform4.S', + 'x86/x86_cliptest.S', + 'x86/mmx.h', + 'x86/mmx_blend.S', + 'x86/mmx_blendtmp.h', + 'x86/3dnow.h', + 'x86/3dnow_xform1.S', + 'x86/3dnow_xform2.S', + 'x86/3dnow_xform3.S', + 'x86/3dnow_xform4.S', + 'x86/sse.h', + 'x86/sse_xform1.S', + 'x86/sse_xform2.S', + 'x86/sse_xform3.S', + 'x86/sse_xform4.S', + 'x86/sse_normal.S', + 'x86/read_rgba_span_x86.S', + ) + inc_libmesa_asm = include_directories('x86') +elif with_asm_arch == 'x86_64' + files_libmesa_common += files('x86-64/x86-64.h', 'x86-64/xform4.S') + inc_libmesa_asm = include_directories('x86-64') +elif with_asm_arch == 'sparc' + files_libmesa_common += files( + 'sparc/sparc_clip.S', + 'sparc/norm.S', + 'sparc/xform.S', + ) + inc_libmesa_asm = include_directories('sparc') +endif + +format_fallback_c = custom_target( + 'format_fallback.c', + input : ['main/format_fallback.py', 'main/formats.csv'], + output : 'format_fallback.c', + command : [prog_python, '@INPUT0@', '@INPUT1@', '@OUTPUT@'], + depend_files : files('main/format_parser.py'), +) + +get_hash_h = custom_target( + 'get_hash.h', + input : ['main/get_hash_generator.py', gl_and_es_api_files], + output : 'get_hash.h', + command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + depend_files : files('main/get_hash_params.py'), + capture : true, +) + +foreach x : [['format_info.h', 'format_info.py'], + ['format_pack.c', 'format_pack.py'], + ['format_unpack.c', 'format_unpack.py']] + files_libmesa_common += custom_target( + x[0], + input : ['main/@0@'.format(x[1]), 'main/formats.csv'], + output : x[0], + command : [prog_python, '@INPUT0@', '@INPUT1@'], + depend_files : files('main/format_parser.py'), + capture : true, + ) +endforeach + +files_libmesa_common += [ + mesa_lex, + program_parse_tab, + main_api_exec_c, + main_enums_c, + format_fallback_c, + get_hash_h, + main_marshal_generated_c, + main_marshal_generated_h, + main_dispatch_h, + ir_expression_operation_h, + main_remap_helper_h, + matypes_h, + sha1_h, +] + +if with_sse41 + libmesa_sse41 = static_library( + 'mesa_sse41', + files('main/streaming-load-memcpy.c', 'main/sse_minmax.c'), + c_args : [c_vis_args, c_msvc_compat_args, sse41_args], + include_directories : inc_common, + ) +else + libmesa_sse41 = [] +endif + +libmesa_classic = static_library( + 'mesa_classic', + [files_libmesa_common, files_libmesa_classic], + c_args : [c_vis_args, c_msvc_compat_args], + cpp_args : [cpp_vis_args, cpp_msvc_compat_args], + include_directories : [inc_common, inc_libmesa_asm, include_directories('main')], + link_with : [libglsl, libmesa_sse41], + dependencies : idep_nir_headers, + build_by_default : false, +) + +libmesa_gallium = static_library( + 'mesa_gallium', + [files_libmesa_common, files_libmesa_gallium], + c_args : [c_vis_args, c_msvc_compat_args], + cpp_args : [cpp_vis_args, cpp_msvc_compat_args], + include_directories : [inc_common, inc_libmesa_asm, include_directories('main')], + link_with : [libglsl, libmesa_sse41], + dependencies : [idep_nir_headers, dep_vdpau], + build_by_default : false, +) + +subdir('drivers/dri') +if with_osmesa == 'classic' + subdir('drivers/osmesa') +endif +if with_glx == 'xlib' + subdir('drivers/x11') +endif +if with_tests and dri_drivers != [] + subdir('main/tests') +endif diff --git a/lib/mesa/src/mesa/swrast/s_aalinetemp.h b/lib/mesa/src/mesa/swrast/s_aalinetemp.h index bebb131a5..64767a3a5 100644 --- a/lib/mesa/src/mesa/swrast/s_aalinetemp.h +++ b/lib/mesa/src/mesa/swrast/s_aalinetemp.h @@ -179,10 +179,12 @@ NAME(line)(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1) if (attr >= VARYING_SLOT_TEX0 && attr < VARYING_SLOT_VAR0) { const GLuint u = attr - VARYING_SLOT_TEX0; const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; - const struct gl_texture_image *texImage = - _mesa_base_tex_image(obj); - line.texWidth[attr] = (GLfloat) texImage->Width; - line.texHeight[attr] = (GLfloat) texImage->Height; + if (obj) { + const struct gl_texture_image *texImage = + _mesa_base_tex_image(obj); + line.texWidth[attr] = (GLfloat) texImage->Width; + line.texHeight[attr] = (GLfloat) texImage->Height; + } } ATTRIB_LOOP_END } diff --git a/lib/mesa/src/mesa/swrast/s_blit.c b/lib/mesa/src/mesa/swrast/s_blit.c index 3e838a41d..107e41307 100644 --- a/lib/mesa/src/mesa/swrast/s_blit.c +++ b/lib/mesa/src/mesa/swrast/s_blit.c @@ -198,8 +198,8 @@ blit_nearest(struct gl_context *ctx, /* Blit to all the draw buffers */ for (i = 0; i < numDrawBuffers; i++) { if (buffer == GL_COLOR_BUFFER_BIT) { - int idx = drawFb->_ColorDrawBufferIndexes[i]; - if (idx == -1) + gl_buffer_index idx = drawFb->_ColorDrawBufferIndexes[i]; + if (idx == BUFFER_NONE) continue; drawAtt = &drawFb->Attachment[idx]; drawRb = drawAtt->Renderbuffer; @@ -253,7 +253,7 @@ blit_nearest(struct gl_context *ctx, ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0, readRb->Width, readRb->Height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &map, &rowStride); + &map, &rowStride, readFb->FlipY); if (!map) { goto fail_no_memory; } @@ -280,14 +280,16 @@ blit_nearest(struct gl_context *ctx, ctx->Driver.MapRenderbuffer(ctx, readRb, srcXpos, srcYpos, srcWidth, srcHeight, - GL_MAP_READ_BIT, &srcMap, &srcRowStride); + GL_MAP_READ_BIT, &srcMap, &srcRowStride, + readFb->FlipY); if (!srcMap) { goto fail_no_memory; } ctx->Driver.MapRenderbuffer(ctx, drawRb, dstXpos, dstYpos, dstWidth, dstHeight, - GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); + GL_MAP_WRITE_BIT, &dstMap, &dstRowStride, + drawFb->FlipY); if (!dstMap) { ctx->Driver.UnmapRenderbuffer(ctx, readRb); goto fail_no_memory; @@ -569,12 +571,12 @@ blit_linear(struct gl_context *ctx, } for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) { - GLint idx = drawFb->_ColorDrawBufferIndexes[i]; + gl_buffer_index idx = drawFb->_ColorDrawBufferIndexes[i]; struct gl_renderbuffer_attachment *drawAtt; struct gl_renderbuffer *drawRb; mesa_format drawFormat; - if (idx == -1) + if (idx == BUFFER_NONE) continue; drawAtt = &drawFb->Attachment[idx]; @@ -594,7 +596,8 @@ blit_linear(struct gl_context *ctx, ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0, readRb->Width, readRb->Height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &srcMap, &srcRowStride); + &srcMap, &srcRowStride, + readFb->FlipY); if (!srcMap) { goto fail_no_memory; } @@ -609,13 +612,15 @@ blit_linear(struct gl_context *ctx, */ ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0, readRb->Width, readRb->Height, - GL_MAP_READ_BIT, &srcMap, &srcRowStride); + GL_MAP_READ_BIT, &srcMap, &srcRowStride, + readFb->FlipY); if (!srcMap) { goto fail_no_memory; } ctx->Driver.MapRenderbuffer(ctx, drawRb, 0, 0, drawRb->Width, drawRb->Height, - GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); + GL_MAP_WRITE_BIT, &dstMap, &dstRowStride, + drawFb->FlipY); if (!dstMap) { ctx->Driver.UnmapRenderbuffer(ctx, readRb); goto fail_no_memory; diff --git a/lib/mesa/src/mesa/swrast/s_clear.c b/lib/mesa/src/mesa/swrast/s_clear.c index c26b4be0d..ef0f6df9d 100644 --- a/lib/mesa/src/mesa/swrast/s_clear.c +++ b/lib/mesa/src/mesa/swrast/s_clear.c @@ -66,7 +66,8 @@ clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, /* map dest buffer */ ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - mapMode, &map, &rowStride); + mapMode, &map, &rowStride, + ctx->DrawBuffer->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(color)"); return; @@ -187,7 +188,13 @@ clear_color_buffers(struct gl_context *ctx) if (rb == NULL) continue; - clear_rgba_buffer(ctx, rb, ctx->Color.ColorMask[buf]); + const GLubyte colormask[4] = { + GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xff : 0, + GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xff : 0, + GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xff : 0, + GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xff : 0, + }; + clear_rgba_buffer(ctx, rb, colormask); } } diff --git a/lib/mesa/src/mesa/swrast/s_context.h b/lib/mesa/src/mesa/swrast/s_context.h index 7cf0e30dc..49c30a3de 100644 --- a/lib/mesa/src/mesa/swrast/s_context.h +++ b/lib/mesa/src/mesa/swrast/s_context.h @@ -43,7 +43,6 @@ #ifndef S_CONTEXT_H #define S_CONTEXT_H -#include "main/compiler.h" #include "main/mtypes.h" #include "main/texcompress.h" #include "program/prog_execute.h" diff --git a/lib/mesa/src/mesa/swrast/s_copypix.c b/lib/mesa/src/mesa/swrast/s_copypix.c index 0dbccc0f6..d0703fa07 100644 --- a/lib/mesa/src/mesa/swrast/s_copypix.c +++ b/lib/mesa/src/mesa/swrast/s_copypix.c @@ -503,7 +503,7 @@ swrast_fast_copy_pixels(struct gl_context *ctx, ctx->Driver.MapRenderbuffer(ctx, srcRb, 0, 0, srcRb->Width, srcRb->Height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &map, &rowStride); + &map, &rowStride, srcFb->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return GL_TRUE; /* don't retry with slow path */ @@ -530,14 +530,16 @@ swrast_fast_copy_pixels(struct gl_context *ctx, /* different src/dst buffers */ ctx->Driver.MapRenderbuffer(ctx, srcRb, srcX, srcY, width, height, - GL_MAP_READ_BIT, &srcMap, &srcRowStride); + GL_MAP_READ_BIT, &srcMap, &srcRowStride, + srcFb->FlipY); if (!srcMap) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return GL_TRUE; /* don't retry with slow path */ } ctx->Driver.MapRenderbuffer(ctx, dstRb, dstX, dstY, width, height, - GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); + GL_MAP_WRITE_BIT, &dstMap, &dstRowStride, + dstFb->FlipY); if (!dstMap) { ctx->Driver.UnmapRenderbuffer(ctx, srcRb); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); @@ -598,7 +600,8 @@ map_readbuffer(struct gl_context *ctx, GLenum type) ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height, GL_MAP_READ_BIT, - &srb->Map, &srb->RowStride); + &srb->Map, &srb->RowStride, + fb->FlipY); return rb; } diff --git a/lib/mesa/src/mesa/swrast/s_depth.c b/lib/mesa/src/mesa/swrast/s_depth.c index ffadc05a7..de7f14a4f 100644 --- a/lib/mesa/src/mesa/swrast/s_depth.c +++ b/lib/mesa/src/mesa/swrast/s_depth.c @@ -310,12 +310,6 @@ _swrast_depth_test_span(struct gl_context *ctx, SWspan *span) zBufferVals = zStart; } else { - if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED) { - _mesa_problem(ctx, "Incorrectly writing swrast's integer depth " - "values to %s depth buffer", - _mesa_get_format_name(rb->Format)); - } - /* copy Z buffer values into temp buffer (32-bit Z values) */ zBufferTemp = malloc(count * sizeof(GLuint)); if (!zBufferTemp) @@ -570,7 +564,8 @@ _swrast_clear_depth_buffer(struct gl_context *ctx) } ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - mapMode, &map, &rowStride); + mapMode, &map, &rowStride, + ctx->DrawBuffer->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth)"); return; @@ -695,7 +690,8 @@ _swrast_clear_depth_stencil_buffer(struct gl_context *ctx) } ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - mapMode, &map, &rowStride); + mapMode, &map, &rowStride, + ctx->DrawBuffer->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth+stencil)"); return; diff --git a/lib/mesa/src/mesa/swrast/s_drawpix.c b/lib/mesa/src/mesa/swrast/s_drawpix.c index f05528d0d..7ee401b2d 100644 --- a/lib/mesa/src/mesa/swrast/s_drawpix.c +++ b/lib/mesa/src/mesa/swrast/s_drawpix.c @@ -55,7 +55,8 @@ fast_draw_rgb_ubyte_pixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) + const GLvoid *pixels, + bool flip_y) { const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, pixels, width, @@ -67,7 +68,8 @@ fast_draw_rgb_ubyte_pixels(struct gl_context *ctx, GLint dstRowStride; ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - GL_MAP_WRITE_BIT, &dst, &dstRowStride); + GL_MAP_WRITE_BIT, &dst, &dstRowStride, + flip_y); if (!dst) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); @@ -102,7 +104,8 @@ fast_draw_rgba_ubyte_pixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) + const GLvoid *pixels, + bool flip_y) { const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, pixels, width, @@ -114,7 +117,8 @@ fast_draw_rgba_ubyte_pixels(struct gl_context *ctx, GLint dstRowStride; ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - GL_MAP_WRITE_BIT, &dst, &dstRowStride); + GL_MAP_WRITE_BIT, &dst, &dstRowStride, + flip_y); if (!dst) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); @@ -151,7 +155,8 @@ fast_draw_generic_pixels(struct gl_context *ctx, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) + const GLvoid *pixels, + bool flip_y) { const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, pixels, width, @@ -164,7 +169,8 @@ fast_draw_generic_pixels(struct gl_context *ctx, GLint dstRowStride; ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - GL_MAP_WRITE_BIT, &dst, &dstRowStride); + GL_MAP_WRITE_BIT, &dst, &dstRowStride, + flip_y); if (!dst) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); @@ -197,6 +203,7 @@ fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y, const struct gl_pixelstore_attrib *userUnpack, const GLvoid *pixels) { + struct gl_framebuffer *fb = ctx->DrawBuffer; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; SWcontext *swrast = SWRAST_CONTEXT(ctx); struct gl_pixelstore_attrib unpack; @@ -228,7 +235,7 @@ fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y, (rb->Format == MESA_FORMAT_B8G8R8X8_UNORM || rb->Format == MESA_FORMAT_B8G8R8A8_UNORM)) { fast_draw_rgb_ubyte_pixels(ctx, rb, x, y, width, height, - &unpack, pixels); + &unpack, pixels, fb->FlipY); return GL_TRUE; } @@ -237,14 +244,15 @@ fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y, (rb->Format == MESA_FORMAT_B8G8R8X8_UNORM || rb->Format == MESA_FORMAT_B8G8R8A8_UNORM)) { fast_draw_rgba_ubyte_pixels(ctx, rb, x, y, width, height, - &unpack, pixels); + &unpack, pixels, fb->FlipY); return GL_TRUE; } if (_mesa_format_matches_format_and_type(rb->Format, format, type, ctx->Unpack.SwapBytes, NULL)) { fast_draw_generic_pixels(ctx, rb, x, y, width, height, - format, type, &unpack, pixels); + format, type, &unpack, pixels, + fb->FlipY); return GL_TRUE; } diff --git a/lib/mesa/src/mesa/swrast/s_fog.c b/lib/mesa/src/mesa/swrast/s_fog.c index 8b0bdf8fa..33da09b61 100644 --- a/lib/mesa/src/mesa/swrast/s_fog.c +++ b/lib/mesa/src/mesa/swrast/s_fog.c @@ -24,6 +24,7 @@ #include "c99_math.h" +#include "main/errors.h" #include "main/glheader.h" #include "main/macros.h" diff --git a/lib/mesa/src/mesa/swrast/s_masking.c b/lib/mesa/src/mesa/swrast/s_masking.c index c10bf1ac2..8941375a9 100644 --- a/lib/mesa/src/mesa/swrast/s_masking.c +++ b/lib/mesa/src/mesa/swrast/s_masking.c @@ -56,8 +56,14 @@ _swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, * Note that we're not using span->array->mask[] here. We could... */ if (span->array->ChanType == GL_UNSIGNED_BYTE) { + const GLubyte colormask[4] = { + GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xff : 0, + GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xff : 0, + GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xff : 0, + GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xff : 0, + }; GLuint srcMask; - memcpy(&srcMask, ctx->Color.ColorMask[buf], sizeof(srcMask)); + memcpy(&srcMask, colormask, sizeof(srcMask)); const GLuint dstMask = ~srcMask; const GLuint *dst = (const GLuint *) rbPixels; GLuint *src = (GLuint *) span->array->rgba8; @@ -69,10 +75,10 @@ _swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, else if (span->array->ChanType == GL_UNSIGNED_SHORT) { /* 2-byte components */ /* XXX try to use 64-bit arithmetic someday */ - const GLushort rMask = ctx->Color.ColorMask[buf][RCOMP] ? 0xffff : 0x0; - const GLushort gMask = ctx->Color.ColorMask[buf][GCOMP] ? 0xffff : 0x0; - const GLushort bMask = ctx->Color.ColorMask[buf][BCOMP] ? 0xffff : 0x0; - const GLushort aMask = ctx->Color.ColorMask[buf][ACOMP] ? 0xffff : 0x0; + const GLushort rMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xffff : 0x0; + const GLushort gMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xffff : 0x0; + const GLushort bMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xffff : 0x0; + const GLushort aMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xffff : 0x0; const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels; GLushort (*src)[4] = span->array->rgba16; GLuint i; @@ -85,10 +91,10 @@ _swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, } else { /* 4-byte components */ - const GLuint rMask = ctx->Color.ColorMask[buf][RCOMP] ? ~0x0 : 0x0; - const GLuint gMask = ctx->Color.ColorMask[buf][GCOMP] ? ~0x0 : 0x0; - const GLuint bMask = ctx->Color.ColorMask[buf][BCOMP] ? ~0x0 : 0x0; - const GLuint aMask = ctx->Color.ColorMask[buf][ACOMP] ? ~0x0 : 0x0; + const GLuint rMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? ~0x0 : 0x0; + const GLuint gMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? ~0x0 : 0x0; + const GLuint bMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? ~0x0 : 0x0; + const GLuint aMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? ~0x0 : 0x0; const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels; GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[VARYING_SLOT_COL0]; GLuint i; diff --git a/lib/mesa/src/mesa/swrast/s_renderbuffer.h b/lib/mesa/src/mesa/swrast/s_renderbuffer.h index 2595d7c17..9238d8afa 100644 --- a/lib/mesa/src/mesa/swrast/s_renderbuffer.h +++ b/lib/mesa/src/mesa/swrast/s_renderbuffer.h @@ -43,7 +43,8 @@ _swrast_map_soft_renderbuffer(struct gl_context *ctx, GLuint x, GLuint y, GLuint w, GLuint h, GLbitfield mode, GLubyte **out_map, - GLint *out_stride); + GLint *out_stride, + bool flip_y); extern void _swrast_unmap_soft_renderbuffer(struct gl_context *ctx, diff --git a/lib/mesa/src/mesa/swrast/s_stencil.c b/lib/mesa/src/mesa/swrast/s_stencil.c index 294b593a2..8ccd5a164 100644 --- a/lib/mesa/src/mesa/swrast/s_stencil.c +++ b/lib/mesa/src/mesa/swrast/s_stencil.c @@ -28,7 +28,6 @@ #include "main/imports.h" #include "main/format_pack.h" #include "main/format_unpack.h" -#include "main/core.h" #include "main/stencil.h" #include "s_context.h" @@ -580,7 +579,8 @@ _swrast_clear_stencil_buffer(struct gl_context *ctx) } ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - mapMode, &map, &rowStride); + mapMode, &map, &rowStride, + ctx->DrawBuffer->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(stencil)"); return; diff --git a/lib/mesa/src/mesa/swrast/s_texcombine.c b/lib/mesa/src/mesa/swrast/s_texcombine.c index da4a01363..743ee4015 100644 --- a/lib/mesa/src/mesa/swrast/s_texcombine.c +++ b/lib/mesa/src/mesa/swrast/s_texcombine.c @@ -84,7 +84,8 @@ texture_combine( struct gl_context *ctx, GLuint unit, SWspan *span ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]); + const struct gl_fixedfunc_texture_unit *textureUnit = + &ctx->Texture.FixedFuncUnit[unit]; const struct gl_tex_env_combine_state *combine = textureUnit->_CurrentCombine; float4_array argRGB[MAX_COMBINER_TERMS]; float4_array argA[MAX_COMBINER_TERMS]; diff --git a/lib/mesa/src/mesa/swrast/s_texfetch.c b/lib/mesa/src/mesa/swrast/s_texfetch.c index e2c3c085b..fec8728a7 100644 --- a/lib/mesa/src/mesa/swrast/s_texfetch.c +++ b/lib/mesa/src/mesa/swrast/s_texfetch.c @@ -33,6 +33,7 @@ */ +#include "main/errors.h" #include "main/macros.h" #include "main/texcompress.h" #include "main/texcompress_fxt1.h" diff --git a/lib/mesa/src/mesa/swrast/s_zoom.c b/lib/mesa/src/mesa/swrast/s_zoom.c index 34b8eb196..2472aa730 100644 --- a/lib/mesa/src/mesa/swrast/s_zoom.c +++ b/lib/mesa/src/mesa/swrast/s_zoom.c @@ -22,6 +22,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include "main/errors.h" #include "main/glheader.h" #include "main/macros.h" #include "main/imports.h" diff --git a/lib/mesa/src/mesa/tnl/t_context.h b/lib/mesa/src/mesa/tnl/t_context.h index e7adb5f53..eca9f6603 100644 --- a/lib/mesa/src/mesa/tnl/t_context.h +++ b/lib/mesa/src/mesa/tnl/t_context.h @@ -57,6 +57,8 @@ #include "vbo/vbo.h" +#include "tnl.h" + #define MAX_PIPELINE_STAGES 30 /* @@ -76,39 +78,45 @@ * attribs want (16). */ enum { - _TNL_ATTRIB_POS = 0, - _TNL_ATTRIB_WEIGHT = 1, - _TNL_ATTRIB_NORMAL = 2, - _TNL_ATTRIB_COLOR0 = 3, - _TNL_ATTRIB_COLOR1 = 4, - _TNL_ATTRIB_FOG = 5, - _TNL_ATTRIB_COLOR_INDEX = 6, - _TNL_ATTRIB_EDGEFLAG = 7, - _TNL_ATTRIB_TEX0 = 8, - _TNL_ATTRIB_TEX1 = 9, - _TNL_ATTRIB_TEX2 = 10, - _TNL_ATTRIB_TEX3 = 11, - _TNL_ATTRIB_TEX4 = 12, - _TNL_ATTRIB_TEX5 = 13, - _TNL_ATTRIB_TEX6 = 14, - _TNL_ATTRIB_TEX7 = 15, - - _TNL_ATTRIB_GENERIC0 = 17, /* doesn't really exist! */ - _TNL_ATTRIB_GENERIC1 = 18, - _TNL_ATTRIB_GENERIC2 = 19, - _TNL_ATTRIB_GENERIC3 = 20, - _TNL_ATTRIB_GENERIC4 = 21, - _TNL_ATTRIB_GENERIC5 = 22, - _TNL_ATTRIB_GENERIC6 = 23, - _TNL_ATTRIB_GENERIC7 = 24, - _TNL_ATTRIB_GENERIC8 = 25, - _TNL_ATTRIB_GENERIC9 = 26, - _TNL_ATTRIB_GENERIC10 = 27, - _TNL_ATTRIB_GENERIC11 = 28, - _TNL_ATTRIB_GENERIC12 = 29, - _TNL_ATTRIB_GENERIC13 = 30, - _TNL_ATTRIB_GENERIC14 = 31, - _TNL_ATTRIB_GENERIC15 = 32, + _TNL_ATTRIB_POS, + _TNL_ATTRIB_NORMAL, + _TNL_ATTRIB_COLOR0, + _TNL_ATTRIB_COLOR1, + _TNL_ATTRIB_FOG, + _TNL_ATTRIB_COLOR_INDEX, + _TNL_ATTRIB_EDGEFLAG, + _TNL_ATTRIB_TEX0, + _TNL_ATTRIB_TEX1, + _TNL_ATTRIB_TEX2, + _TNL_ATTRIB_TEX3, + _TNL_ATTRIB_TEX4, + _TNL_ATTRIB_TEX5, + _TNL_ATTRIB_TEX6, + _TNL_ATTRIB_TEX7, + + /* This is really a VARYING_SLOT, not an attrib. Need to fix + * tnl to understand the difference. + */ + _TNL_ATTRIB_POINTSIZE, + + _TNL_ATTRIB_GENERIC0, /* doesn't really exist! */ + _TNL_ATTRIB_GENERIC1, + _TNL_ATTRIB_GENERIC2, + _TNL_ATTRIB_GENERIC3, + _TNL_ATTRIB_GENERIC4, + _TNL_ATTRIB_GENERIC5, + _TNL_ATTRIB_GENERIC6, + _TNL_ATTRIB_GENERIC7, + _TNL_ATTRIB_GENERIC8, + _TNL_ATTRIB_GENERIC9, + _TNL_ATTRIB_GENERIC10, + _TNL_ATTRIB_GENERIC11, + _TNL_ATTRIB_GENERIC12, + _TNL_ATTRIB_GENERIC13, + _TNL_ATTRIB_GENERIC14, + _TNL_ATTRIB_GENERIC15, + + _TNL_ATTRIB_MAX, /* These alias with the generics, but they are not active * concurrently, so it's not a problem. The TNL module @@ -120,26 +128,19 @@ enum { * generic attribute in order to pick up per-vertex material * data. */ - _TNL_ATTRIB_MAT_FRONT_AMBIENT = 17, - _TNL_ATTRIB_MAT_BACK_AMBIENT = 18, - _TNL_ATTRIB_MAT_FRONT_DIFFUSE = 19, - _TNL_ATTRIB_MAT_BACK_DIFFUSE = 20, - _TNL_ATTRIB_MAT_FRONT_SPECULAR = 21, - _TNL_ATTRIB_MAT_BACK_SPECULAR = 22, - _TNL_ATTRIB_MAT_FRONT_EMISSION = 23, - _TNL_ATTRIB_MAT_BACK_EMISSION = 24, - _TNL_ATTRIB_MAT_FRONT_SHININESS = 25, - _TNL_ATTRIB_MAT_BACK_SHININESS = 26, - _TNL_ATTRIB_MAT_FRONT_INDEXES = 27, - _TNL_ATTRIB_MAT_BACK_INDEXES = 28, - - /* This is really a VARYING_SLOT, not an attrib. Need to fix - * tnl to understand the difference. - */ - _TNL_ATTRIB_POINTSIZE = 16, - - _TNL_ATTRIB_MAX = 33 -} ; + _TNL_ATTRIB_MAT_FRONT_AMBIENT=VERT_ATTRIB_MAT(MAT_ATTRIB_FRONT_AMBIENT), + _TNL_ATTRIB_MAT_BACK_AMBIENT, + _TNL_ATTRIB_MAT_FRONT_DIFFUSE, + _TNL_ATTRIB_MAT_BACK_DIFFUSE, + _TNL_ATTRIB_MAT_FRONT_SPECULAR, + _TNL_ATTRIB_MAT_BACK_SPECULAR, + _TNL_ATTRIB_MAT_FRONT_EMISSION, + _TNL_ATTRIB_MAT_BACK_EMISSION, + _TNL_ATTRIB_MAT_FRONT_SHININESS, + _TNL_ATTRIB_MAT_BACK_SHININESS, + _TNL_ATTRIB_MAT_FRONT_INDEXES, + _TNL_ATTRIB_MAT_BACK_INDEXES, +}; #define _TNL_ATTRIB_TEX(u) (_TNL_ATTRIB_TEX0 + (u)) #define _TNL_ATTRIB_GENERIC(n) (_TNL_ATTRIB_GENERIC0 + (n)) @@ -150,7 +151,7 @@ enum { /** * Handy attribute ranges: */ -#define _TNL_FIRST_PROG _TNL_ATTRIB_WEIGHT +#define _TNL_FIRST_PROG _TNL_ATTRIB_NORMAL #define _TNL_LAST_PROG _TNL_ATTRIB_TEX7 #define _TNL_FIRST_TEX _TNL_ATTRIB_TEX0 @@ -159,8 +160,8 @@ enum { #define _TNL_FIRST_GENERIC _TNL_ATTRIB_GENERIC0 #define _TNL_LAST_GENERIC _TNL_ATTRIB_GENERIC15 -#define _TNL_FIRST_MAT _TNL_ATTRIB_MAT_FRONT_AMBIENT /* GENERIC0 */ -#define _TNL_LAST_MAT _TNL_ATTRIB_MAT_BACK_INDEXES /* GENERIC11 */ +#define _TNL_FIRST_MAT _TNL_ATTRIB_MAT_FRONT_AMBIENT /* GENERIC4 */ +#define _TNL_LAST_MAT _TNL_ATTRIB_MAT_BACK_INDEXES /* GENERIC15 */ /* Number of available texture attributes */ #define _TNL_NUM_TEX 8 @@ -498,6 +499,41 @@ struct tnl_device_driver /** + * Utility that tracks and updates the current array entries. + */ +struct tnl_inputs +{ + /** + * Array of inputs to be set to the _DrawArrays pointer. + * The array contains pointers into the _DrawVAO and to the vbo modules + * current values. The array of pointers is updated incrementally + * based on the current and vertex_processing_mode values below. + */ + struct tnl_vertex_array inputs[VERT_ATTRIB_MAX]; + /** Those VERT_BIT_'s where the inputs array point to current values. */ + GLbitfield current; + /** Store which aliasing current values - generics or materials - are set. */ + gl_vertex_processing_mode vertex_processing_mode; +}; + + +/** + * Initialize inputs. + */ +void +_tnl_init_inputs(struct tnl_inputs *inputs); + + +/** + * Update the tnl_vertex_array array inside the tnl_inputs structure + * provided the current _VPMode, the provided vao and + * the vao's enabled arrays filtered by the filter bitmask. + */ +void +_tnl_update_inputs(struct gl_context *ctx, struct tnl_inputs *inputs); + + +/** * Context state for T&L context. */ typedef struct @@ -537,6 +573,9 @@ typedef struct struct tnl_shine_tab *_ShineTable[2]; /**< Active shine tables */ struct tnl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ /**@}*/ + + /* The list of tnl_vertex_array inputs. */ + struct tnl_inputs draw_arrays; } TNLcontext; diff --git a/lib/mesa/src/mesa/tnl/t_rebase.c b/lib/mesa/src/mesa/tnl/t_rebase.c new file mode 100644 index 000000000..b6950e04f --- /dev/null +++ b/lib/mesa/src/mesa/tnl/t_rebase.c @@ -0,0 +1,253 @@ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <keithw@vmware.com> + */ + +/* Helper for drivers which find themselves rendering a range of + * indices starting somewhere above zero. Typically the application + * is issuing multiple DrawArrays() or DrawElements() to draw + * successive primitives layed out linearly in the vertex arrays. + * Unless the vertex arrays are all in a VBO, the OpenGL semantics + * imply that we need to re-upload the vertex data on each draw call. + * In that case, we want to avoid starting the upload at zero, as it + * will mean every draw call uploads an increasing amount of not-used + * vertex data. Worse - in the software tnl module, all those + * vertices will be transformed and lit. + * + * If we just upload the new data, however, the indices will be + * incorrect as we tend to upload each set of vertex data to a new + * region. + * + * This file provides a helper to adjust the arrays, primitives and + * indices of a draw call so that it can be re-issued with a min_index + * of zero. + */ + +#include <stdio.h> +#include "main/bufferobj.h" +#include "main/errors.h" +#include "main/glheader.h" +#include "main/imports.h" +#include "main/mtypes.h" +#include "vbo/vbo.h" + +#include "t_rebase.h" + + +#define REBASE(TYPE) \ +static void *rebase_##TYPE( const void *ptr, \ + GLuint count, \ + TYPE min_index ) \ +{ \ + GLuint i; \ + const TYPE *in = (TYPE *)ptr; \ + TYPE *tmp_indices = malloc(count * sizeof(TYPE)); \ + \ + if (tmp_indices == NULL) { \ + _mesa_error_no_memory(__func__); \ + return NULL; \ + } \ + \ + for (i = 0; i < count; i++) \ + tmp_indices[i] = in[i] - min_index; \ + \ + return (void *)tmp_indices; \ +} + + +REBASE(GLuint) +REBASE(GLushort) +REBASE(GLubyte) + + + +/* Adjust primitives, indices and vertex definitions so that min_index + * becomes zero. There are lots of reasons for wanting to do this, eg: + * + * Software tnl: + * - any time min_index != 0, otherwise unused vertices lower than + * min_index will be transformed. + * + * Hardware tnl: + * - if ib != NULL and min_index != 0, otherwise vertices lower than + * min_index will be uploaded. Requires adjusting index values. + * + * - if ib == NULL and min_index != 0, just for convenience so this doesn't + * have to be handled within the driver. + * + * Hardware tnl with VBO support: + * - as above, but only when vertices are not (all?) in VBO's. + * - can't save time by trying to upload half a vbo - typically it is + * all or nothing. + */ +void t_rebase_prims( struct gl_context *ctx, + const struct tnl_vertex_array *arrays, + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index, + tnl_draw_func draw ) +{ + struct gl_array_attributes tmp_attribs[VERT_ATTRIB_MAX]; + struct tnl_vertex_array tmp_arrays[VERT_ATTRIB_MAX]; + + struct _mesa_index_buffer tmp_ib; + struct _mesa_prim *tmp_prims = NULL; + void *tmp_indices = NULL; + GLuint i; + + assert(min_index != 0); + + if (0) + printf("%s %d..%d\n", __func__, min_index, max_index); + + + /* XXX this path is disabled for now. + * There's rendering corruption in some apps when it's enabled. + */ + if (0 && ib && ctx->Extensions.ARB_draw_elements_base_vertex) { + /* If we can just tell the hardware or the TNL to interpret our + * indices with a different base, do so. + */ + tmp_prims = malloc(sizeof(*prim) * nr_prims); + + if (tmp_prims == NULL) { + _mesa_error_no_memory(__func__); + return; + } + + for (i = 0; i < nr_prims; i++) { + tmp_prims[i] = prim[i]; + tmp_prims[i].basevertex -= min_index; + } + + prim = tmp_prims; + } else if (ib) { + /* Unfortunately need to adjust each index individually. + */ + GLboolean map_ib = ib->obj->Name && + !ib->obj->Mappings[MAP_INTERNAL].Pointer; + void *ptr; + + if (map_ib) + ctx->Driver.MapBufferRange(ctx, 0, ib->obj->Size, GL_MAP_READ_BIT, + ib->obj, MAP_INTERNAL); + + + ptr = ADD_POINTERS(ib->obj->Mappings[MAP_INTERNAL].Pointer, ib->ptr); + + /* Some users might prefer it if we translated elements to + * GLuints here. Others wouldn't... + */ + switch (ib->index_size) { + case 4: + tmp_indices = rebase_GLuint( ptr, ib->count, min_index ); + break; + case 2: + tmp_indices = rebase_GLushort( ptr, ib->count, min_index ); + break; + case 1: + tmp_indices = rebase_GLubyte( ptr, ib->count, min_index ); + break; + } + + if (map_ib) + ctx->Driver.UnmapBuffer(ctx, ib->obj, MAP_INTERNAL); + + if (tmp_indices == NULL) { + return; + } + + tmp_ib.obj = ctx->Shared->NullBufferObj; + tmp_ib.ptr = tmp_indices; + tmp_ib.count = ib->count; + tmp_ib.index_size = ib->index_size; + + ib = &tmp_ib; + } + else { + /* Otherwise the primitives need adjustment. + */ + tmp_prims = malloc(sizeof(*prim) * nr_prims); + + if (tmp_prims == NULL) { + _mesa_error_no_memory(__func__); + return; + } + + for (i = 0; i < nr_prims; i++) { + /* If this fails, it could indicate an application error: + */ + assert(prim[i].start >= min_index); + + tmp_prims[i] = prim[i]; + tmp_prims[i].start -= min_index; + } + + prim = tmp_prims; + } + + /* Just need to adjust the pointer values on each incoming array. + * This works for VBO and non-vbo rendering and shouldn't pesimize + * VBO-based upload schemes. However this may still not be a fast + * path for hardware tnl for VBO based rendering as most machines + * will be happier if you just specify a starting vertex value in + * each primitive. + * + * For drivers with hardware tnl, you only want to do this if you + * are forced to, eg non-VBO indexed rendering with start != 0. + */ + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + tmp_attribs[i] = *(arrays[i].VertexAttrib); + tmp_arrays[i].BufferBinding = arrays[i].BufferBinding; + tmp_arrays[i].VertexAttrib = &tmp_attribs[i]; + if (_mesa_is_bufferobj(arrays[i].BufferBinding->BufferObj)) + tmp_attribs[i].RelativeOffset += + min_index * arrays[i].BufferBinding->Stride; + else + tmp_attribs[i].Ptr += min_index * arrays[i].BufferBinding->Stride; + } + + /* Re-issue the draw call. + */ + draw( ctx, + tmp_arrays, + prim, + nr_prims, + ib, + GL_TRUE, + 0, + max_index - min_index, + NULL, 0, NULL ); + + free(tmp_indices); + + free(tmp_prims); +} + + + diff --git a/lib/mesa/src/mesa/tnl/t_rebase.h b/lib/mesa/src/mesa/tnl/t_rebase.h new file mode 100644 index 000000000..d0aa9e189 --- /dev/null +++ b/lib/mesa/src/mesa/tnl/t_rebase.h @@ -0,0 +1,39 @@ +/* + * mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _T_REBASE_H_ +#define _T_REBASE_H_ + +#include "tnl.h" + +void t_rebase_prims( struct gl_context *ctx, + const struct tnl_vertex_array *arrays, + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index, + tnl_draw_func draw ); + +#endif diff --git a/lib/mesa/src/mesa/tnl/t_split.c b/lib/mesa/src/mesa/tnl/t_split.c new file mode 100644 index 000000000..d7aac10e4 --- /dev/null +++ b/lib/mesa/src/mesa/tnl/t_split.c @@ -0,0 +1,160 @@ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <keithw@vmware.com> + */ + +/* Deal with hardware and/or swtnl maximums: + * - maximum number of vertices in buffer + * - maximum number of elements (maybe zero) + * + * The maximums may vary with opengl state (eg if a larger hardware + * vertex is required in this state, the maximum number of vertices + * may be smaller than in another state). + * + * We want buffer splitting to be a convenience function for the code + * actually drawing the primitives rather than a system-wide maximum, + * otherwise it is hard to avoid pessimism. + * + * For instance, if a driver has no hardware limits on vertex buffer + * dimensions, it would not ordinarily want to split vbos. But if + * there is an unexpected fallback, eg memory manager fails to upload + * textures, it will want to pass the drawing commands onto swtnl, + * which does have limitations. A convenience function allows swtnl + * to split the drawing and vbos internally without imposing its + * limitations on drivers which want to use it as a fallback path. + */ + +#include "main/glheader.h" +#include "main/mtypes.h" +#include "vbo/vbo.h" + +#include "t_split.h" + + +/* True if a primitive can be split without copying of vertices, false + * otherwise. + */ +GLboolean +_tnl_split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr) +{ + switch (mode) { + case GL_POINTS: + *first = 1; + *incr = 1; + return GL_TRUE; + case GL_LINES: + *first = 2; + *incr = 2; + return GL_TRUE; + case GL_LINE_STRIP: + *first = 2; + *incr = 1; + return GL_TRUE; + case GL_TRIANGLES: + *first = 3; + *incr = 3; + return GL_TRUE; + case GL_TRIANGLE_STRIP: + *first = 3; + *incr = 1; + return GL_TRUE; + case GL_QUADS: + *first = 4; + *incr = 4; + return GL_TRUE; + case GL_QUAD_STRIP: + *first = 4; + *incr = 2; + return GL_TRUE; + default: + *first = 0; + *incr = 1; /* so that count % incr works */ + return GL_FALSE; + } +} + + + +void +_tnl_split_prims(struct gl_context *ctx, + const struct tnl_vertex_array arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index, + tnl_draw_func draw, + const struct split_limits *limits) +{ + if (ib) { + if (limits->max_indices == 0) { + /* Could traverse the indices, re-emitting vertices in turn. + * But it's hard to see why this case would be needed - for + * software tnl, it is better to convert to non-indexed + * rendering after transformation is complete. Are there any devices + * with hardware tnl that cannot do indexed rendering? + * + * For now, this path is disabled. + */ + assert(0); + } + else if (max_index - min_index >= limits->max_verts) { + /* The vertex buffers are too large for hardware (or the + * swtnl module). Traverse the indices, re-emitting vertices + * in turn. Use a vertex cache to preserve some of the + * sharing from the original index list. + */ + _tnl_split_copy(ctx, arrays, prim, nr_prims, ib, draw, limits); + } + else if (ib->count > limits->max_indices) { + /* The index buffer is too large for hardware. Try to split + * on whole-primitive boundaries, otherwise try to split the + * individual primitives. + */ + _tnl_split_inplace(ctx, arrays, prim, nr_prims, ib, + min_index, max_index, draw, limits); + } + else { + /* Why were we called? */ + assert(0); + } + } + else { + if (max_index - min_index >= limits->max_verts) { + /* The vertex buffer is too large for hardware (or the swtnl + * module). Try to split on whole-primitive boundaries, + * otherwise try to split the individual primitives. + */ + _tnl_split_inplace(ctx, arrays, prim, nr_prims, ib, + min_index, max_index, draw, limits); + } + else { + /* Why were we called? */ + assert(0); + } + } +} + diff --git a/lib/mesa/src/mesa/tnl/t_split.h b/lib/mesa/src/mesa/tnl/t_split.h new file mode 100644 index 000000000..49017e5df --- /dev/null +++ b/lib/mesa/src/mesa/tnl/t_split.h @@ -0,0 +1,74 @@ +/* + * mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \brief VBO builder module datatypes and definitions. + * \author Keith Whitwell + */ + + +/** + * \mainpage The TNL splitter + * + * This is the private data used internally to the _tnl_split_prims() + * helper function. Nobody outside the _tnl_split* files needs to + * include or know about this structure. + */ + + +#ifndef _TNL_SPLIT_H +#define _TNL_SPLIT_H + +#include "tnl.h" + + +/* True if a primitive can be split without copying of vertices, false + * otherwise. + */ +GLboolean +_tnl_split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr); + +void +_tnl_split_inplace(struct gl_context *ctx, + const struct tnl_vertex_array arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index, + tnl_draw_func draw, + const struct split_limits *limits); + +/* Requires ib != NULL: + */ +void +_tnl_split_copy(struct gl_context *ctx, + const struct tnl_vertex_array arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + tnl_draw_func draw, + const struct split_limits *limits); + +#endif diff --git a/lib/mesa/src/mesa/tnl/t_split_copy.c b/lib/mesa/src/mesa/tnl/t_split_copy.c new file mode 100644 index 000000000..085ae9a28 --- /dev/null +++ b/lib/mesa/src/mesa/tnl/t_split_copy.c @@ -0,0 +1,650 @@ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <keithw@vmware.com> + */ + +/* Split indexed primitives with per-vertex copying. + */ + +#include <stdio.h> + +#include "main/glheader.h" +#include "main/bufferobj.h" +#include "main/imports.h" +#include "main/glformats.h" +#include "main/macros.h" +#include "main/mtypes.h" +#include "main/varray.h" +#include "vbo/vbo.h" + +#include "t_split.h" +#include "tnl.h" + + +#define ELT_TABLE_SIZE 16 + +/** + * Used for vertex-level splitting of indexed buffers. Note that + * non-indexed primitives may be converted to indexed in some cases + * (eg loops, fans) in order to use this splitting path. + */ +struct copy_context { + struct gl_context *ctx; + const struct tnl_vertex_array *array; + const struct _mesa_prim *prim; + GLuint nr_prims; + const struct _mesa_index_buffer *ib; + tnl_draw_func draw; + + const struct split_limits *limits; + + struct { + GLuint attr; + GLuint size; + const struct tnl_vertex_array *array; + const GLubyte *src_ptr; + + struct gl_vertex_buffer_binding dstbinding; + struct gl_array_attributes dstattribs; + + } varying[VERT_ATTRIB_MAX]; + GLuint nr_varying; + + struct tnl_vertex_array dstarray[VERT_ATTRIB_MAX]; + struct _mesa_index_buffer dstib; + + GLuint *translated_elt_buf; + const GLuint *srcelt; + + /** A baby hash table to avoid re-emitting (some) duplicate + * vertices when splitting indexed primitives. + */ + struct { + GLuint in; + GLuint out; + } vert_cache[ELT_TABLE_SIZE]; + + GLuint vertex_size; + GLubyte *dstbuf; + GLubyte *dstptr; /**< dstptr == dstbuf + dstelt_max * vertsize */ + GLuint dstbuf_size; /**< in vertices */ + GLuint dstbuf_nr; /**< count of emitted vertices, also the largest value + * in dstelt. Our MaxIndex. + */ + + GLuint *dstelt; + GLuint dstelt_nr; + GLuint dstelt_size; + +#define MAX_PRIM 32 + struct _mesa_prim dstprim[MAX_PRIM]; + GLuint dstprim_nr; +}; + + +static GLuint +attr_size(const struct gl_array_attributes *attrib) +{ + return attrib->Size * _mesa_sizeof_type(attrib->Type); +} + + +/** + * Shallow copy one vertex array to another. + */ +static inline void +copy_vertex_array(struct tnl_vertex_array *dst, + const struct tnl_vertex_array *src) +{ + dst->VertexAttrib = src->VertexAttrib; + dst->BufferBinding = src->BufferBinding; +} + + +/** + * Starts returning true slightly before the buffer fills, to ensure + * that there is sufficient room for any remaining vertices to finish + * off the prim: + */ +static GLboolean +check_flush(struct copy_context *copy) +{ + GLenum mode = copy->dstprim[copy->dstprim_nr].mode; + + if (GL_TRIANGLE_STRIP == mode && + copy->dstelt_nr & 1) { /* see bug9962 */ + return GL_FALSE; + } + + if (copy->dstbuf_nr + 4 > copy->dstbuf_size) + return GL_TRUE; + + if (copy->dstelt_nr + 4 > copy->dstelt_size) + return GL_TRUE; + + return GL_FALSE; +} + + +/** + * Dump the parameters/info for a vbo->draw() call. + */ +static void +dump_draw_info(struct gl_context *ctx, + const struct tnl_vertex_array *arrays, + const struct _mesa_prim *prims, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index) +{ + GLuint i, j; + + printf("VBO Draw:\n"); + for (i = 0; i < nr_prims; i++) { + printf("Prim %u of %u\n", i, nr_prims); + printf(" Prim mode 0x%x\n", prims[i].mode); + printf(" IB: %p\n", (void*) ib); + for (j = 0; j < VERT_ATTRIB_MAX; j++) { + const struct tnl_vertex_array *array = &arrays[j]; + const struct gl_vertex_buffer_binding *binding + = array->BufferBinding; + const struct gl_array_attributes *attrib = array->VertexAttrib; + const GLubyte *ptr = _mesa_vertex_attrib_address(attrib, binding); + printf(" array %d at %p:\n", j, (void*) &arrays[j]); + printf(" ptr %p, size %d, type 0x%x, stride %d\n", + ptr, attrib->Size, attrib->Type, binding->Stride); + if (0) { + GLint k = prims[i].start + prims[i].count - 1; + GLfloat *last = (GLfloat *) (ptr + binding->Stride * k); + printf(" last: %f %f %f\n", + last[0], last[1], last[2]); + } + } + } +} + + +static void +flush(struct copy_context *copy) +{ + struct gl_context *ctx = copy->ctx; + GLuint i; + + /* Set some counters: + */ + copy->dstib.count = copy->dstelt_nr; + +#if 0 + dump_draw_info(copy->ctx, + copy->dstarray, + copy->dstprim, + copy->dstprim_nr, + ©->dstib, + 0, + copy->dstbuf_nr); +#else + (void) dump_draw_info; +#endif + + copy->draw(ctx, + copy->dstarray, + copy->dstprim, + copy->dstprim_nr, + ©->dstib, + GL_TRUE, + 0, + copy->dstbuf_nr - 1, + NULL, 0, NULL); + + /* Reset all pointers: + */ + copy->dstprim_nr = 0; + copy->dstelt_nr = 0; + copy->dstbuf_nr = 0; + copy->dstptr = copy->dstbuf; + + /* Clear the vertex cache: + */ + for (i = 0; i < ELT_TABLE_SIZE; i++) + copy->vert_cache[i].in = ~0; +} + + +/** + * Called at begin of each primitive during replay. + */ +static void +begin(struct copy_context *copy, GLenum mode, GLboolean begin_flag) +{ + struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; + + prim->mode = mode; + prim->begin = begin_flag; + prim->num_instances = 1; +} + + +/** + * Use a hashtable to attempt to identify recently-emitted vertices + * and avoid re-emitting them. + */ +static GLuint +elt(struct copy_context *copy, GLuint elt_idx) +{ + GLuint elt = copy->srcelt[elt_idx] + copy->prim->basevertex; + GLuint slot = elt & (ELT_TABLE_SIZE-1); + + /* Look up the incoming element in the vertex cache. Re-emit if + * necessary. + */ + if (copy->vert_cache[slot].in != elt) { + GLubyte *csr = copy->dstptr; + GLuint i; + + for (i = 0; i < copy->nr_varying; i++) { + const struct tnl_vertex_array *srcarray = copy->varying[i].array; + const struct gl_vertex_buffer_binding* srcbinding + = srcarray->BufferBinding; + const GLubyte *srcptr + = copy->varying[i].src_ptr + elt * srcbinding->Stride; + + memcpy(csr, srcptr, copy->varying[i].size); + csr += copy->varying[i].size; + +#ifdef NAN_CHECK + if (srcarray->Type == GL_FLOAT) { + GLuint k; + GLfloat *f = (GLfloat *) srcptr; + for (k = 0; k < srcarray->Size; k++) { + assert(!IS_INF_OR_NAN(f[k])); + assert(f[k] <= 1.0e20 && f[k] >= -1.0e20); + } + } +#endif + + if (0) { + const GLuint *f = (const GLuint *)srcptr; + GLuint j; + printf(" varying %d: ", i); + for (j = 0; j < copy->varying[i].size / 4; j++) + printf("%x ", f[j]); + printf("\n"); + } + } + + copy->vert_cache[slot].in = elt; + copy->vert_cache[slot].out = copy->dstbuf_nr++; + copy->dstptr += copy->vertex_size; + + assert(csr == copy->dstptr); + assert(copy->dstptr == (copy->dstbuf + + copy->dstbuf_nr * copy->vertex_size)); + } + + copy->dstelt[copy->dstelt_nr++] = copy->vert_cache[slot].out; + return check_flush(copy); +} + + +/** + * Called at end of each primitive during replay. + */ +static void +end(struct copy_context *copy, GLboolean end_flag) +{ + struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; + + prim->end = end_flag; + prim->count = copy->dstelt_nr - prim->start; + + if (++copy->dstprim_nr == MAX_PRIM || check_flush(copy)) { + flush(copy); + } +} + + +static void +replay_elts(struct copy_context *copy) +{ + GLuint i, j, k; + GLboolean split; + + for (i = 0; i < copy->nr_prims; i++) { + const struct _mesa_prim *prim = ©->prim[i]; + const GLuint start = prim->start; + GLuint first, incr; + + switch (prim->mode) { + case GL_LINE_LOOP: + /* Convert to linestrip and emit the final vertex explicitly, + * but only in the resultant strip that requires it. + */ + j = 0; + while (j != prim->count) { + begin(copy, GL_LINE_STRIP, prim->begin && j == 0); + + for (split = GL_FALSE; j != prim->count && !split; j++) + split = elt(copy, start + j); + + if (j == prim->count) { + /* Done, emit final line. Split doesn't matter as + * it is always raised a bit early so we can emit + * the last verts if necessary! + */ + if (prim->end) + (void)elt(copy, start + 0); + + end(copy, prim->end); + } + else { + /* Wrap + */ + assert(split); + end(copy, 0); + j--; + } + } + break; + + case GL_TRIANGLE_FAN: + case GL_POLYGON: + j = 2; + while (j != prim->count) { + begin(copy, prim->mode, prim->begin && j == 0); + + split = elt(copy, start+0); + assert(!split); + + split = elt(copy, start+j-1); + assert(!split); + + for (; j != prim->count && !split; j++) + split = elt(copy, start+j); + + end(copy, prim->end && j == prim->count); + + if (j != prim->count) { + /* Wrapped the primitive, need to repeat some vertices: + */ + j -= 1; + } + } + break; + + default: + (void)_tnl_split_prim_inplace(prim->mode, &first, &incr); + + j = 0; + while (j != prim->count) { + + begin(copy, prim->mode, prim->begin && j == 0); + + split = 0; + for (k = 0; k < first; k++, j++) + split |= elt(copy, start+j); + + assert(!split); + + for (; j != prim->count && !split;) + for (k = 0; k < incr; k++, j++) + split |= elt(copy, start+j); + + end(copy, prim->end && j == prim->count); + + if (j != prim->count) { + /* Wrapped the primitive, need to repeat some vertices: + */ + assert(j > first - incr); + j -= (first - incr); + } + } + break; + } + } + + if (copy->dstprim_nr) + flush(copy); +} + + +static void +replay_init(struct copy_context *copy) +{ + struct gl_context *ctx = copy->ctx; + GLuint i; + GLuint offset; + const GLvoid *srcptr; + + /* Make a list of varying attributes and their vbo's. Also + * calculate vertex size. + */ + copy->vertex_size = 0; + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + const struct tnl_vertex_array *array = ©->array[i]; + const struct gl_vertex_buffer_binding *binding = array->BufferBinding; + + if (binding->Stride == 0) { + copy_vertex_array(©->dstarray[i], array); + } + else { + const struct gl_array_attributes *attrib = array->VertexAttrib; + struct gl_buffer_object *vbo = binding->BufferObj; + const GLubyte *ptr = _mesa_vertex_attrib_address(attrib, binding); + GLuint j = copy->nr_varying++; + + copy->varying[j].attr = i; + copy->varying[j].array = ©->array[i]; + copy->varying[j].size = attr_size(attrib); + copy->vertex_size += attr_size(attrib); + + if (_mesa_is_bufferobj(vbo) && + !_mesa_bufferobj_mapped(vbo, MAP_INTERNAL)) + ctx->Driver.MapBufferRange(ctx, 0, vbo->Size, GL_MAP_READ_BIT, vbo, + MAP_INTERNAL); + + copy->varying[j].src_ptr = + ADD_POINTERS(vbo->Mappings[MAP_INTERNAL].Pointer, ptr); + + copy->dstarray[i].VertexAttrib = ©->varying[j].dstattribs; + copy->dstarray[i].BufferBinding = ©->varying[j].dstbinding; + } + } + + /* There must always be an index buffer. Currently require the + * caller convert non-indexed prims to indexed. Could alternately + * do it internally. + */ + if (_mesa_is_bufferobj(copy->ib->obj) && + !_mesa_bufferobj_mapped(copy->ib->obj, MAP_INTERNAL)) + ctx->Driver.MapBufferRange(ctx, 0, copy->ib->obj->Size, GL_MAP_READ_BIT, + copy->ib->obj, MAP_INTERNAL); + + srcptr = (const GLubyte *) + ADD_POINTERS(copy->ib->obj->Mappings[MAP_INTERNAL].Pointer, + copy->ib->ptr); + + switch (copy->ib->index_size) { + case 1: + copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count); + copy->srcelt = copy->translated_elt_buf; + + for (i = 0; i < copy->ib->count; i++) + copy->translated_elt_buf[i] = ((const GLubyte *)srcptr)[i]; + break; + + case 2: + copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count); + copy->srcelt = copy->translated_elt_buf; + + for (i = 0; i < copy->ib->count; i++) + copy->translated_elt_buf[i] = ((const GLushort *)srcptr)[i]; + break; + + case 4: + copy->translated_elt_buf = NULL; + copy->srcelt = (const GLuint *)srcptr; + break; + } + + /* Figure out the maximum allowed vertex buffer size: + */ + if (copy->vertex_size * copy->limits->max_verts <= copy->limits->max_vb_size) { + copy->dstbuf_size = copy->limits->max_verts; + } + else { + copy->dstbuf_size = copy->limits->max_vb_size / copy->vertex_size; + } + + /* Allocate an output vertex buffer: + * + * XXX: This should be a VBO! + */ + copy->dstbuf = malloc(copy->dstbuf_size * copy->vertex_size); + copy->dstptr = copy->dstbuf; + + /* Setup new vertex arrays to point into the output buffer: + */ + for (offset = 0, i = 0; i < copy->nr_varying; i++) { + const struct tnl_vertex_array *src = copy->varying[i].array; + const struct gl_array_attributes *srcattr = src->VertexAttrib; + struct tnl_vertex_array *dst = ©->dstarray[copy->varying[i].attr]; + struct gl_vertex_buffer_binding *dstbind = ©->varying[i].dstbinding; + struct gl_array_attributes *dstattr = ©->varying[i].dstattribs; + + dstattr->Size = srcattr->Size; + dstattr->Type = srcattr->Type; + dstattr->Format = GL_RGBA; + dstbind->Stride = copy->vertex_size; + dstattr->Ptr = copy->dstbuf + offset; + dstattr->Normalized = srcattr->Normalized; + dstattr->Integer = srcattr->Integer; + dstattr->Doubles = srcattr->Doubles; + dstbind->BufferObj = ctx->Shared->NullBufferObj; + dstattr->_ElementSize = srcattr->_ElementSize; + dst->BufferBinding = dstbind; + dst->VertexAttrib = dstattr; + + offset += copy->varying[i].size; + } + + /* Allocate an output element list: + */ + copy->dstelt_size = MIN2(65536, copy->ib->count * 2 + 3); + copy->dstelt_size = MIN2(copy->dstelt_size, copy->limits->max_indices); + copy->dstelt = malloc(sizeof(GLuint) * copy->dstelt_size); + copy->dstelt_nr = 0; + + /* Setup the new index buffer to point to the allocated element + * list: + */ + copy->dstib.count = 0; /* duplicates dstelt_nr */ + copy->dstib.index_size = 4; + copy->dstib.obj = ctx->Shared->NullBufferObj; + copy->dstib.ptr = copy->dstelt; +} + + +/** + * Free up everything allocated during split/replay. + */ +static void +replay_finish(struct copy_context *copy) +{ + struct gl_context *ctx = copy->ctx; + GLuint i; + + /* Free our vertex and index buffers */ + free(copy->translated_elt_buf); + free(copy->dstbuf); + free(copy->dstelt); + + /* Unmap VBO's */ + for (i = 0; i < copy->nr_varying; i++) { + struct gl_buffer_object *vbo = + copy->varying[i].array->BufferBinding->BufferObj; + if (_mesa_is_bufferobj(vbo) && _mesa_bufferobj_mapped(vbo, MAP_INTERNAL)) + ctx->Driver.UnmapBuffer(ctx, vbo, MAP_INTERNAL); + } + + /* Unmap index buffer */ + if (_mesa_is_bufferobj(copy->ib->obj) && + _mesa_bufferobj_mapped(copy->ib->obj, MAP_INTERNAL)) { + ctx->Driver.UnmapBuffer(ctx, copy->ib->obj, MAP_INTERNAL); + } +} + + +/** + * Split VBO into smaller pieces, draw the pieces. + */ +void +_tnl_split_copy(struct gl_context *ctx, + const struct tnl_vertex_array *arrays, + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + tnl_draw_func draw, + const struct split_limits *limits) +{ + struct copy_context copy; + GLuint i, this_nr_prims; + + for (i = 0; i < nr_prims;) { + /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices + * will rebase the elements to the basevertex, and we'll only + * emit strings of prims with the same basevertex in one draw call. + */ + for (this_nr_prims = 1; i + this_nr_prims < nr_prims; + this_nr_prims++) { + if (prim[i].basevertex != prim[i + this_nr_prims].basevertex) + break; + } + + memset(©, 0, sizeof(copy)); + + /* Require indexed primitives: + */ + assert(ib); + + copy.ctx = ctx; + copy.array = arrays; + copy.prim = &prim[i]; + copy.nr_prims = this_nr_prims; + copy.ib = ib; + copy.draw = draw; + copy.limits = limits; + + /* Clear the vertex cache: + */ + for (i = 0; i < ELT_TABLE_SIZE; i++) + copy.vert_cache[i].in = ~0; + + replay_init(©); + replay_elts(©); + replay_finish(©); + } +} diff --git a/lib/mesa/src/mesa/tnl/t_split_inplace.c b/lib/mesa/src/mesa/tnl/t_split_inplace.c new file mode 100644 index 000000000..8e9ecb704 --- /dev/null +++ b/lib/mesa/src/mesa/tnl/t_split_inplace.c @@ -0,0 +1,298 @@ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <keithw@vmware.com> + */ + + +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/enums.h" +#include "vbo/vbo.h" + +#include "t_split.h" + + +#define MAX_PRIM 32 + +/* Used for splitting without copying. No attempt is made to handle + * too large indexed vertex buffers: In general you need to copy to do + * that. + */ +struct split_context { + struct gl_context *ctx; + const struct tnl_vertex_array *array; + const struct _mesa_prim *prim; + GLuint nr_prims; + const struct _mesa_index_buffer *ib; + GLuint min_index; + GLuint max_index; + tnl_draw_func draw; + + const struct split_limits *limits; + GLuint limit; + + struct _mesa_prim dstprim[MAX_PRIM]; + GLuint dstprim_nr; +}; + + + + +static void +flush_vertex( struct split_context *split) +{ + struct gl_context *ctx = split->ctx; + struct _mesa_index_buffer ib; + GLuint i; + + if (!split->dstprim_nr) + return; + + if (split->ib) { + ib = *split->ib; + + ib.count = split->max_index - split->min_index + 1; + ib.ptr = (const void *)((const char *)ib.ptr + + split->min_index * ib.index_size); + + /* Rebase the primitives to save index buffer entries. */ + for (i = 0; i < split->dstprim_nr; i++) + split->dstprim[i].start -= split->min_index; + } + + assert(split->max_index >= split->min_index); + + split->draw(ctx, + split->array, + split->dstprim, + split->dstprim_nr, + split->ib ? &ib : NULL, + !split->ib, + split->min_index, + split->max_index, + NULL, 0, NULL); + + split->dstprim_nr = 0; + split->min_index = ~0; + split->max_index = 0; +} + + +static struct _mesa_prim * +next_outprim(struct split_context *split) +{ + if (split->dstprim_nr == MAX_PRIM-1) { + flush_vertex(split); + } + + { + struct _mesa_prim *prim = &split->dstprim[split->dstprim_nr++]; + memset(prim, 0, sizeof(*prim)); + return prim; + } +} + + +static void +update_index_bounds(struct split_context *split, + const struct _mesa_prim *prim) +{ + split->min_index = MIN2(split->min_index, prim->start); + split->max_index = MAX2(split->max_index, prim->start + prim->count - 1); +} + + +/* Return the maximum amount of vertices that can be emitted for a + * primitive starting at 'prim->start', depending on the previous + * index bounds. + */ +static GLuint +get_max_vertices(struct split_context *split, + const struct _mesa_prim *prim) +{ + if ((prim->start > split->min_index && + prim->start - split->min_index >= split->limit) || + (prim->start < split->max_index && + split->max_index - prim->start >= split->limit)) + /* "prim" starts too far away from the old range. */ + return 0; + + return MIN2(split->min_index, prim->start) + split->limit - prim->start; +} + + +/* Break large primitives into smaller ones. If not possible, convert + * the primitive to indexed and pass to split_elts(). + */ +static void +split_prims(struct split_context *split) +{ + GLuint i; + + for (i = 0; i < split->nr_prims; i++) { + const struct _mesa_prim *prim = &split->prim[i]; + GLuint first, incr; + GLboolean split_inplace = + _tnl_split_prim_inplace(prim->mode, &first, &incr); + GLuint available = get_max_vertices(split, prim); + GLuint count = prim->count - (prim->count - first) % incr; + + if (prim->count < first) + continue; + + if ((available < count && !split_inplace) || + (available < first && split_inplace)) { + flush_vertex(split); + available = get_max_vertices(split, prim); + } + + if (available >= count) { + struct _mesa_prim *outprim = next_outprim(split); + + *outprim = *prim; + update_index_bounds(split, outprim); + } + else if (split_inplace) { + GLuint j, nr; + + for (j = 0 ; j < count ;) { + GLuint remaining = count - j; + struct _mesa_prim *outprim = next_outprim(split); + + nr = MIN2(available, remaining); + nr -= (nr - first) % incr; + + outprim->mode = prim->mode; + outprim->begin = (j == 0 && prim->begin); + outprim->end = (nr == remaining && prim->end); + outprim->start = prim->start + j; + outprim->count = nr; + outprim->num_instances = prim->num_instances; + outprim->base_instance = prim->base_instance; + + update_index_bounds(split, outprim); + + if (nr == remaining) { + /* Finished */ + j += nr; + } + else { + /* Wrapped the primitive */ + j += nr - (first - incr); + flush_vertex(split); + available = get_max_vertices(split, prim); + } + } + } + else if (split->ib == NULL) { + /* XXX: could at least send the first max_verts off from the + * inplace buffers. + */ + + /* else convert to indexed primitive and pass to split_elts, + * which will do the necessary copying and turn it back into a + * vertex primitive for rendering... + */ + struct _mesa_index_buffer ib; + struct _mesa_prim tmpprim; + GLuint *elts = malloc(count * sizeof(GLuint)); + GLuint j; + + for (j = 0; j < count; j++) + elts[j] = prim->start + j; + + ib.count = count; + ib.index_size = 4; + ib.obj = split->ctx->Shared->NullBufferObj; + ib.ptr = elts; + + tmpprim = *prim; + tmpprim.indexed = 1; + tmpprim.start = 0; + tmpprim.count = count; + tmpprim.num_instances = 1; + tmpprim.base_instance = 0; + + flush_vertex(split); + + _tnl_split_copy(split->ctx, + split->array, + &tmpprim, 1, + &ib, + split->draw, + split->limits); + + free(elts); + } + else { + flush_vertex(split); + + _tnl_split_copy(split->ctx, + split->array, + prim, 1, + split->ib, + split->draw, + split->limits); + } + } + + flush_vertex(split); +} + + +void +_tnl_split_inplace(struct gl_context *ctx, + const struct tnl_vertex_array *arrays, + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index, + tnl_draw_func draw, + const struct split_limits *limits) +{ + struct split_context split; + + memset(&split, 0, sizeof(split)); + + split.ctx = ctx; + split.array = arrays; + split.prim = prim; + split.nr_prims = nr_prims; + split.ib = ib; + + /* Empty interval, makes calculations simpler. */ + split.min_index = ~0; + split.max_index = 0; + + split.draw = draw; + split.limits = limits; + split.limit = ib ? limits->max_indices : limits->max_verts; + + split_prims(&split); +} + + diff --git a/lib/mesa/src/mesa/tnl/t_vb_fog.c b/lib/mesa/src/mesa/tnl/t_vb_fog.c index 5489ed685..c224a4192 100644 --- a/lib/mesa/src/mesa/tnl/t_vb_fog.c +++ b/lib/mesa/src/mesa/tnl/t_vb_fog.c @@ -27,6 +27,7 @@ #include "c99_math.h" +#include "main/errors.h" #include "main/glheader.h" #include "main/macros.h" #include "main/imports.h" diff --git a/lib/mesa/src/mesa/tnl/t_vb_texgen.c b/lib/mesa/src/mesa/tnl/t_vb_texgen.c index 94066f4f6..bd585324e 100644 --- a/lib/mesa/src/mesa/tnl/t_vb_texgen.c +++ b/lib/mesa/src/mesa/tnl/t_vb_texgen.c @@ -34,6 +34,7 @@ * including any use thereof or modifications thereto. */ +#include "main/errors.h" #include "main/glheader.h" #include "main/macros.h" #include "main/imports.h" @@ -337,7 +338,8 @@ static void texgen( struct gl_context *ctx, struct vertex_buffer *VB = &tnl->vb; GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit]; GLvector4f *out = &store->texcoord[unit]; - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + const struct gl_fixedfunc_texture_unit *texUnit = + &ctx->Texture.FixedFuncUnit[unit]; const GLvector4f *obj = VB->AttribPtr[_TNL_ATTRIB_POS]; const GLvector4f *eye = VB->EyePtr; const GLvector4f *normal = VB->AttribPtr[_TNL_ATTRIB_NORMAL]; @@ -489,10 +491,10 @@ static GLboolean run_texgen_stage( struct gl_context *ctx, return GL_TRUE; for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; + struct gl_fixedfunc_texture_unit *texUnit = + &ctx->Texture.FixedFuncUnit[i]; if (texUnit->TexGenEnabled) { - store->TexgenFunc[i]( ctx, store, i ); VB->AttribPtr[VERT_ATTRIB_TEX0 + i] = &store->texcoord[i]; @@ -513,7 +515,8 @@ static void validate_texgen_stage( struct gl_context *ctx, return; for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; + struct gl_fixedfunc_texture_unit *texUnit = + &ctx->Texture.FixedFuncUnit[i]; if (texUnit->TexGenEnabled) { GLuint sz; diff --git a/lib/mesa/src/mesa/tnl/t_vb_vertex.c b/lib/mesa/src/mesa/tnl/t_vb_vertex.c index 71a32b495..4fb3659a3 100644 --- a/lib/mesa/src/mesa/tnl/t_vb_vertex.c +++ b/lib/mesa/src/mesa/tnl/t_vb_vertex.c @@ -123,7 +123,7 @@ tnl_clip_prepare(struct gl_context *ctx) /* Neither the x86 nor sparc asm cliptest functions have been updated * for ARB_depth_clamp, so force the C paths. */ - if (ctx->Transform.DepthClamp) { + if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) { static GLboolean c_funcs_installed = GL_FALSE; if (!c_funcs_installed) { init_c_cliptest(); @@ -191,7 +191,8 @@ static GLboolean run_vertex_stage( struct gl_context *ctx, store->clipmask, &store->ormask, &store->andmask, - !ctx->Transform.DepthClamp ); + !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar) ); } else { VB->NdcPtr = NULL; @@ -200,7 +201,8 @@ static GLboolean run_vertex_stage( struct gl_context *ctx, store->clipmask, &store->ormask, &store->andmask, - !ctx->Transform.DepthClamp ); + !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar) ); } if (store->andmask) diff --git a/lib/mesa/src/mesa/vbo/vbo_noop.h b/lib/mesa/src/mesa/vbo/vbo_noop.h index f61cd5136..0ca1bfa8e 100644 --- a/lib/mesa/src/mesa/vbo/vbo_noop.h +++ b/lib/mesa/src/mesa/vbo/vbo_noop.h @@ -23,12 +23,12 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef _API_NOOP_H -#define _API_NOOP_H +#ifndef VBO_NOOP_H +#define VBO_NOOP_H +#include "main/dd.h" -#include "main/mtypes.h" - +struct _glapi_table; extern void _mesa_noop_vtxfmt_init(GLvertexformat *vfmt); @@ -37,4 +37,4 @@ extern GLboolean _mesa_using_noop_vtxfmt(const struct _glapi_table *dispatch); -#endif /* _API_NOOP_H */ +#endif /* VBO_NOOP_H */ diff --git a/lib/mesa/src/mesa/vbo/vbo_private.h b/lib/mesa/src/mesa/vbo/vbo_private.h new file mode 100644 index 000000000..86f6b41b7 --- /dev/null +++ b/lib/mesa/src/mesa/vbo/vbo_private.h @@ -0,0 +1,232 @@ +/* + * mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * Types, functions, etc which are private to the VBO module. + */ + + +#ifndef VBO_PRIVATE_H +#define VBO_PRIVATE_H + + +#include "vbo/vbo_attrib.h" +#include "vbo/vbo_exec.h" +#include "vbo/vbo_save.h" +#include "main/varray.h" + + +struct _glapi_table; +struct _mesa_prim; + + +struct vbo_context { + struct gl_vertex_buffer_binding binding; + struct gl_array_attributes current[VBO_ATTRIB_MAX]; + + struct gl_vertex_array_object *VAO; + + struct vbo_exec_context exec; + struct vbo_save_context save; +}; + + +static inline struct vbo_context * +vbo_context(struct gl_context *ctx) +{ + return ctx->vbo_context; +} + + +static inline const struct vbo_context * +vbo_context_const(const struct gl_context *ctx) +{ + return ctx->vbo_context; +} + + +/** + * Array to apply the fixed function material aliasing map to + * an attribute value used in vbo processing inputs to an attribute + * as they appear in the vao. + */ +extern const GLubyte +_vbo_attribute_alias_map[VP_MODE_MAX][VERT_ATTRIB_MAX]; + + +/** + * Return if format is integer. The immediate mode commands only emit floats + * for non-integer types, thus everything else is integer. + */ +static inline GLboolean +vbo_attrtype_to_integer_flag(GLenum format) +{ + switch (format) { + case GL_FLOAT: + case GL_DOUBLE: + return GL_FALSE; + case GL_INT: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT64_ARB: + return GL_TRUE; + default: + unreachable("Bad vertex attribute type"); + return GL_FALSE; + } +} + +static inline GLboolean +vbo_attrtype_to_double_flag(GLenum format) +{ + switch (format) { + case GL_FLOAT: + case GL_INT: + case GL_UNSIGNED_INT: + return GL_FALSE; + case GL_UNSIGNED_INT64_ARB: + case GL_DOUBLE: + return GL_TRUE; + default: + unreachable("Bad vertex attribute type"); + return GL_FALSE; + } +} + + +/** + * Return default component values for the given format. + * The return type is an array of fi_types, because that's how we declare + * the vertex storage : floats , integers or unsigned integers. + */ +static inline const fi_type * +vbo_get_default_vals_as_union(GLenum format) +{ + static const GLfloat default_float[4] = { 0, 0, 0, 1 }; + static const GLint default_int[4] = { 0, 0, 0, 1 }; + + switch (format) { + case GL_FLOAT: + return (fi_type *)default_float; + case GL_INT: + case GL_UNSIGNED_INT: + return (fi_type *)default_int; + default: + unreachable("Bad vertex format"); + return NULL; + } +} + + +/** + * Compute the max number of vertices which can be stored in + * a vertex buffer, given the current vertex size, and the amount + * of space already used. + */ +static inline unsigned +vbo_compute_max_verts(const struct vbo_exec_context *exec) +{ + unsigned n = (VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) / + (exec->vtx.vertex_size * sizeof(GLfloat)); + if (n == 0) + return 0; + /* Subtract one so we're always sure to have room for an extra + * vertex for GL_LINE_LOOP -> GL_LINE_STRIP conversion. + */ + n--; + return n; +} + + +void +vbo_try_prim_conversion(struct _mesa_prim *p); + +bool +vbo_can_merge_prims(const struct _mesa_prim *p0, const struct _mesa_prim *p1); + +void +vbo_merge_prims(struct _mesa_prim *p0, const struct _mesa_prim *p1); + + +/** + * Get the filter mask for vbo draws depending on the vertex_processing_mode. + */ +static inline GLbitfield +_vbo_get_vao_filter(gl_vertex_processing_mode vertex_processing_mode) +{ + if (vertex_processing_mode == VP_MODE_FF) { + /* The materials mapped into the generic arrays */ + return VERT_BIT_FF_ALL | VERT_BIT_MAT_ALL; + } else { + return VERT_BIT_ALL; + } +} + + +/** + * Translate the bitmask of VBO_ATTRIB_BITs to VERT_ATTRIB_BITS. + * Note that position/generic0 attribute aliasing is done + * generically in the VAO. + */ +static inline GLbitfield +_vbo_get_vao_enabled_from_vbo(gl_vertex_processing_mode vertex_processing_mode, + GLbitfield64 enabled) +{ + if (vertex_processing_mode == VP_MODE_FF) { + /* The materials mapped into the generic arrays */ + return (((GLbitfield)enabled) & VERT_BIT_FF_ALL) + | (((GLbitfield)(enabled >> VBO_MATERIAL_SHIFT)) & VERT_BIT_MAT_ALL); + } else { + return ((GLbitfield)enabled) & VERT_BIT_ALL; + } +} + + +/** + * Set the vertex attrib for vbo draw use. + */ +static inline void +_vbo_set_attrib_format(struct gl_context *ctx, + struct gl_vertex_array_object *vao, + gl_vert_attrib attr, GLintptr buffer_offset, + GLubyte size, GLenum16 type, GLuint offset) +{ + const GLboolean integer = vbo_attrtype_to_integer_flag(type); + const GLboolean doubles = vbo_attrtype_to_double_flag(type); + + if (doubles) + size /= 2; + _mesa_update_array_format(ctx, vao, attr, size, type, GL_RGBA, + GL_FALSE, integer, doubles, offset); + /* Ptr for userspace arrays. + * For updating the pointer we would need to add the vao->NewArrays flag + * to the VAO. But but that is done already unconditionally in + * _mesa_update_array_format called above. + */ + assert((vao->NewArrays | ~vao->_Enabled) & VERT_BIT(attr)); + vao->VertexAttrib[attr].Ptr = ADD_POINTERS(buffer_offset, offset); +} + + +#endif /* VBO_PRIVATE_H */ diff --git a/lib/mesa/src/meson.build b/lib/mesa/src/meson.build new file mode 100644 index 000000000..3b91c6a88 --- /dev/null +++ b/lib/mesa/src/meson.build @@ -0,0 +1,116 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +inc_common = include_directories( + '../include', '.', 'mapi', 'mesa', 'gallium/include', 'gallium/auxiliary') +inc_mesa = include_directories('mesa') +inc_mapi = include_directories('mapi') +inc_src = include_directories('.') +inc_gallium = include_directories('gallium/include') +inc_gallium_aux = include_directories('gallium/auxiliary') +inc_amd_common = include_directories('amd/common') + +libglsl_util = static_library( + 'glsl_util', + files( + 'mesa/main/extensions_table.c', 'mesa/main/imports.c', + 'mesa/program/prog_parameter.c', 'mesa/program/symbol_table.c', + 'mesa/program/dummy_errors.c', + ), + include_directories : [inc_common], + c_args : [c_vis_args], + build_by_default : false, +) + +sha1_h = custom_target( + 'git_sha1.h', + output : 'git_sha1.h', + command : [prog_python, git_sha1_gen_py, '--output', '@OUTPUT@'], + build_always : true, # commit sha1 can change without having touched these files +) + +subdir('gtest') +subdir('util') +subdir('mapi') +# TODO: opengl +subdir('compiler') +if with_platform_wayland + subdir('egl/wayland/wayland-drm') +endif +if with_any_vk + subdir('vulkan') +endif +if with_gallium_radeonsi or with_amd_vk + subdir('amd') +endif +if with_gallium_vc4 or with_gallium_v3d + subdir('broadcom') +endif +if with_dri_i965 or with_intel_vk + subdir('intel') +endif +subdir('mesa') +subdir('loader') +if with_platform_haiku + subdir('hgl') +endif +if with_glx == 'dri' + subdir('glx') +endif +if with_gbm + subdir('gbm') +else + inc_gbm = [] +endif +if with_egl + subdir('egl') +endif +if with_gallium + subdir('gallium') + # This has to be here since it requires libgallium, and subdir cannot + # contain .. + if with_tests and with_shared_glapi + subdir('mesa/state_tracker/tests') + endif +endif + +# This must be after at least mesa, glx, and gallium, since libgl will be +# defined in one of those subdirs depending on the glx provider. +if with_glx != 'disabled' + # If using glvnd the pkg-config header should not point to GL_mesa, it should + # point to GL. glvnd is only available on unix like platforms so adding -l + # should be safe here + # TODO: in the glvnd case glvnd itself should really be providing this. + if with_glvnd + _gl = '-L${libdir} -lGL' + else + _gl = libgl + endif + + pkg.generate( + name : 'gl', + description : 'Mesa OpenGL Library', + version : meson.project_version(), + libraries : _gl, + libraries_private : gl_priv_libs, + requires_private : gl_priv_reqs, + variables : ['glx_tls=yes'], + ) +endif diff --git a/lib/mesa/src/util/00-mesa-defaults.conf b/lib/mesa/src/util/00-mesa-defaults.conf new file mode 100644 index 000000000..a937c46d0 --- /dev/null +++ b/lib/mesa/src/util/00-mesa-defaults.conf @@ -0,0 +1,338 @@ +<!-- + +============================================ +Application bugs worked around in this file: +============================================ + +* Unigine Heaven 3.0 and older contain too many bugs and can't be supported + by drivers that want to be compliant. + +* Various Unigine products don't use the #version and #extension GLSL + directives, meaning they only get GLSL 1.10 and no extensions for their + shaders. + Enabling all extensions for Unigine fixes most issues, but the GLSL version + is still 1.10. + +* If ARB_sample_shading is supported, Unigine Heaven 4.0 and Valley 1.0 uses + an #extension directive in the middle of its shaders, which is illegal + in GLSL. + +* Dying Light and Dead Island Definitive Edition redeclare vertex shader + built-ins (specifically gl_VertexID), which causes the vertex shaders to fail + to compile. + +TODO: document the other workarounds. + +--> + +<driconf> + <!-- Please always enable app-specific workarounds for all drivers and + screens. --> + <device> + <application name="Unigine Sanctuary" executable="Sanctuary"> + <option name="force_glsl_extensions_warn" value="true" /> + <option name="disable_blend_func_extended" value="true" /> + </application> + + <application name="Unigine Tropics" executable="Tropics"> + <option name="force_glsl_extensions_warn" value="true" /> + <option name="disable_blend_func_extended" value="true" /> + </application> + + <application name="Unigine Heaven (32-bit)" executable="heaven_x86"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + <!-- remove dual_color_blend_by_location if 4.1 ever comes out --> + <option name="dual_color_blend_by_location" value="true" /> + </application> + + <application name="Unigine Heaven (64-bit)" executable="heaven_x64"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + <!-- remove dual_color_blend_by_location if 4.1 ever comes out --> + <option name="dual_color_blend_by_location" value="true" /> + </application> + + <application name="Unigine Valley (32-bit)" executable="valley_x86"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + <!-- remove dual_color_blend_by_location if 1.1 ever comes out --> + <option name="dual_color_blend_by_location" value="true" /> + </application> + + <application name="Unigine Valley (64-bit)" executable="valley_x64"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + <!-- remove dual_color_blend_by_location if 1.1 ever comes out --> + <option name="dual_color_blend_by_location" value="true" /> + </application> + + <application name="Unigine OilRush (32-bit)" executable="OilRush_x86"> + <option name="disable_blend_func_extended" value="true" /> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + </application> + + <application name="Unigine OilRush (64-bit)" executable="OilRush_x64"> + <option name="disable_blend_func_extended" value="true" /> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + </application> + + <application name="Savage 2" executable="savage2.bin"> + <option name="disable_glsl_line_continuations" value="true" /> + </application> + + <application name="Topogun (32-bit)" executable="topogun32"> + <option name="always_have_depth_buffer" value="true" /> + </application> + + <application name="Topogun (64-bit)" executable="topogun64"> + <option name="always_have_depth_buffer" value="true" /> + </application> + + <application name="Dead Island (incl. Definitive Edition)" executable="DeadIslandGame"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + + <!-- For the Definitive Edition which shares the same executable name --> + <option name="allow_glsl_builtin_variable_redeclaration" value="true" /> + </application> + + <application name="Dead Island Riptide Definitive Edition" executable="DeadIslandRiptideGame"> + <option name="allow_glsl_builtin_variable_redeclaration" value="true" /> + </application> + + <application name="Dying Light" executable="DyingLightGame"> + <option name="allow_glsl_builtin_variable_redeclaration" value="true" /> + </application> + + <application name="RAGE (64-bit)" executable="Rage64.exe"> + <option name="allow_glsl_builtin_variable_redeclaration" value="true" /> + </application> + + <application name="RAGE (32-bit)" executable="Rage.exe"> + <option name="allow_glsl_builtin_variable_redeclaration" value="true" /> + </application> + + <application name="Second Life" executable="do-not-directly-run-secondlife-bin"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + </application> + + <application name="Warsow (32-bit)" executable="warsow.i386"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + </application> + + <application name="Warsow (64-bit)" executable="warsow.x86_64"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + </application> + + <application name="Rust" executable="rust"> + <option name="glsl_zero_init" value="true"/> + </application> + + <application name="Divinity: Original Sin Enhanced Edition" executable="EoCApp"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + </application> + + <application name="Metro 2033 Redux / Metro Last Night Redux" executable="metro"> + <option name="allow_glsl_extension_directive_midshader" value="true" /> + </application> + + <application name="Worms W.M.D" executable="Worms W.M.Dx64"> + <option name="allow_higher_compat_version" value="true" /> + </application> + + <application name="Crookz - The Big Heist" executable="Crookz"> + <option name="allow_higher_compat_version" value="true" /> + </application> + + <application name="Tropico 5" executable="Tropico5"> + <option name="allow_higher_compat_version" value="true" /> + </application> + + <application name="The Culling" executable="Victory"> + <option name="force_glsl_version" value="440" /> + </application> + + <application name="Spec Ops: The Line (32-bit)" executable="specops.i386"> + <option name="force_glsl_abs_sqrt" value="true" /> + </application> + + <application name="Spec Ops: The Line (64-bit)" executable="specops"> + <option name="force_glsl_abs_sqrt" value="true" /> + </application> + + <application name="Kerbal Space Program (32-bit)" executable="KSP.x86"> + <option name="glsl_zero_init" value="true"/> + </application> + + <application name="Kerbal Space Program (64-bit)" executable="KSP.x86_64"> + <option name="glsl_zero_init" value="true"/> + </application> + + <application name="Rocket League" executable="RocketLeague"> + <option name="glsl_correct_derivatives_after_discard" value="true"/> + </application> + + <application name="The Witcher 2" executable="witcher2"> + <option name="glsl_correct_derivatives_after_discard" value="true"/> + </application> + + <application name="Unreal 4 Editor" executable="UE4Editor"> + <option name="allow_glsl_cross_stage_interpolation_mismatch" value="true"/> + </application> + + <application name="Observer" executable="TheObserver-Linux-Shipping"> + <option name="allow_glsl_cross_stage_interpolation_mismatch" value="true"/> + </application> + + <application name="Steamroll" executable="Steamroll-Linux-Shipping"> + <option name="allow_glsl_cross_stage_interpolation_mismatch" value="true"/> + </application> + + <application name="Refunct" executable="Refunct-Linux-Shipping"> + <option name="allow_glsl_cross_stage_interpolation_mismatch" value="true"/> + </application> + + <application name="Google Earth VR" executable="Earth.exe"> + <option name="allow_glsl_builtin_const_expression" value="true"/> + <option name="allow_glsl_relaxed_es" value="true"/> + </application> + + <application name="No Mans Sky" executable="NMS.exe"> + <option name="force_glsl_extensions_warn" value="true" /> + <option name="allow_glsl_layout_qualifier_on_function_parameters" value="true" /> + </application> + + <application name="Wolfenstein The Old Blood" executable="WolfOldBlood_x64.exe"> + <option name="force_compat_profile" value="true" /> + </application> + + <application name="ARMA 3" executable="arma3.x86_64"> + <option name="glsl_correct_derivatives_after_discard" value="true"/> + </application> + + <!-- The GL thread whitelist is below, workarounds are above. + Keep it that way. --> + + <application name="Alien Isolation" executable="AlienIsolation"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="BioShock Infinite" executable="bioshock.i386"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Borderlands 2" executable="Borderlands2"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Civilization 5" executable="Civ5XP"> + <option name="mesa_glthread" value="true"/> + </application> + <application name="Civilization 6" executable="Civ6"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Dreamfall Chapters" executable="Dreamfall Chapters"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Hitman" executable="HitmanPro"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Renowned Explorers: International Society" executable="abbeycore_steam"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Saints Row 2" executable="saintsrow2.i386"> + <option name="mesa_glthread" value="true"/> + </application> + <application name="Saints Row: The Third" executable="SaintsRow3.i386"> + <option name="mesa_glthread" value="true"/> + </application> + <application name="Saints Row IV" executable="SaintsRow4.i386"> + <option name="mesa_glthread" value="true"/> + </application> + <application name="Saints Row: Gat out of Hell" executable="SaintsRow4GooH.i386"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Sid Meier's: Civilization Beyond Earth" executable="CivBE"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="The Witcher 2" executable="witcher2"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="American Truck Simulator" executable="amtrucks"> + <option name="mesa_glthread" value="true"/> + </application> + <application name="Euro Truck Simulator 2" executable="eurotrucks2"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Overlord" executable="overlord.i386"> + <option name="mesa_glthread" value="true"/> + </application> + <application name="Overlord 2" executable="overlord2.i386"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Oil Rush" executable="OilRush_x86"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="War Thunder" executable="aces"> + <option name="mesa_glthread" value="true"/> + </application> + <application name="War Thunder (Wine)" executable="aces.exe"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Outlast" executable="OLGame.x86_64"> + <option name="mesa_glthread" value="true"/> + </application> + + <application name="Spec Ops: The Line (32-bit)" executable="specops.i386"> + <option name="mesa_glthread" value="true"/> + </application> + <application name="Spec Ops: The Line (64-bit)" executable="specops"> + <option name="mesa_glthread" value="true"/> + </application> + <application name="Mount and Blade Warband" executable="mb_warband_linux"> + <option name="mesa_glthread" value="true"/> + </application> + + <!-- around 18% performance increase in min and avg fps, max fps capped at 60fps. --> + <application name="Medieval II: Total War" executable="Medieval2"> + <option name="mesa_glthread" value="true"/> + </application> + + <!-- min fps ~21 ===> ~27 while standing still in game, also higher gpu load. --> + <application name="Carnivores: Dinosaur Hunter Reborn (wine)" executable="Carnivores-master.exe"> + <option name="mesa_glthread" value="true"/> + </application> + + <!-- around 30% increase in avg fps --> + <application name="Far Cry 2 (wine)" executable="farcry2.exe"> + <option name="mesa_glthread" value="true"/> + </application> + </device> + <!-- vmwgfx doesn't like full buffer swaps and can't sync to vertical retraces.--> + <device driver="vmwgfx"> + <application name="gnome-shell" executable="gnome-shell"> + <option name="glx_disable_ext_buffer_age" value="true" /> + <option name="glx_disable_oml_sync_control" value="true" /> + <option name="glx_disable_sgi_video_sync" value="true" /> + </application> + <application name="Compiz" executable="Compiz"> + <option name="glx_disable_ext_buffer_age" value="true" /> + <option name="glx_disable_oml_sync_control" value="true" /> + </application> + </device> + <device driver="radeonsi"> + <application name="ARK: Survival Evolved (and unintentionally the UE4 demo template)" executable="ShooterGame"> + <option name="radeonsi_clear_db_cache_before_clear" value="true" /> + </application> + <application name="No Mans Sky" executable="NMS.exe"> + <option name="radeonsi_zerovram" value="true" /> + </application> + </device> +</driconf> diff --git a/lib/mesa/src/util/bigmath.h b/lib/mesa/src/util/bigmath.h new file mode 100644 index 000000000..6339bb6f6 --- /dev/null +++ b/lib/mesa/src/util/bigmath.h @@ -0,0 +1,112 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UTIL_BIGMATH_H +#define UTIL_BIGMATH_H + +#include "macros.h" + +#include <assert.h> +#include <stdint.h> +#include <string.h> + +static inline bool +_ubm_add_u32arr(uint32_t *dst, unsigned dst_len, + uint32_t *a, unsigned a_len, + uint32_t *b, unsigned b_len) +{ + uint32_t carry = 0; + for (unsigned i = 0; i < dst_len; i++) { + uint64_t sum = carry; + if (i < a_len) + sum += a[i]; + if (i < b_len) + sum += b[i]; + dst[i] = sum; + carry = sum >> 32; + } + + /* Now compute overflow */ + + for (unsigned i = dst_len; i < a_len; i++) { + if (a[i]) + return true; + } + + for (unsigned i = dst_len; i < b_len; i++) { + if (b[i]) + return true; + } + + return carry; +} +#define ubm_add_u32arr(dst, a, b) \ + _ubm_add_u32arr(dst, ARRAY_SIZE(dst), a, ARRAY_SIZE(a), b, ARRAY_SIZE(b)) + +static inline bool +_ubm_mul_u32arr(uint32_t *dst, unsigned dst_len, + uint32_t *a, unsigned a_len, + uint32_t *b, unsigned b_len) +{ + memset(dst, 0, dst_len * sizeof(*dst)); + + bool overflow = false; + + for (unsigned i = 0; i < a_len; i++) { + uint32_t carry = 0; + for (unsigned j = 0; j < b_len; j++) { + /* The maximum values of a[i] and b[i] are UINT32_MAX so the maximum + * value of tmp is UINT32_MAX * UINT32_MAX. The maximum value that + * will fit in tmp is + * + * UINT64_MAX = UINT32_MAX << 32 + UINT32_MAX + * = UINT32_MAX * (UINT32_MAX + 1) + UINT32_MAX + * = UINT32_MAX * UINT32_MAX + 2 * UINT32_MAX + * + * so we're guaranteed that we can add in two more 32-bit values + * without overflowing tmp. + */ + uint64_t tmp = (uint64_t)a[i] * (uint64_t)b[j]; + tmp += carry; + if (i + j < dst_len) { + tmp += dst[i + j]; + dst[i + j] = tmp; + carry = tmp >> 32; + } else { + /* We're trying to write a value that doesn't fit */ + overflow = overflow || tmp > 0; + break; + } + } + if (i + b_len < dst_len) + dst[i + b_len] = carry; + else + overflow = overflow || carry > 0; + } + + return overflow; +} +#define ubm_mul_u32arr(dst, a, b) \ + _ubm_mul_u32arr(dst, ARRAY_SIZE(dst), a, ARRAY_SIZE(a), b, ARRAY_SIZE(b)) + +#endif /* UTIL_BIGMATH_H */ diff --git a/lib/mesa/src/util/bitset.h b/lib/mesa/src/util/bitset.h index 2404ce7f6..3b18abac7 100644 --- a/lib/mesa/src/util/bitset.h +++ b/lib/mesa/src/util/bitset.h @@ -31,7 +31,8 @@ #ifndef BITSET_H #define BITSET_H -#include "util/u_math.h" +#include "util/bitscan.h" +#include "util/macros.h" /**************************************************************************** * generic bitset implementation @@ -53,7 +54,7 @@ #define BITSET_ONES(x) memset( (x), 0xff, sizeof (x) ) #define BITSET_BITWORD(b) ((b) / BITSET_WORDBITS) -#define BITSET_BIT(b) (1 << ((b) % BITSET_WORDBITS)) +#define BITSET_BIT(b) (1u << ((b) % BITSET_WORDBITS)) /* single bit operations */ @@ -132,4 +133,121 @@ __bitset_next_set(unsigned i, BITSET_WORD *tmp, for (__tmp = *(__set), __i = 0; \ (__i = __bitset_next_set(__i, &__tmp, __set, __size)) < __size;) +#ifdef __cplusplus + +/** + * Simple C++ wrapper of a bitset type of static size, with value semantics + * and basic bitwise arithmetic operators. The operators defined below are + * expected to have the same semantics as the same operator applied to other + * fundamental integer types. T is the name of the struct to instantiate + * it as, and N is the number of bits in the bitset. + */ +#define DECLARE_BITSET_T(T, N) struct T { \ + EXPLICIT_CONVERSION \ + operator bool() const \ + { \ + for (unsigned i = 0; i < BITSET_WORDS(N); i++) \ + if (words[i]) \ + return true; \ + return false; \ + } \ + \ + T & \ + operator=(int x) \ + { \ + const T c = {{ (BITSET_WORD)x }}; \ + return *this = c; \ + } \ + \ + friend bool \ + operator==(const T &b, const T &c) \ + { \ + return BITSET_EQUAL(b.words, c.words); \ + } \ + \ + friend bool \ + operator!=(const T &b, const T &c) \ + { \ + return !(b == c); \ + } \ + \ + friend bool \ + operator==(const T &b, int x) \ + { \ + const T c = {{ (BITSET_WORD)x }}; \ + return b == c; \ + } \ + \ + friend bool \ + operator!=(const T &b, int x) \ + { \ + return !(b == x); \ + } \ + \ + friend T \ + operator~(const T &b) \ + { \ + T c; \ + for (unsigned i = 0; i < BITSET_WORDS(N); i++) \ + c.words[i] = ~b.words[i]; \ + return c; \ + } \ + \ + T & \ + operator|=(const T &b) \ + { \ + for (unsigned i = 0; i < BITSET_WORDS(N); i++) \ + words[i] |= b.words[i]; \ + return *this; \ + } \ + \ + friend T \ + operator|(const T &b, const T &c) \ + { \ + T d = b; \ + d |= c; \ + return d; \ + } \ + \ + T & \ + operator&=(const T &b) \ + { \ + for (unsigned i = 0; i < BITSET_WORDS(N); i++) \ + words[i] &= b.words[i]; \ + return *this; \ + } \ + \ + friend T \ + operator&(const T &b, const T &c) \ + { \ + T d = b; \ + d &= c; \ + return d; \ + } \ + \ + bool \ + test(unsigned i) const \ + { \ + return BITSET_TEST(words, i); \ + } \ + \ + T & \ + set(unsigned i) \ + { \ + BITSET_SET(words, i); \ + return *this; \ + } \ + \ + T & \ + clear(unsigned i) \ + { \ + BITSET_CLEAR(words, i); \ + return *this; \ + } \ + \ + BITSET_WORD words[BITSET_WORDS(N)]; \ + } + +#endif + #endif diff --git a/lib/mesa/src/util/fast_idiv_by_const.c b/lib/mesa/src/util/fast_idiv_by_const.c new file mode 100644 index 000000000..7b9331626 --- /dev/null +++ b/lib/mesa/src/util/fast_idiv_by_const.c @@ -0,0 +1,243 @@ +/* + * Copyright © 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* Imported from: + * https://raw.githubusercontent.com/ridiculousfish/libdivide/master/divide_by_constants_codegen_reference.c + * Paper: + * http://ridiculousfish.com/files/faster_unsigned_division_by_constants.pdf + * + * The author, ridiculous_fish, wrote: + * + * ''Reference implementations of computing and using the "magic number" + * approach to dividing by constants, including codegen instructions. + * The unsigned division incorporates the "round down" optimization per + * ridiculous_fish. + * + * This is free and unencumbered software. Any copyright is dedicated + * to the Public Domain.'' + */ + +#include "fast_idiv_by_const.h" +#include "u_math.h" +#include <limits.h> +#include <assert.h> + +struct util_fast_udiv_info +util_compute_fast_udiv_info(uint64_t D, unsigned num_bits, unsigned UINT_BITS) +{ + /* The numerator must fit in a uint64_t */ + assert(num_bits > 0 && num_bits <= UINT_BITS); + assert(D != 0); + + /* The eventual result */ + struct util_fast_udiv_info result; + + if (util_is_power_of_two_or_zero64(D)) { + unsigned div_shift = util_logbase2_64(D); + + if (div_shift) { + /* Dividing by a power of two. */ + result.multiplier = 1ull << (UINT_BITS - div_shift); + result.pre_shift = 0; + result.post_shift = 0; + result.increment = 0; + return result; + } else { + /* Dividing by 1. */ + /* Assuming: floor((num + 1) * (2^32 - 1) / 2^32) = num */ + result.multiplier = UINT_BITS == 64 ? UINT64_MAX : + (1ull << UINT_BITS) - 1; + result.pre_shift = 0; + result.post_shift = 0; + result.increment = 1; + return result; + } + } + + /* The extra shift implicit in the difference between UINT_BITS and num_bits + */ + const unsigned extra_shift = UINT_BITS - num_bits; + + /* The initial power of 2 is one less than the first one that can possibly + * work. + */ + const uint64_t initial_power_of_2 = (uint64_t)1 << (UINT_BITS-1); + + /* The remainder and quotient of our power of 2 divided by d */ + uint64_t quotient = initial_power_of_2 / D; + uint64_t remainder = initial_power_of_2 % D; + + /* ceil(log_2 D) */ + unsigned ceil_log_2_D; + + /* The magic info for the variant "round down" algorithm */ + uint64_t down_multiplier = 0; + unsigned down_exponent = 0; + int has_magic_down = 0; + + /* Compute ceil(log_2 D) */ + ceil_log_2_D = 0; + uint64_t tmp; + for (tmp = D; tmp > 0; tmp >>= 1) + ceil_log_2_D += 1; + + + /* Begin a loop that increments the exponent, until we find a power of 2 + * that works. + */ + unsigned exponent; + for (exponent = 0; ; exponent++) { + /* Quotient and remainder is from previous exponent; compute it for this + * exponent. + */ + if (remainder >= D - remainder) { + /* Doubling remainder will wrap around D */ + quotient = quotient * 2 + 1; + remainder = remainder * 2 - D; + } else { + /* Remainder will not wrap */ + quotient = quotient * 2; + remainder = remainder * 2; + } + + /* We're done if this exponent works for the round_up algorithm. + * Note that exponent may be larger than the maximum shift supported, + * so the check for >= ceil_log_2_D is critical. + */ + if ((exponent + extra_shift >= ceil_log_2_D) || + (D - remainder) <= ((uint64_t)1 << (exponent + extra_shift))) + break; + + /* Set magic_down if we have not set it yet and this exponent works for + * the round_down algorithm + */ + if (!has_magic_down && + remainder <= ((uint64_t)1 << (exponent + extra_shift))) { + has_magic_down = 1; + down_multiplier = quotient; + down_exponent = exponent; + } + } + + if (exponent < ceil_log_2_D) { + /* magic_up is efficient */ + result.multiplier = quotient + 1; + result.pre_shift = 0; + result.post_shift = exponent; + result.increment = 0; + } else if (D & 1) { + /* Odd divisor, so use magic_down, which must have been set */ + assert(has_magic_down); + result.multiplier = down_multiplier; + result.pre_shift = 0; + result.post_shift = down_exponent; + result.increment = 1; + } else { + /* Even divisor, so use a prefix-shifted dividend */ + unsigned pre_shift = 0; + uint64_t shifted_D = D; + while ((shifted_D & 1) == 0) { + shifted_D >>= 1; + pre_shift += 1; + } + result = util_compute_fast_udiv_info(shifted_D, num_bits - pre_shift, + UINT_BITS); + /* expect no increment or pre_shift in this path */ + assert(result.increment == 0 && result.pre_shift == 0); + result.pre_shift = pre_shift; + } + return result; +} + +static inline int64_t +sign_extend(int64_t x, unsigned SINT_BITS) +{ + return (x << (64 - SINT_BITS)) >> (64 - SINT_BITS); +} + +struct util_fast_sdiv_info +util_compute_fast_sdiv_info(int64_t D, unsigned SINT_BITS) +{ + /* D must not be zero. */ + assert(D != 0); + /* The result is not correct for these divisors. */ + assert(D != 1 && D != -1); + + /* Our result */ + struct util_fast_sdiv_info result; + + /* Absolute value of D (we know D is not the most negative value since + * that's a power of 2) + */ + const uint64_t abs_d = (D < 0 ? -D : D); + + /* The initial power of 2 is one less than the first one that can possibly + * work */ + /* "two31" in Warren */ + unsigned exponent = SINT_BITS - 1; + const uint64_t initial_power_of_2 = (uint64_t)1 << exponent; + + /* Compute the absolute value of our "test numerator," + * which is the largest dividend whose remainder with d is d-1. + * This is called anc in Warren. + */ + const uint64_t tmp = initial_power_of_2 + (D < 0); + const uint64_t abs_test_numer = tmp - 1 - tmp % abs_d; + + /* Initialize our quotients and remainders (q1, r1, q2, r2 in Warren) */ + uint64_t quotient1 = initial_power_of_2 / abs_test_numer; + uint64_t remainder1 = initial_power_of_2 % abs_test_numer; + uint64_t quotient2 = initial_power_of_2 / abs_d; + uint64_t remainder2 = initial_power_of_2 % abs_d; + uint64_t delta; + + /* Begin our loop */ + do { + /* Update the exponent */ + exponent++; + + /* Update quotient1 and remainder1 */ + quotient1 *= 2; + remainder1 *= 2; + if (remainder1 >= abs_test_numer) { + quotient1 += 1; + remainder1 -= abs_test_numer; + } + + /* Update quotient2 and remainder2 */ + quotient2 *= 2; + remainder2 *= 2; + if (remainder2 >= abs_d) { + quotient2 += 1; + remainder2 -= abs_d; + } + + /* Keep going as long as (2**exponent) / abs_d <= delta */ + delta = abs_d - remainder2; + } while (quotient1 < delta || (quotient1 == delta && remainder1 == 0)); + + result.multiplier = sign_extend(quotient2 + 1, SINT_BITS); + if (D < 0) result.multiplier = -result.multiplier; + result.shift = exponent - SINT_BITS; + return result; +} diff --git a/lib/mesa/src/util/fast_idiv_by_const.h b/lib/mesa/src/util/fast_idiv_by_const.h new file mode 100644 index 000000000..638b52a3f --- /dev/null +++ b/lib/mesa/src/util/fast_idiv_by_const.h @@ -0,0 +1,183 @@ +/* + * Copyright © 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef FAST_IDIV_BY_CONST_H +#define FAST_IDIV_BY_CONST_H + +/* Imported from: + * https://raw.githubusercontent.com/ridiculousfish/libdivide/master/divide_by_constants_codegen_reference.c + */ + +#include <inttypes.h> +#include <limits.h> +#include <assert.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Computes "magic info" for performing signed division by a fixed integer D. + * The type 'sint_t' is assumed to be defined as a signed integer type large + * enough to hold both the dividend and the divisor. + * Here >> is arithmetic (signed) shift, and >>> is logical shift. + * + * To emit code for n/d, rounding towards zero, use the following sequence: + * + * m = compute_signed_magic_info(D) + * emit("result = (m.multiplier * n) >> SINT_BITS"); + * if d > 0 and m.multiplier < 0: emit("result += n") + * if d < 0 and m.multiplier > 0: emit("result -= n") + * if m.post_shift > 0: emit("result >>= m.shift") + * emit("result += (result < 0)") + * + * The shifts by SINT_BITS may be "free" if the high half of the full multiply + * is put in a separate register. + * + * The final add can of course be implemented via the sign bit, e.g. + * result += (result >>> (SINT_BITS - 1)) + * or + * result -= (result >> (SINT_BITS - 1)) + * + * This code is heavily indebted to Hacker's Delight by Henry Warren. + * See http://www.hackersdelight.org/HDcode/magic.c.txt + * Used with permission from http://www.hackersdelight.org/permissions.htm + */ + +struct util_fast_sdiv_info { + int64_t multiplier; /* the "magic number" multiplier */ + unsigned shift; /* shift for the dividend after multiplying */ +}; + +struct util_fast_sdiv_info +util_compute_fast_sdiv_info(int64_t D, unsigned SINT_BITS); + +/* Computes "magic info" for performing unsigned division by a fixed positive + * integer D. UINT_BITS is the bit size at which the final "magic" + * calculation will be performed; it is assumed to be large enough to hold + * both the dividand and the divisor. num_bits can be set appropriately if n + * is known to be smaller than calc_bits; if this is not known then UINT_BITS + * for num_bits. + * + * Assume we have a hardware register of width UINT_BITS, a known constant D + * which is not zero and not a power of 2, and a variable n of width num_bits + * (which may be up to UINT_BITS). To emit code for n/d, use one of the two + * following sequences (here >>> refers to a logical bitshift): + * + * m = compute_unsigned_magic_info(D, num_bits) + * if m.pre_shift > 0: emit("n >>>= m.pre_shift") + * if m.increment: emit("n = saturated_increment(n)") + * emit("result = (m.multiplier * n) >>> UINT_BITS") + * if m.post_shift > 0: emit("result >>>= m.post_shift") + * + * or + * + * m = compute_unsigned_magic_info(D, num_bits) + * if m.pre_shift > 0: emit("n >>>= m.pre_shift") + * emit("result = m.multiplier * n") + * if m.increment: emit("result = result + m.multiplier") + * emit("result >>>= UINT_BITS") + * if m.post_shift > 0: emit("result >>>= m.post_shift") + * + * This second version works even if D is 1. The shifts by UINT_BITS may be + * "free" if the high half of the full multiply is put in a separate register. + * + * saturated_increment(n) means "increment n unless it would wrap to 0," i.e. + * if n == (1 << UINT_BITS)-1: result = n + * else: result = n+1 + * A common way to implement this is with the carry bit. For example, on x86: + * add 1 + * sbb 0 + * + * Some invariants: + * 1: At least one of pre_shift and increment is zero + * 2: multiplier is never zero + * + * This code incorporates the "round down" optimization per ridiculous_fish. + */ + +struct util_fast_udiv_info { + uint64_t multiplier; /* the "magic number" multiplier */ + unsigned pre_shift; /* shift for the dividend before multiplying */ + unsigned post_shift; /* shift for the dividend after multiplying */ + int increment; /* 0 or 1; if set then increment the numerator, using one of + the two strategies */ +}; + +struct util_fast_udiv_info +util_compute_fast_udiv_info(uint64_t D, unsigned num_bits, unsigned UINT_BITS); + +/* Below are possible options for dividing by a uniform in a shader where + * the divisor is constant but not known at compile time. + */ + +/* Full version. */ +static inline uint32_t +util_fast_udiv32(uint32_t n, struct util_fast_udiv_info info) +{ + n = n >> info.pre_shift; + /* If the divisor is not 1, you can instead use a 32-bit ADD that clamps + * to UINT_MAX. Dividing by 1 needs the full 64-bit ADD. + * + * If you have unsigned 64-bit MAD with 32-bit inputs, you can do: + * increment = increment ? multiplier : 0; // on the CPU + * (n * multiplier + increment) // on the GPU using unsigned 64-bit MAD + */ + n = (((uint64_t)n + info.increment) * info.multiplier) >> 32; + n = n >> info.post_shift; + return n; +} + +/* A little more efficient version if n != UINT_MAX, i.e. no unsigned + * wraparound in the computation. + */ +static inline uint32_t +util_fast_udiv32_nuw(uint32_t n, struct util_fast_udiv_info info) +{ + assert(n != UINT32_MAX); + n = n >> info.pre_shift; + n = n + info.increment; + n = ((uint64_t)n * info.multiplier) >> 32; + n = n >> info.post_shift; + return n; +} + +/* Even faster version but both operands must be 31-bit unsigned integers + * and the divisor must be greater than 1. + * + * info must be computed with num_bits == 31. + */ +static inline uint32_t +util_fast_udiv32_u31_d_not_one(uint32_t n, struct util_fast_udiv_info info) +{ + assert(info.pre_shift == 0); + assert(info.increment == 0); + n = ((uint64_t)n * info.multiplier) >> 32; + n = n >> info.post_shift; + return n; +} + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif /* FAST_IDIV_BY_CONST_H */ diff --git a/lib/mesa/src/util/format_srgb.h b/lib/mesa/src/util/format_srgb.h index 34b50afe3..596af56f4 100644 --- a/lib/mesa/src/util/format_srgb.h +++ b/lib/mesa/src/util/format_srgb.h @@ -55,6 +55,20 @@ util_format_linear_to_srgb_helper_table[104]; static inline float +util_format_srgb_to_linear_float(float cs) +{ + if (cs <= 0.0f) + return 0.0f; + else if (cs <= 0.04045f) + return cs / 12.92f; + else if (cs < 1.0f) + return powf((cs + 0.055) / 1.055f, 2.4f); + else + return 1.0f; +} + + +static inline float util_format_linear_to_srgb_float(float cl) { if (cl <= 0.0f) diff --git a/lib/mesa/src/util/futex.h b/lib/mesa/src/util/futex.h new file mode 100644 index 000000000..440289306 --- /dev/null +++ b/lib/mesa/src/util/futex.h @@ -0,0 +1,56 @@ +/* + * Copyright © 2015 Intel + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UTIL_FUTEX_H +#define UTIL_FUTEX_H + +#if defined(HAVE_LINUX_FUTEX_H) + +#include <limits.h> +#include <stdint.h> +#include <unistd.h> +#include <linux/futex.h> +#include <sys/syscall.h> +#include <sys/time.h> + +static inline long sys_futex(void *addr1, int op, int val1, const struct timespec *timeout, void *addr2, int val3) +{ + return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3); +} + +static inline int futex_wake(uint32_t *addr, int count) +{ + return sys_futex(addr, FUTEX_WAKE, count, NULL, NULL, 0); +} + +static inline int futex_wait(uint32_t *addr, int32_t value, const struct timespec *timeout) +{ + /* FUTEX_WAIT_BITSET with FUTEX_BITSET_MATCH_ANY is equivalent to + * FUTEX_WAIT, except that it treats the timeout as absolute. */ + return sys_futex(addr, FUTEX_WAIT_BITSET, value, timeout, NULL, + FUTEX_BITSET_MATCH_ANY); +} + +#endif + +#endif /* UTIL_FUTEX_H */ diff --git a/lib/mesa/src/util/half_float.c b/lib/mesa/src/util/half_float.c index 4df64c2cc..63aec5c5c 100644 --- a/lib/mesa/src/util/half_float.c +++ b/lib/mesa/src/util/half_float.c @@ -2,6 +2,8 @@ * Mesa 3-D graphics library * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright 2015 Philip Taylor <philip@zaynar.co.uk> + * Copyright 2018 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,6 +28,7 @@ #include <assert.h> #include "half_float.h" #include "rounding.h" +#include "macros.h" typedef union { float f; int32_t i; uint32_t u; } fi_type; @@ -175,3 +178,70 @@ _mesa_half_to_float(uint16_t val) result = fi.f; return result; } + +/** + * Convert 0.0 to 0x00, 1.0 to 0xff. + * Values outside the range [0.0, 1.0] will give undefined results. + */ +uint8_t _mesa_half_to_unorm8(uint16_t val) +{ + const int m = val & 0x3ff; + const int e = (val >> 10) & 0x1f; + MAYBE_UNUSED const int s = (val >> 15) & 0x1; + + /* v = round_to_nearest(1.mmmmmmmmmm * 2^(e-15) * 255) + * = round_to_nearest((1.mmmmmmmmmm * 255) * 2^(e-15)) + * = round_to_nearest((1mmmmmmmmmm * 255) * 2^(e-25)) + * = round_to_zero((1mmmmmmmmmm * 255) * 2^(e-25) + 0.5) + * = round_to_zero(((1mmmmmmmmmm * 255) * 2^(e-24) + 1) / 2) + * + * This happens to give the correct answer for zero/subnormals too + */ + assert(s == 0 && val <= FP16_ONE); /* check 0 <= this <= 1 */ + /* (implies e <= 15, which means the bit-shifts below are safe) */ + + uint32_t v = ((1 << 10) | m) * 255; + v = ((v >> (24 - e)) + 1) >> 1; + return v; +} + +/** + * Takes a uint16_t, divides by 65536, converts the infinite-precision + * result to fp16 with round-to-zero. Used by the ASTC decoder. + */ +uint16_t _mesa_uint16_div_64k_to_half(uint16_t v) +{ + /* Zero or subnormal. Set the mantissa to (v << 8) and return. */ + if (v < 4) + return v << 8; + + /* Count the leading 0s in the uint16_t */ +#ifdef HAVE___BUILTIN_CLZ + int n = __builtin_clz(v) - 16; +#else + int n = 16; + for (int i = 15; i >= 0; i--) { + if (v & (1 << i)) { + n = 15 - i; + break; + } + } +#endif + + /* Shift the mantissa up so bit 16 is the hidden 1 bit, + * mask it off, then shift back down to 10 bits + */ + int m = ( ((uint32_t)v << (n + 1)) & 0xffff ) >> 6; + + /* (0{n} 1 X{15-n}) * 2^-16 + * = 1.X * 2^(15-n-16) + * = 1.X * 2^(14-n - 15) + * which is the FP16 form with e = 14 - n + */ + int e = 14 - n; + + assert(e >= 1 && e <= 30); + assert(m >= 0 && m < 0x400); + + return (e << 10) | m; +} diff --git a/lib/mesa/src/util/half_float.h b/lib/mesa/src/util/half_float.h index b3bc3f687..015574247 100644 --- a/lib/mesa/src/util/half_float.h +++ b/lib/mesa/src/util/half_float.h @@ -32,8 +32,13 @@ extern "C" { #endif +#define FP16_ONE 0x3C00 +#define FP16_ZERO 0 + uint16_t _mesa_float_to_half(float val); float _mesa_half_to_float(uint16_t val); +uint8_t _mesa_half_to_unorm8(uint16_t v); +uint16_t _mesa_uint16_div_64k_to_half(uint16_t v); static inline bool _mesa_half_is_negative(uint16_t h) diff --git a/lib/mesa/src/util/meson.build b/lib/mesa/src/util/meson.build new file mode 100644 index 000000000..156621aff --- /dev/null +++ b/lib/mesa/src/util/meson.build @@ -0,0 +1,184 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +inc_util = include_directories('.') + +subdir('xmlpool') + +files_mesa_util = files( + 'bigmath.h', + 'bitscan.c', + 'bitscan.h', + 'bitset.h', + 'build_id.c', + 'build_id.h', + 'crc32.c', + 'crc32.h', + 'debug.c', + 'debug.h', + 'disk_cache.c', + 'disk_cache.h', + 'fast_idiv_by_const.c', + 'fast_idiv_by_const.h', + 'format_r11g11b10f.h', + 'format_rgb9e5.h', + 'format_srgb.h', + 'futex.h', + 'half_float.c', + 'half_float.h', + 'hash_table.c', + 'hash_table.h', + 'list.h', + 'macros.h', + 'mesa-sha1.c', + 'mesa-sha1.h', + 'os_time.c', + 'os_time.h', + 'os_misc.c', + 'os_misc.h', + 'u_process.c', + 'u_process.h', + 'sha1/sha1.c', + 'sha1/sha1.h', + 'ralloc.c', + 'ralloc.h', + 'rand_xor.c', + 'rand_xor.h', + 'rb_tree.c', + 'rb_tree.h', + 'register_allocate.c', + 'register_allocate.h', + 'rgtc.c', + 'rgtc.h', + 'rounding.h', + 'set.c', + 'set.h', + 'simple_list.h', + 'simple_mtx.h', + 'slab.c', + 'slab.h', + 'string_buffer.c', + 'string_buffer.h', + 'strndup.h', + 'strtod.c', + 'strtod.h', + 'texcompress_rgtc_tmp.h', + 'u_atomic.c', + 'u_atomic.h', + 'u_dynarray.h', + 'u_endian.h', + 'u_queue.c', + 'u_queue.h', + 'u_string.h', + 'u_thread.h', + 'u_vector.c', + 'u_vector.h', + 'u_math.c', + 'u_math.h', + 'u_debug.c', + 'u_debug.h', + 'u_cpu_detect.c', + 'u_cpu_detect.h', + 'vma.c', + 'vma.h', +) + +install_data('00-mesa-defaults.conf', install_dir : join_paths(get_option('datadir'), 'drirc.d')) + +files_xmlconfig = files( + 'xmlconfig.c', + 'xmlconfig.h', +) + +format_srgb = custom_target( + 'format_srgb', + input : ['format_srgb.py'], + output : 'format_srgb.c', + command : [prog_python, '@INPUT0@'], + capture : true, +) + +libmesa_util = static_library( + 'mesa_util', + [files_mesa_util, format_srgb], + include_directories : inc_common, + dependencies : [dep_zlib, dep_clock, dep_thread, dep_atomic, dep_m], + c_args : [c_msvc_compat_args, c_vis_args], + build_by_default : false +) + +libxmlconfig = static_library( + 'xmlconfig', + files_xmlconfig, + include_directories : inc_common, + link_with : libmesa_util, + dependencies : [dep_expat, dep_m], + c_args : [ + c_msvc_compat_args, c_vis_args, + '-DSYSCONFDIR="@0@"'.format( + join_paths(get_option('prefix'), get_option('sysconfdir')) + ), + '-DDATADIR="@0@"'.format( + join_paths(get_option('prefix'), get_option('datadir')) + ), + ], + build_by_default : false, +) + +if with_tests + test( + 'u_atomic', + executable( + 'u_atomic_test', + files('u_atomic_test.c'), + include_directories : inc_common, + link_with : libmesa_util, + c_args : [c_msvc_compat_args], + ) + ) + + test( + 'roundeven', + executable( + 'roundeven_test', + files('roundeven_test.c'), + include_directories : inc_common, + c_args : [c_msvc_compat_args], + dependencies : [dep_m], + ) + ) + + test( + 'mesa-sha1', + executable( + 'mesa-sha1_test', + files('mesa-sha1_test.c'), + include_directories : inc_common, + link_with : libmesa_util, + c_args : [c_msvc_compat_args], + ) + ) + + subdir('tests/fast_idiv_by_const') + subdir('tests/hash_table') + subdir('tests/string_buffer') + subdir('tests/vma') + subdir('tests/set') +endif diff --git a/lib/mesa/src/util/os_misc.c b/lib/mesa/src/util/os_misc.c new file mode 100644 index 000000000..09d4400e0 --- /dev/null +++ b/lib/mesa/src/util/os_misc.c @@ -0,0 +1,176 @@ +/************************************************************************** + * + * Copyright 2008-2010 Vmware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "os_misc.h" + +#include <stdarg.h> + + +#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#endif +#include <windows.h> +#include <stdio.h> + +#else + +#include <stdio.h> +#include <stdlib.h> + +#endif + + +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS) +# include <unistd.h> +#elif defined(PIPE_OS_APPLE) || defined(PIPE_OS_BSD) +# include <sys/sysctl.h> +#elif defined(PIPE_OS_HAIKU) +# include <kernel/OS.h> +#elif defined(PIPE_OS_WINDOWS) +# include <windows.h> +#else +#error unexpected platform in os_sysinfo.c +#endif + + +void +os_log_message(const char *message) +{ + /* If the GALLIUM_LOG_FILE environment variable is set to a valid filename, + * write all messages to that file. + */ + static FILE *fout = NULL; + + if (!fout) { +#ifdef DEBUG + /* one-time init */ + const char *filename = os_get_option("GALLIUM_LOG_FILE"); + if (filename) { + const char *mode = "w"; + if (filename[0] == '+') { + /* If the filename is prefixed with '+' then open the file for + * appending instead of normal writing. + */ + mode = "a"; + filename++; /* skip the '+' */ + } + fout = fopen(filename, mode); + } +#endif + if (!fout) + fout = stderr; + } + +#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) + OutputDebugStringA(message); + if(GetConsoleWindow() && !IsDebuggerPresent()) { + fflush(stdout); + fputs(message, fout); + fflush(fout); + } + else if (fout != stderr) { + fputs(message, fout); + fflush(fout); + } +#else /* !PIPE_SUBSYSTEM_WINDOWS */ + fflush(stdout); + fputs(message, fout); + fflush(fout); +#endif +} + + +#if !defined(PIPE_SUBSYSTEM_EMBEDDED) +const char * +os_get_option(const char *name) +{ + return getenv(name); +} +#endif /* !PIPE_SUBSYSTEM_EMBEDDED */ + + +/** + * Return the size of the total physical memory. + * \param size returns the size of the total physical memory + * \return true for success, or false on failure + */ +bool +os_get_total_physical_memory(uint64_t *size) +{ +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS) + const long phys_pages = sysconf(_SC_PHYS_PAGES); + const long page_size = sysconf(_SC_PAGE_SIZE); + + if (phys_pages <= 0 || page_size <= 0) + return false; + + *size = (uint64_t)phys_pages * (uint64_t)page_size; + return true; +#elif defined(PIPE_OS_APPLE) || defined(PIPE_OS_BSD) + size_t len = sizeof(*size); + int mib[2]; + + mib[0] = CTL_HW; +#if defined(PIPE_OS_APPLE) + mib[1] = HW_MEMSIZE; +#elif defined(PIPE_OS_NETBSD) || defined(PIPE_OS_OPENBSD) + mib[1] = HW_PHYSMEM64; +#elif defined(PIPE_OS_FREEBSD) + mib[1] = HW_REALMEM; +#elif defined(PIPE_OS_DRAGONFLY) + mib[1] = HW_PHYSMEM; +#else +#error Unsupported *BSD +#endif + + return (sysctl(mib, 2, size, &len, NULL, 0) == 0); +#elif defined(PIPE_OS_HAIKU) + system_info info; + status_t ret; + + ret = get_system_info(&info); + if (ret != B_OK || info.max_pages <= 0) + return false; + + *size = (uint64_t)info.max_pages * (uint64_t)B_PAGE_SIZE; + return true; +#elif defined(PIPE_OS_WINDOWS) + MEMORYSTATUSEX status; + BOOL ret; + + status.dwLength = sizeof(status); + ret = GlobalMemoryStatusEx(&status); + *size = status.ullTotalPhys; + return (ret == TRUE); +#else +#error unexpected platform in os_sysinfo.c + return false; +#endif +} diff --git a/lib/mesa/src/util/os_misc.h b/lib/mesa/src/util/os_misc.h new file mode 100644 index 000000000..403c8ee6e --- /dev/null +++ b/lib/mesa/src/util/os_misc.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2010 Vmware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/* + * Miscellaneous OS services. + */ + + +#ifndef _OS_MISC_H_ +#define _OS_MISC_H_ + + +#include "pipe/p_compiler.h" + + +#if defined(PIPE_OS_UNIX) +# include <signal.h> /* for kill() */ +# include <unistd.h> /* getpid() */ +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Trap into the debugger. + */ +#if (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)) && defined(PIPE_CC_GCC) +# define os_break() __asm("int3") +#elif defined(PIPE_CC_MSVC) +# define os_break() __debugbreak() +#elif defined(PIPE_OS_UNIX) +# define os_break() kill(getpid(), SIGTRAP) +#else +# define os_break() abort() +#endif + + +/* + * Abort the program. + */ +#if defined(DEBUG) +# define os_abort() do { os_break(); abort(); } while(0) +#else +# define os_abort() abort() +#endif + + +/* + * Output a message. Message should preferably end in a newline. + */ +void +os_log_message(const char *message); + + +/* + * Get an option. Should return NULL if specified option is not set. + */ +const char * +os_get_option(const char *name); + + +/* + * Get the total amount of physical memory available on the system. + */ +bool +os_get_total_physical_memory(uint64_t *size); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _OS_MISC_H_ */ diff --git a/lib/mesa/src/util/os_time.c b/lib/mesa/src/util/os_time.c new file mode 100644 index 000000000..ac488b228 --- /dev/null +++ b/lib/mesa/src/util/os_time.c @@ -0,0 +1,192 @@ +/************************************************************************** + * + * Copyright 2008-2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * OS independent time-manipulation functions. + * + * @author Jose Fonseca <jfonseca@vmware.com> + */ + +#include "os_time.h" + +/* TODO: fix this dependency */ +#include "gallium/include/pipe/p_config.h" + +#include "util/u_atomic.h" + +#if defined(PIPE_OS_UNIX) +# include <unistd.h> /* usleep */ +# include <time.h> /* timeval */ +# include <sys/time.h> /* timeval */ +# include <sched.h> /* sched_yield */ +# include <errno.h> +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) +# include <windows.h> +#else +# error Unsupported OS +#endif + + +int64_t +os_time_get_nano(void) +{ +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) + + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); + return tv.tv_nsec + tv.tv_sec*INT64_C(1000000000); + +#elif defined(PIPE_OS_UNIX) + + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_usec*INT64_C(1000) + tv.tv_sec*INT64_C(1000000000); + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + + static LARGE_INTEGER frequency; + LARGE_INTEGER counter; + int64_t secs, nanosecs; + if(!frequency.QuadPart) + QueryPerformanceFrequency(&frequency); + QueryPerformanceCounter(&counter); + /* Compute seconds and nanoseconds parts separately to + * reduce severity of precision loss. + */ + secs = counter.QuadPart / frequency.QuadPart; + nanosecs = (counter.QuadPart % frequency.QuadPart) * INT64_C(1000000000) + / frequency.QuadPart; + return secs*INT64_C(1000000000) + nanosecs; + +#else + +#error Unsupported OS + +#endif +} + + + +void +os_time_sleep(int64_t usecs) +{ +#if defined(PIPE_OS_LINUX) + struct timespec time; + time.tv_sec = usecs / 1000000; + time.tv_nsec = (usecs % 1000000) * 1000; + while (clock_nanosleep(CLOCK_MONOTONIC, 0, &time, &time) == EINTR); + +#elif defined(PIPE_OS_UNIX) + usleep(usecs); + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + DWORD dwMilliseconds = (DWORD) ((usecs + 999) / 1000); + /* Avoid Sleep(O) as that would cause to sleep for an undetermined duration */ + if (dwMilliseconds) { + Sleep(dwMilliseconds); + } +#else +# error Unsupported OS +#endif +} + + + +int64_t +os_time_get_absolute_timeout(uint64_t timeout) +{ + int64_t time, abs_timeout; + + /* Also check for the type upper bound. */ + if (timeout == OS_TIMEOUT_INFINITE || timeout > INT64_MAX) + return OS_TIMEOUT_INFINITE; + + time = os_time_get_nano(); + abs_timeout = time + (int64_t)timeout; + + /* Check for overflow. */ + if (abs_timeout < time) + return OS_TIMEOUT_INFINITE; + + return abs_timeout; +} + + +bool +os_wait_until_zero(volatile int *var, uint64_t timeout) +{ + if (!p_atomic_read(var)) + return true; + + if (!timeout) + return false; + + if (timeout == OS_TIMEOUT_INFINITE) { + while (p_atomic_read(var)) { +#if defined(PIPE_OS_UNIX) + sched_yield(); +#endif + } + return true; + } + else { + int64_t start_time = os_time_get_nano(); + int64_t end_time = start_time + timeout; + + while (p_atomic_read(var)) { + if (os_time_timeout(start_time, end_time, os_time_get_nano())) + return false; + +#if defined(PIPE_OS_UNIX) + sched_yield(); +#endif + } + return true; + } +} + + +bool +os_wait_until_zero_abs_timeout(volatile int *var, int64_t timeout) +{ + if (!p_atomic_read(var)) + return true; + + if (timeout == OS_TIMEOUT_INFINITE) + return os_wait_until_zero(var, OS_TIMEOUT_INFINITE); + + while (p_atomic_read(var)) { + if (os_time_get_nano() >= timeout) + return false; + +#if defined(PIPE_OS_UNIX) + sched_yield(); +#endif + } + return true; +} diff --git a/lib/mesa/src/util/os_time.h b/lib/mesa/src/util/os_time.h new file mode 100644 index 000000000..049ab118d --- /dev/null +++ b/lib/mesa/src/util/os_time.h @@ -0,0 +1,130 @@ +/************************************************************************** + * + * Copyright 2008-2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * OS independent time-manipulation functions. + * + * @author Jose Fonseca <jfonseca@vmware.com> + */ + +#ifndef _OS_TIME_H_ +#define _OS_TIME_H_ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* must be equal to PIPE_TIMEOUT_INFINITE */ +#define OS_TIMEOUT_INFINITE 0xffffffffffffffffull + +/* + * Get the current time in nanoseconds from an unknown base. + */ +int64_t +os_time_get_nano(void); + + +/* + * Get the current time in microseconds from an unknown base. + */ +static inline int64_t +os_time_get(void) +{ + return os_time_get_nano() / 1000; +} + + +/* + * Sleep. + */ +void +os_time_sleep(int64_t usecs); + + +/* + * Helper function for detecting time outs, taking in account overflow. + * + * Returns true if the current time has elapsed beyond the specified interval. + */ +static inline bool +os_time_timeout(int64_t start, + int64_t end, + int64_t curr) +{ + if (start <= end) + return !(start <= curr && curr < end); + else + return !((start <= curr) || (curr < end)); +} + + +/** + * Convert a relative timeout in nanoseconds into an absolute timeout, + * in other words, it returns current time + timeout. + * os_time_get_nano() must be monotonic. + * OS_TIMEOUT_INFINITE is passed through unchanged. If the calculation + * overflows, OS_TIMEOUT_INFINITE is returned. + */ +int64_t +os_time_get_absolute_timeout(uint64_t timeout); + + +/** + * Wait until the variable at the given memory location is zero. + * + * \param var variable + * \param timeout timeout in ns, can be anything from 0 (no wait) to + * OS_TIMEOUT_INFINITE (wait forever) + * \return true if the variable is zero + */ +bool +os_wait_until_zero(volatile int *var, uint64_t timeout); + + +/** + * Wait until the variable at the given memory location is zero. + * The timeout is the absolute time when the waiting should stop. If it is + * less than or equal to the current time, it only returns the status and + * doesn't wait. OS_TIMEOUT_INFINITE waits forever. This requires that + * os_time_get_nano is monotonic. + * + * \param var variable + * \param timeout the time in ns when the waiting should stop + * \return true if the variable is zero + */ +bool +os_wait_until_zero_abs_timeout(volatile int *var, int64_t timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_TIME_H_ */ diff --git a/lib/mesa/src/util/rb_tree.c b/lib/mesa/src/util/rb_tree.c new file mode 100644 index 000000000..a86fa31a8 --- /dev/null +++ b/lib/mesa/src/util/rb_tree.c @@ -0,0 +1,421 @@ +/* + * Copyright © 2017 Jason Ekstrand + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "rb_tree.h" + +/** \file rb_tree.c + * + * An implementation of a red-black tree + * + * This file implements the guts of a red-black tree. The implementation + * is mostly based on the one in "Introduction to Algorithms", third + * edition, by Cormen, Leiserson, Rivest, and Stein. The primary + * divergence in our algorithms from those presented in CLRS is that we use + * NULL for the leaves instead of a sentinel. This means we have to do a + * tiny bit more tracking in our implementation of delete but it makes the + * algorithms far more explicit than stashing stuff in the sentinel. + */ + +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +static bool +rb_node_is_black(struct rb_node *n) +{ + /* NULL nodes are leaves and therefore black */ + return (n == NULL) || (n->parent & 1); +} + +static bool +rb_node_is_red(struct rb_node *n) +{ + return !rb_node_is_black(n); +} + +static void +rb_node_set_black(struct rb_node *n) +{ + n->parent |= 1; +} + +static void +rb_node_set_red(struct rb_node *n) +{ + n->parent &= ~1ull; +} + +static void +rb_node_copy_color(struct rb_node *dst, struct rb_node *src) +{ + dst->parent = (dst->parent & ~1ull) | (src->parent & 1); +} + +static void +rb_node_set_parent(struct rb_node *n, struct rb_node *p) +{ + n->parent = (n->parent & 1) | (uintptr_t)p; +} + +static struct rb_node * +rb_node_minimum(struct rb_node *node) +{ + while (node->left) + node = node->left; + return node; +} + +static struct rb_node * +rb_node_maximum(struct rb_node *node) +{ + while (node->right) + node = node->right; + return node; +} + +void +rb_tree_init(struct rb_tree *T) +{ + T->root = NULL; +} + +/** + * Replace the subtree of T rooted at u with the subtree rooted at v + * + * This is called RB-transplant in CLRS. + * + * The node to be replaced is assumed to be a non-leaf. + */ +static void +rb_tree_splice(struct rb_tree *T, struct rb_node *u, struct rb_node *v) +{ + assert(u); + struct rb_node *p = rb_node_parent(u); + if (p == NULL) { + assert(T->root == u); + T->root = v; + } else if (u == p->left) { + p->left = v; + } else { + assert(u == p->right); + p->right = v; + } + if (v) + rb_node_set_parent(v, p); +} + +static void +rb_tree_rotate_left(struct rb_tree *T, struct rb_node *x) +{ + assert(x && x->right); + + struct rb_node *y = x->right; + x->right = y->left; + if (y->left) + rb_node_set_parent(y->left, x); + rb_tree_splice(T, x, y); + y->left = x; + rb_node_set_parent(x, y); +} + +static void +rb_tree_rotate_right(struct rb_tree *T, struct rb_node *y) +{ + assert(y && y->left); + + struct rb_node *x = y->left; + y->left = x->right; + if (x->right) + rb_node_set_parent(x->right, y); + rb_tree_splice(T, y, x); + x->right = y; + rb_node_set_parent(y, x); +} + +void +rb_tree_insert_at(struct rb_tree *T, struct rb_node *parent, + struct rb_node *node, bool insert_left) +{ + /* This sets null children, parent, and a color of red */ + memset(node, 0, sizeof(*node)); + + if (parent == NULL) { + assert(T->root == NULL); + T->root = node; + rb_node_set_black(node); + return; + } + + if (insert_left) { + assert(parent->left == NULL); + parent->left = node; + } else { + assert(parent->right == NULL); + parent->right = node; + } + rb_node_set_parent(node, parent); + + /* Now we do the insertion fixup */ + struct rb_node *z = node; + while (rb_node_is_red(rb_node_parent(z))) { + struct rb_node *z_p = rb_node_parent(z); + assert(z == z_p->left || z == z_p->right); + struct rb_node *z_p_p = rb_node_parent(z_p); + assert(z_p_p != NULL); + if (z_p == z_p_p->left) { + struct rb_node *y = z_p_p->right; + if (rb_node_is_red(y)) { + rb_node_set_black(z_p); + rb_node_set_black(y); + rb_node_set_red(z_p_p); + z = z_p_p; + } else { + if (z == z_p->right) { + z = z_p; + rb_tree_rotate_left(T, z); + /* We changed z */ + z_p = rb_node_parent(z); + assert(z == z_p->left || z == z_p->right); + z_p_p = rb_node_parent(z_p); + } + rb_node_set_black(z_p); + rb_node_set_red(z_p_p); + rb_tree_rotate_right(T, z_p_p); + } + } else { + struct rb_node *y = z_p_p->left; + if (rb_node_is_red(y)) { + rb_node_set_black(z_p); + rb_node_set_black(y); + rb_node_set_red(z_p_p); + z = z_p_p; + } else { + if (z == z_p->left) { + z = z_p; + rb_tree_rotate_right(T, z); + /* We changed z */ + z_p = rb_node_parent(z); + assert(z == z_p->left || z == z_p->right); + z_p_p = rb_node_parent(z_p); + } + rb_node_set_black(z_p); + rb_node_set_red(z_p_p); + rb_tree_rotate_left(T, z_p_p); + } + } + } + rb_node_set_black(T->root); +} + +void +rb_tree_remove(struct rb_tree *T, struct rb_node *z) +{ + /* x_p is always the parent node of X. We have to track this + * separately because x may be NULL. + */ + struct rb_node *x, *x_p; + struct rb_node *y = z; + bool y_was_black = rb_node_is_black(y); + if (z->left == NULL) { + x = z->right; + x_p = rb_node_parent(z); + rb_tree_splice(T, z, x); + } else if (z->right == NULL) { + x = z->left; + x_p = rb_node_parent(z); + rb_tree_splice(T, z, x); + } else { + /* Find the minimum sub-node of z->right */ + y = rb_node_minimum(z->right); + y_was_black = rb_node_is_black(y); + + x = y->right; + if (rb_node_parent(y) == z) { + x_p = y; + } else { + x_p = rb_node_parent(y); + rb_tree_splice(T, y, x); + y->right = z->right; + rb_node_set_parent(y->right, y); + } + assert(y->left == NULL); + rb_tree_splice(T, z, y); + y->left = z->left; + rb_node_set_parent(y->left, y); + rb_node_copy_color(y, z); + } + + assert(x_p == NULL || x == x_p->left || x == x_p->right); + + if (!y_was_black) + return; + + /* Fixup RB tree after the delete */ + while (x != T->root && rb_node_is_black(x)) { + if (x == x_p->left) { + struct rb_node *w = x_p->right; + if (rb_node_is_red(w)) { + rb_node_set_black(w); + rb_node_set_red(x_p); + rb_tree_rotate_left(T, x_p); + assert(x == x_p->left); + w = x_p->right; + } + if (rb_node_is_black(w->left) && rb_node_is_black(w->right)) { + rb_node_set_red(w); + x = x_p; + } else { + if (rb_node_is_black(w->right)) { + rb_node_set_black(w->left); + rb_node_set_red(w); + rb_tree_rotate_right(T, w); + w = x_p->right; + } + rb_node_copy_color(w, x_p); + rb_node_set_black(x_p); + rb_node_set_black(w->right); + rb_tree_rotate_left(T, x_p); + x = T->root; + } + } else { + struct rb_node *w = x_p->left; + if (rb_node_is_red(w)) { + rb_node_set_black(w); + rb_node_set_red(x_p); + rb_tree_rotate_right(T, x_p); + assert(x == x_p->right); + w = x_p->left; + } + if (rb_node_is_black(w->right) && rb_node_is_black(w->left)) { + rb_node_set_red(w); + x = x_p; + } else { + if (rb_node_is_black(w->left)) { + rb_node_set_black(w->right); + rb_node_set_red(w); + rb_tree_rotate_left(T, w); + w = x_p->left; + } + rb_node_copy_color(w, x_p); + rb_node_set_black(x_p); + rb_node_set_black(w->left); + rb_tree_rotate_right(T, x_p); + x = T->root; + } + } + x_p = rb_node_parent(x); + } + if (x) + rb_node_set_black(x); +} + +struct rb_node * +rb_tree_first(struct rb_tree *T) +{ + return T->root ? rb_node_minimum(T->root) : NULL; +} + +struct rb_node * +rb_tree_last(struct rb_tree *T) +{ + return T->root ? rb_node_maximum(T->root) : NULL; +} + +struct rb_node * +rb_node_next(struct rb_node *node) +{ + if (node->right) { + /* If we have a right child, then the next thing (compared to this + * node) is the left-most child of our right child. + */ + return rb_node_minimum(node->right); + } else { + /* If node doesn't have a right child, crawl back up the to the + * left until we hit a parent to the right. + */ + struct rb_node *p = rb_node_parent(node); + while (p && node == p->right) { + node = p; + p = rb_node_parent(node); + } + assert(p == NULL || node == p->left); + return p; + } +} + +struct rb_node * +rb_node_prev(struct rb_node *node) +{ + if (node->left) { + /* If we have a left child, then the previous thing (compared to + * this node) is the right-most child of our left child. + */ + return rb_node_maximum(node->left); + } else { + /* If node doesn't have a left child, crawl back up the to the + * right until we hit a parent to the left. + */ + struct rb_node *p = rb_node_parent(node); + while (p && node == p->left) { + node = p; + p = rb_node_parent(node); + } + assert(p == NULL || node == p->right); + return p; + } +} + +static void +validate_rb_node(struct rb_node *n, int black_depth) +{ + if (n == NULL) { + assert(black_depth == 0); + return; + } + + if (rb_node_is_black(n)) { + black_depth--; + } else { + assert(rb_node_is_black(n->left)); + assert(rb_node_is_black(n->right)); + } + + validate_rb_node(n->left, black_depth); + validate_rb_node(n->right, black_depth); +} + +void +rb_tree_validate(struct rb_tree *T) +{ + if (T->root == NULL) + return; + + assert(rb_node_is_black(T->root)); + + unsigned black_depth = 0; + for (struct rb_node *n = T->root; n; n = n->left) { + if (rb_node_is_black(n)) + black_depth++; + } + + validate_rb_node(T->root, black_depth); +} diff --git a/lib/mesa/src/util/rb_tree.h b/lib/mesa/src/util/rb_tree.h new file mode 100644 index 000000000..1e8aeb4a7 --- /dev/null +++ b/lib/mesa/src/util/rb_tree.h @@ -0,0 +1,327 @@ +/* + * Copyright © 2017 Jason Ekstrand + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef RB_TREE_H +#define RB_TREE_H + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +/** A red-black tree node + * + * This struct represents a node in the red-black tree. This struct should + * be embedded as a member in whatever structure you wish to put in the + * tree. + */ +struct rb_node { + /** Parent and color of this node + * + * The least significant bit represents the color and is est to 1 for + * black and 0 for red. The other bits are the pointer to the parent + * and that pointer can be retrieved by masking off the bottom bit and + * casting to a pointer. + */ + uintptr_t parent; + + /** Left child of this node, null for a leaf */ + struct rb_node *left; + + /** Right child of this node, null for a leaf */ + struct rb_node *right; +}; + +/** Return the parent node of the given node or NULL if it is the root */ +static inline struct rb_node * +rb_node_parent(struct rb_node *n) +{ + return (struct rb_node *)(n->parent & ~(uintptr_t)1); +} + +/** A red-black tree + * + * This struct represents the red-black tree itself. It is just a pointer + * to the root node with no other metadata. + */ +struct rb_tree { + struct rb_node *root; +}; + +/** Initialize a red-black tree */ +void rb_tree_init(struct rb_tree *T); + +/** Returns true if the red-black tree is empty */ +static inline bool +rb_tree_is_empty(const struct rb_tree *T) +{ + return T->root == NULL; +} + +/** Retrieve the data structure containing a node + * + * \param type The type of the containing data structure + * + * \param node A pointer to a rb_node + * + * \param field The rb_node field in the containing data structure + */ +#define rb_node_data(type, node, field) \ + ((type *)(((char *)(node)) - offsetof(type, field))) + +/** Insert a node into a tree at a particular location + * + * This function should probably not be used directly as it relies on the + * caller to ensure that the parent node is correct. Use rb_tree_insert + * instead. + * + * \param T The red-black tree into which to insert the new node + * + * \param parent The node in the tree that will be the parent of the + * newly inserted node + * + * \param node The node to insert + * + * \param insert_left If true, the new node will be the left child of + * \p parent, otherwise it will be the right child + */ +void rb_tree_insert_at(struct rb_tree *T, struct rb_node *parent, + struct rb_node *node, bool insert_left); + +/** Insert a node into a tree + * + * \param T The red-black tree into which to insert the new node + * + * \param node The node to insert + * + * \param cmp A comparison function to use to order the nodes. + */ +static inline void +rb_tree_insert(struct rb_tree *T, struct rb_node *node, + int (*cmp)(const struct rb_node *, const struct rb_node *)) +{ + /* This function is declared inline in the hopes that the compiler can + * optimize away the comparison function pointer call. + */ + struct rb_node *y = NULL; + struct rb_node *x = T->root; + bool left = false; + while (x != NULL) { + y = x; + left = cmp(node, x) < 0; + if (left) + x = x->left; + else + x = x->right; + } + + rb_tree_insert_at(T, y, node, left); +} + +/** Remove a node from a tree + * + * \param T The red-black tree from which to remove the node + * + * \param node The node to remove + */ +void rb_tree_remove(struct rb_tree *T, struct rb_node *z); + +/** Search the tree for a node + * + * If a node with a matching key exists, the first matching node found will + * be returned. If no matching node exists, NULL is returned. + * + * \param T The red-black tree to search + * + * \param key The key to search for + * + * \param cmp A comparison function to use to order the nodes + */ +static inline struct rb_node * +rb_tree_search(struct rb_tree *T, const void *key, + int (*cmp)(const struct rb_node *, const void *)) +{ + /* This function is declared inline in the hopes that the compiler can + * optimize away the comparison function pointer call. + */ + struct rb_node *x = T->root; + while (x != NULL) { + int c = cmp(x, key); + if (c < 0) + x = x->right; + else if (c > 0) + x = x->left; + else + return x; + } + + return x; +} + +/** Sloppily search the tree for a node + * + * This function searches the tree for a given node. If a node with a + * matching key exists, that first matching node found will be returned. + * If no node with an exactly matching key exists, the node returned will + * be either the right-most node comparing less than \p key or the + * right-most node comparing greater than \p key. If the tree is empty, + * NULL is returned. + * + * \param T The red-black tree to search + * + * \param key The key to search for + * + * \param cmp A comparison function to use to order the nodes + */ +static inline struct rb_node * +rb_tree_search_sloppy(struct rb_tree *T, const void *key, + int (*cmp)(const struct rb_node *, const void *)) +{ + /* This function is declared inline in the hopes that the compiler can + * optimize away the comparison function pointer call. + */ + struct rb_node *y = NULL; + struct rb_node *x = T->root; + while (x != NULL) { + y = x; + int c = cmp(x, key); + if (c < 0) + x = x->right; + else if (c > 0) + x = x->left; + else + return x; + } + + return y; +} + +/** Get the first (left-most) node in the tree or NULL */ +struct rb_node *rb_tree_first(struct rb_tree *T); + +/** Get the last (right-most) node in the tree or NULL */ +struct rb_node *rb_tree_last(struct rb_tree *T); + +/** Get the next node (to the right) in the tree or NULL */ +struct rb_node *rb_node_next(struct rb_node *node); + +/** Get the next previous (to the left) in the tree or NULL */ +struct rb_node *rb_node_prev(struct rb_node *node); + +/** Get the next node if available or the same node again. + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_node_next_if_available(type, node, field) \ + (&node->field != NULL) ? rb_node_data(type, rb_node_next(&node->field), field) : node + +/** Get the previous node if available or the same node again. + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_node_prev_if_available(type, node, field) \ + (&node->field != NULL) ? rb_node_data(type, rb_node_prev(&node->field), field) : node + +/** Iterate over the nodes in the tree + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param T The red-black tree + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_foreach(type, node, T, field) \ + for (type *node = rb_node_data(type, rb_tree_first(T), field); \ + &node->field != NULL; \ + node = rb_node_data(type, rb_node_next(&node->field), field)) + +/** Iterate over the nodes in the tree, allowing the current node to be freed + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param T The red-black tree + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_foreach_safe(type, node, T, field) \ + for (type *node = rb_node_data(type, rb_tree_first(T), field), \ + *__next = rb_tree_node_next_if_available(type, node, field); \ + &node->field != NULL; \ + node = __next, __next = rb_tree_node_next_if_available(type, node, field)) + +/** Iterate over the nodes in the tree in reverse + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param T The red-black tree + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_foreach_rev(type, node, T, field) \ + for (type *node = rb_node_data(type, rb_tree_last(T), field); \ + &node->field != NULL; \ + node = rb_node_data(type, rb_node_prev(&node->field), field)) + +/** Iterate over the nodes in the tree in reverse, allowing the current node to be freed + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param T The red-black tree + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_foreach_rev_safe(type, node, T, field) \ + for (type *node = rb_node_data(type, rb_tree_last(T), field), \ + *__prev = rb_tree_node_prev_if_available(type, node, field); \ + &node->field != NULL; \ + node = __prev, __prev = rb_tree_node_prev_if_available(type, node, field)) + +/** Validate a red-black tree + * + * This function walks the tree and validates that this is a valid red- + * black tree. If anything is wrong, it will assert-fail. + */ +void rb_tree_validate(struct rb_tree *T); + +#endif /* RB_TREE_H */ diff --git a/lib/mesa/src/util/register_allocate.c b/lib/mesa/src/util/register_allocate.c index de8978bb9..500540bfd 100644 --- a/lib/mesa/src/util/register_allocate.c +++ b/lib/mesa/src/util/register_allocate.c @@ -75,7 +75,6 @@ #include "ralloc.h" #include "main/imports.h" #include "main/macros.h" -#include "main/mtypes.h" #include "util/bitset.h" #include "register_allocate.h" diff --git a/lib/mesa/src/util/set.h b/lib/mesa/src/util/set.h index 9acd2c28c..54719e4c8 100644 --- a/lib/mesa/src/util/set.h +++ b/lib/mesa/src/util/set.h @@ -58,9 +58,15 @@ _mesa_set_create(void *mem_ctx, uint32_t (*key_hash_function)(const void *key), bool (*key_equals_function)(const void *a, const void *b)); +struct set * +_mesa_set_clone(struct set *set, void *dst_mem_ctx); + void _mesa_set_destroy(struct set *set, void (*delete_function)(struct set_entry *entry)); +void +_mesa_set_clear(struct set *set, + void (*delete_function)(struct set_entry *entry)); struct set_entry * _mesa_set_add(struct set *set, const void *key); @@ -75,6 +81,8 @@ _mesa_set_search_pre_hashed(const struct set *set, uint32_t hash, void _mesa_set_remove(struct set *set, struct set_entry *entry); +void +_mesa_set_remove_key(struct set *set, const void *key); struct set_entry * _mesa_set_next_entry(const struct set *set, struct set_entry *entry); @@ -88,9 +96,9 @@ _mesa_set_random_entry(struct set *set, * insertion (which may rehash the set, making entry a dangling * pointer). */ -#define set_foreach(set, entry) \ - for (entry = _mesa_set_next_entry(set, NULL); \ - entry != NULL; \ +#define set_foreach(set, entry) \ + for (struct set_entry *entry = _mesa_set_next_entry(set, NULL); \ + entry != NULL; \ entry = _mesa_set_next_entry(set, entry)) #ifdef __cplusplus diff --git a/lib/mesa/src/util/simple_mtx.h b/lib/mesa/src/util/simple_mtx.h new file mode 100644 index 000000000..cfb82ba56 --- /dev/null +++ b/lib/mesa/src/util/simple_mtx.h @@ -0,0 +1,136 @@ +/* + * Copyright © 2015 Intel + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _SIMPLE_MTX_H +#define _SIMPLE_MTX_H + +#include "util/futex.h" + +#include "c11/threads.h" + +#if defined(__GNUC__) && defined(HAVE_LINUX_FUTEX_H) + +/* mtx_t - Fast, simple mutex + * + * While modern pthread mutexes are very fast (implemented using futex), they + * still incur a call to an external DSO and overhead of the generality and + * features of pthread mutexes. Most mutexes in mesa only needs lock/unlock, + * and the idea here is that we can inline the atomic operation and make the + * fast case just two intructions. Mutexes are subtle and finicky to + * implement, so we carefully copy the implementation from Ulrich Dreppers + * well-written and well-reviewed paper: + * + * "Futexes Are Tricky" + * http://www.akkadia.org/drepper/futex.pdf + * + * We implement "mutex3", which gives us a mutex that has no syscalls on + * uncontended lock or unlock. Further, the uncontended case boils down to a + * locked cmpxchg and an untaken branch, the uncontended unlock is just a + * locked decr and an untaken branch. We use __builtin_expect() to indicate + * that contention is unlikely so that gcc will put the contention code out of + * the main code flow. + * + * A fast mutex only supports lock/unlock, can't be recursive or used with + * condition variables. + */ + +typedef struct { + uint32_t val; +} simple_mtx_t; + +#define _SIMPLE_MTX_INITIALIZER_NP { 0 } + +static inline void +simple_mtx_init(simple_mtx_t *mtx, MAYBE_UNUSED int type) +{ + assert(type == mtx_plain); + + mtx->val = 0; +} + +static inline void +simple_mtx_destroy(UNUSED simple_mtx_t *mtx) +{ +} + +static inline void +simple_mtx_lock(simple_mtx_t *mtx) +{ + uint32_t c; + + c = __sync_val_compare_and_swap(&mtx->val, 0, 1); + if (__builtin_expect(c != 0, 0)) { + if (c != 2) + c = __sync_lock_test_and_set(&mtx->val, 2); + while (c != 0) { + futex_wait(&mtx->val, 2, NULL); + c = __sync_lock_test_and_set(&mtx->val, 2); + } + } +} + +static inline void +simple_mtx_unlock(simple_mtx_t *mtx) +{ + uint32_t c; + + c = __sync_fetch_and_sub(&mtx->val, 1); + if (__builtin_expect(c != 1, 0)) { + mtx->val = 0; + futex_wake(&mtx->val, 1); + } +} + +#else + +typedef mtx_t simple_mtx_t; + +#define _SIMPLE_MTX_INITIALIZER_NP _MTX_INITIALIZER_NP + +static inline void +simple_mtx_init(simple_mtx_t *mtx, int type) +{ + mtx_init(mtx, type); +} + +static inline void +simple_mtx_destroy(simple_mtx_t *mtx) +{ + mtx_destroy(mtx); +} + +static inline void +simple_mtx_lock(simple_mtx_t *mtx) +{ + mtx_lock(mtx); +} + +static inline void +simple_mtx_unlock(simple_mtx_t *mtx) +{ + mtx_unlock(mtx); +} + +#endif + +#endif diff --git a/lib/mesa/src/util/tests/fast_idiv_by_const/Makefile.am b/lib/mesa/src/util/tests/fast_idiv_by_const/Makefile.am new file mode 100644 index 000000000..1ebee09f5 --- /dev/null +++ b/lib/mesa/src/util/tests/fast_idiv_by_const/Makefile.am @@ -0,0 +1,43 @@ +# Copyright © 2018 Intel +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gtest/include \ + $(PTHREAD_CFLAGS) \ + $(DEFINES) + +TESTS = fast_idiv_by_const_test + +check_PROGRAMS = $(TESTS) + +fast_idiv_by_const_test_SOURCES = \ + fast_idiv_by_const_test.cpp + +fast_idiv_by_const_test_LDADD = \ + $(top_builddir)/src/gtest/libgtest.la \ + $(top_builddir)/src/util/libmesautil.la \ + $(PTHREAD_LIBS) \ + $(DLOPEN_LIBS) + +EXTRA_DIST = meson.build diff --git a/lib/mesa/src/util/tests/fast_idiv_by_const/Makefile.in b/lib/mesa/src/util/tests/fast_idiv_by_const/Makefile.in new file mode 100644 index 000000000..0242034e8 --- /dev/null +++ b/lib/mesa/src/util/tests/fast_idiv_by_const/Makefile.in @@ -0,0 +1,1224 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright © 2018 Intel +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +TESTS = fast_idiv_by_const_test$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) +subdir = src/util/tests/fast_idiv_by_const +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_gnu_make.m4 \ + $(top_srcdir)/m4/ax_check_python_mako_module.m4 \ + $(top_srcdir)/m4/ax_gcc_builtin.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_prog_bison.m4 \ + $(top_srcdir)/m4/ax_prog_flex.m4 \ + $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/VERSION $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = fast_idiv_by_const_test$(EXEEXT) +am_fast_idiv_by_const_test_OBJECTS = \ + fast_idiv_by_const_test.$(OBJEXT) +fast_idiv_by_const_test_OBJECTS = \ + $(am_fast_idiv_by_const_test_OBJECTS) +am__DEPENDENCIES_1 = +fast_idiv_by_const_test_DEPENDENCIES = \ + $(top_builddir)/src/gtest/libgtest.la \ + $(top_builddir)/src/util/libmesautil.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/fast_idiv_by_const_test.Po +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(fast_idiv_by_const_test_SOURCES) +DIST_SOURCES = $(fast_idiv_by_const_test_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/bin/depcomp \ + $(top_srcdir)/bin/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDGPU_CFLAGS = @AMDGPU_CFLAGS@ +AMDGPU_LIBS = @AMDGPU_LIBS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +ANDROID_CFLAGS = @ANDROID_CFLAGS@ +ANDROID_LIBS = @ANDROID_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BACKTRACE_CFLAGS = @BACKTRACE_CFLAGS@ +BACKTRACE_LIBS = @BACKTRACE_LIBS@ +BSYMBOLIC = @BSYMBOLIC@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@ +CLOCK_LIB = @CLOCK_LIB@ +CLOVER_STD_OVERRIDE = @CLOVER_STD_OVERRIDE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXX11_CXXFLAGS = @CXX11_CXXFLAGS@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +D3D_DRIVER_INSTALL_DIR = @D3D_DRIVER_INSTALL_DIR@ +DEFINES = @DEFINES@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DLOPEN_LIBS = @DLOPEN_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRIGL_CFLAGS = @DRIGL_CFLAGS@ +DRIGL_LIBS = @DRIGL_LIBS@ +DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@ +DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@ +DRI_LIB_DEPS = @DRI_LIB_DEPS@ +DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGL_CFLAGS = @EGL_CFLAGS@ +EGL_LIB_DEPS = @EGL_LIB_DEPS@ +EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@ +EGREP = @EGREP@ +ETNAVIV_CFLAGS = @ETNAVIV_CFLAGS@ +ETNAVIV_LIBS = @ETNAVIV_LIBS@ +EXEEXT = @EXEEXT@ +EXPAT_CFLAGS = @EXPAT_CFLAGS@ +EXPAT_LIBS = @EXPAT_LIBS@ +FGREP = @FGREP@ +GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@ +GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@ +GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@ +GC_SECTIONS = @GC_SECTIONS@ +GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@ +GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@ +GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@ +GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@ +GLPROTO_CFLAGS = @GLPROTO_CFLAGS@ +GLPROTO_LIBS = @GLPROTO_LIBS@ +GLVND_CFLAGS = @GLVND_CFLAGS@ +GLVND_LIBS = @GLVND_LIBS@ +GLX_TLS = @GLX_TLS@ +GL_LIB = @GL_LIB@ +GL_LIB_DEPS = @GL_LIB_DEPS@ +GL_PC_CFLAGS = @GL_PC_CFLAGS@ +GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@ +GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@ +GL_PKGCONF_LIB = @GL_PKGCONF_LIB@ +GREP = @GREP@ +I915_CFLAGS = @I915_CFLAGS@ +I915_LIBS = @I915_LIBS@ +INDENT = @INDENT@ +INDENT_FLAGS = @INDENT_FLAGS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LD_BUILD_ID = @LD_BUILD_ID@ +LD_NO_UNDEFINED = @LD_NO_UNDEFINED@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBATOMIC_LIBS = @LIBATOMIC_LIBS@ +LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@ +LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBELF_CFLAGS = @LIBELF_CFLAGS@ +LIBELF_LIBS = @LIBELF_LIBS@ +LIBGLVND_DATADIR = @LIBGLVND_DATADIR@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSENSORS_LIBS = @LIBSENSORS_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ +LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ +LIB_DIR = @LIB_DIR@ +LIB_EXT = @LIB_EXT@ +LIPO = @LIPO@ +LLVM_CFLAGS = @LLVM_CFLAGS@ +LLVM_CONFIG = @LLVM_CONFIG@ +LLVM_CXXFLAGS = @LLVM_CXXFLAGS@ +LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@ +LLVM_LDFLAGS = @LLVM_LDFLAGS@ +LLVM_LIBS = @LLVM_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@ +MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@ +NINE_MAJOR = @NINE_MAJOR@ +NINE_MINOR = @NINE_MINOR@ +NINE_PATCH = @NINE_PATCH@ +NINE_VERSION = @NINE_VERSION@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@ +NOUVEAU_LIBS = @NOUVEAU_LIBS@ +NVVIEUX_CFLAGS = @NVVIEUX_CFLAGS@ +NVVIEUX_LIBS = @NVVIEUX_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OMX_BELLAGIO_CFLAGS = @OMX_BELLAGIO_CFLAGS@ +OMX_BELLAGIO_LIBS = @OMX_BELLAGIO_LIBS@ +OMX_BELLAGIO_LIB_INSTALL_DIR = @OMX_BELLAGIO_LIB_INSTALL_DIR@ +OMX_TIZONIA_CFLAGS = @OMX_TIZONIA_CFLAGS@ +OMX_TIZONIA_LIBS = @OMX_TIZONIA_LIBS@ +OMX_TIZONIA_LIB_INSTALL_DIR = @OMX_TIZONIA_LIB_INSTALL_DIR@ +OPENCL_LIBNAME = @OPENCL_LIBNAME@ +OPENCL_VERSION = @OPENCL_VERSION@ +OSMESA_LIB = @OSMESA_LIB@ +OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@ +OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@ +OSMESA_PC_REQ = @OSMESA_PC_REQ@ +OSMESA_VERSION = @OSMESA_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +PTHREADSTUBS_CFLAGS = @PTHREADSTUBS_CFLAGS@ +PTHREADSTUBS_LIBS = @PTHREADSTUBS_LIBS@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PWR8_CFLAGS = @PWR8_CFLAGS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RADEON_CFLAGS = @RADEON_CFLAGS@ +RADEON_LIBS = @RADEON_LIBS@ +RANLIB = @RANLIB@ +RM = @RM@ +SCANNER_ARG = @SCANNER_ARG@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIMPENROSE_CFLAGS = @SIMPENROSE_CFLAGS@ +SIMPENROSE_LIBS = @SIMPENROSE_LIBS@ +SSE41_CFLAGS = @SSE41_CFLAGS@ +STRIP = @STRIP@ +SWR_AVX2_CXXFLAGS = @SWR_AVX2_CXXFLAGS@ +SWR_AVX_CXXFLAGS = @SWR_AVX_CXXFLAGS@ +SWR_KNL_CXXFLAGS = @SWR_KNL_CXXFLAGS@ +SWR_SKX_CXXFLAGS = @SWR_SKX_CXXFLAGS@ +V3D_SIMULATOR_CFLAGS = @V3D_SIMULATOR_CFLAGS@ +V3D_SIMULATOR_LIBS = @V3D_SIMULATOR_LIBS@ +VALGRIND_CFLAGS = @VALGRIND_CFLAGS@ +VALGRIND_LIBS = @VALGRIND_LIBS@ +VA_CFLAGS = @VA_CFLAGS@ +VA_LIBS = @VA_LIBS@ +VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@ +VA_MAJOR = @VA_MAJOR@ +VA_MINOR = @VA_MINOR@ +VC4_CFLAGS = @VC4_CFLAGS@ +VC4_LIBS = @VC4_LIBS@ +VDPAU_CFLAGS = @VDPAU_CFLAGS@ +VDPAU_LIBS = @VDPAU_LIBS@ +VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@ +VDPAU_MAJOR = @VDPAU_MAJOR@ +VDPAU_MINOR = @VDPAU_MINOR@ +VERSION = @VERSION@ +VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ +VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@ +VL_CFLAGS = @VL_CFLAGS@ +VL_LIBS = @VL_LIBS@ +VULKAN_ICD_INSTALL_DIR = @VULKAN_ICD_INSTALL_DIR@ +WAYLAND_CLIENT_CFLAGS = @WAYLAND_CLIENT_CFLAGS@ +WAYLAND_CLIENT_LIBS = @WAYLAND_CLIENT_LIBS@ +WAYLAND_EGL_CFLAGS = @WAYLAND_EGL_CFLAGS@ +WAYLAND_EGL_LIBS = @WAYLAND_EGL_LIBS@ +WAYLAND_PROTOCOLS_CFLAGS = @WAYLAND_PROTOCOLS_CFLAGS@ +WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ +WAYLAND_PROTOCOLS_LIBS = @WAYLAND_PROTOCOLS_LIBS@ +WAYLAND_SCANNER = @WAYLAND_SCANNER@ +WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ +WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ +WAYLAND_SERVER_CFLAGS = @WAYLAND_SERVER_CFLAGS@ +WAYLAND_SERVER_LIBS = @WAYLAND_SERVER_LIBS@ +WNO_OVERRIDE_INIT = @WNO_OVERRIDE_INIT@ +X11_INCLUDES = @X11_INCLUDES@ +XA_MAJOR = @XA_MAJOR@ +XA_MINOR = @XA_MINOR@ +XA_PATCH = @XA_PATCH@ +XA_VERSION = @XA_VERSION@ +XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@ +XCB_DRI2_LIBS = @XCB_DRI2_LIBS@ +XCB_DRI3_CFLAGS = @XCB_DRI3_CFLAGS@ +XCB_DRI3_LIBS = @XCB_DRI3_LIBS@ +XCB_DRI3_MODIFIERS_CFLAGS = @XCB_DRI3_MODIFIERS_CFLAGS@ +XCB_DRI3_MODIFIERS_LIBS = @XCB_DRI3_MODIFIERS_LIBS@ +XCB_RANDR_CFLAGS = @XCB_RANDR_CFLAGS@ +XCB_RANDR_LIBS = @XCB_RANDR_LIBS@ +XLIBGL_CFLAGS = @XLIBGL_CFLAGS@ +XLIBGL_LIBS = @XLIBGL_LIBS@ +XLIB_RANDR_CFLAGS = @XLIB_RANDR_CFLAGS@ +XLIB_RANDR_LIBS = @XLIB_RANDR_LIBS@ +XVMC_CFLAGS = @XVMC_CFLAGS@ +XVMC_LIBS = @XVMC_LIBS@ +XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@ +XVMC_MAJOR = @XVMC_MAJOR@ +XVMC_MINOR = @XVMC_MINOR@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acv_mako_found = @acv_mako_found@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +ifGNUmake = @ifGNUmake@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gtest/include \ + $(PTHREAD_CFLAGS) \ + $(DEFINES) + +fast_idiv_by_const_test_SOURCES = \ + fast_idiv_by_const_test.cpp + +fast_idiv_by_const_test_LDADD = \ + $(top_builddir)/src/gtest/libgtest.la \ + $(top_builddir)/src/util/libmesautil.la \ + $(PTHREAD_LIBS) \ + $(DLOPEN_LIBS) + +EXTRA_DIST = meson.build +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/util/tests/fast_idiv_by_const/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/util/tests/fast_idiv_by_const/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +fast_idiv_by_const_test$(EXEEXT): $(fast_idiv_by_const_test_OBJECTS) $(fast_idiv_by_const_test_DEPENDENCIES) $(EXTRA_fast_idiv_by_const_test_DEPENDENCIES) + @rm -f fast_idiv_by_const_test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(fast_idiv_by_const_test_OBJECTS) $(fast_idiv_by_const_test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_idiv_by_const_test.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: $(check_PROGRAMS) + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +fast_idiv_by_const_test.log: fast_idiv_by_const_test$(EXEEXT) + @p='fast_idiv_by_const_test$(EXEEXT)'; \ + b='fast_idiv_by_const_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/fast_idiv_by_const_test.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/fast_idiv_by_const_test.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/mesa/src/util/tests/fast_idiv_by_const/fast_idiv_by_const_test.cpp b/lib/mesa/src/util/tests/fast_idiv_by_const/fast_idiv_by_const_test.cpp new file mode 100644 index 000000000..3983a39ed --- /dev/null +++ b/lib/mesa/src/util/tests/fast_idiv_by_const/fast_idiv_by_const_test.cpp @@ -0,0 +1,472 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <gtest/gtest.h> +#include "util/bigmath.h" +#include "util/fast_idiv_by_const.h" +#include "util/u_math.h" + +#define RAND_TEST_ITERATIONS 100000 + +#define MAX_UINT(bits) \ + (((bits) == 64) ? UINT64_MAX : ((1ull << (bits)) - 1)) + +static inline uint64_t +utrunc(uint64_t x, unsigned num_bits) +{ + if (num_bits == 64) + return x; + + return (x << (64 - num_bits)) >> (64 - num_bits); +} + +static inline int64_t +strunc(int64_t x, unsigned num_bits) +{ + if (num_bits == 64) + return x; + + return (x << (64 - num_bits)) >> (64 - num_bits); +} + +static inline bool +uint_is_in_range(uint64_t x, unsigned num_bits) +{ + if (num_bits == 64) + return true; + + return x < (1ull << num_bits); +} + +static inline bool +sint_is_in_range(int64_t x, unsigned num_bits) +{ + if (num_bits == 64) + return true; + + return x >= -(1ll << (num_bits - 1)) && + x < (1ll << (num_bits - 1)); +} + +static inline uint64_t +uadd_sat(uint64_t a, uint64_t b, unsigned num_bits) +{ + assert(uint_is_in_range(a, num_bits)); + assert(uint_is_in_range(b, num_bits)); + + uint64_t sum = a + b; + if (num_bits == 64) { + /* Standard overflow check */ + return sum < a ? UINT64_MAX : sum; + } else { + /* Check if sum is more than num_bits */ + return (sum >> num_bits) ? MAX_UINT(num_bits) : sum; + } +} + +static inline uint64_t +umul_add_high(uint64_t a, uint64_t b, uint64_t c, unsigned num_bits) +{ + assert(uint_is_in_range(a, num_bits)); + assert(uint_is_in_range(b, num_bits)); + assert(uint_is_in_range(c, num_bits)); + + if (num_bits == 64) { + uint32_t a32[2] = { (uint32_t)a, (uint32_t)(a >> 32) }; + uint32_t b32[2] = { (uint32_t)b, (uint32_t)(b >> 32) }; + uint32_t c32[2] = { (uint32_t)c, (uint32_t)(c >> 32) }; + + uint32_t ab32[4]; + ubm_mul_u32arr(ab32, a32, b32); + + uint32_t abc32[4]; + ubm_add_u32arr(abc32, ab32, c32); + + return abc32[2] | ((uint64_t)abc32[3] << 32); + } else { + assert(num_bits <= 32); + return utrunc(((a * b) + c) >> num_bits, num_bits); + } +} + +static inline int64_t +smul_high(int64_t a, int64_t b, unsigned num_bits) +{ + assert(sint_is_in_range(a, num_bits)); + assert(sint_is_in_range(b, num_bits)); + + if (num_bits == 64) { + uint32_t a32[4] = { + (uint32_t)a, + (uint32_t)(a >> 32), + (uint32_t)(a >> 63), /* sign extend */ + (uint32_t)(a >> 63), /* sign extend */ + }; + uint32_t b32[4] = { + (uint32_t)b, + (uint32_t)(b >> 32), + (uint32_t)(b >> 63), /* sign extend */ + (uint32_t)(b >> 63), /* sign extend */ + }; + + uint32_t ab32[4]; + ubm_mul_u32arr(ab32, a32, b32); + + return ab32[2] | ((uint64_t)ab32[3] << 32); + } else { + assert(num_bits <= 32); + return strunc((a * b) >> num_bits, num_bits); + } +} + +static inline uint64_t +fast_udiv_add_sat(uint64_t n, struct util_fast_udiv_info m, unsigned num_bits) +{ + assert(uint_is_in_range(n, num_bits)); + assert(uint_is_in_range(m.multiplier, num_bits)); + + n = n >> m.pre_shift; + n = uadd_sat(n, m.increment, num_bits); + n = umul_add_high(n, m.multiplier, 0, num_bits); + n = n >> m.post_shift; + + return n; +} + +static inline uint64_t +fast_udiv_mul_add(uint64_t n, struct util_fast_udiv_info m, unsigned num_bits) +{ + assert(uint_is_in_range(n, num_bits)); + assert(uint_is_in_range(m.multiplier, num_bits)); + + n = n >> m.pre_shift; + n = umul_add_high(n, m.multiplier, + m.increment ? m.multiplier : 0, + num_bits); + n = n >> m.post_shift; + + return n; +} + +static inline uint64_t +fast_sdiv(int64_t n, int64_t d, struct util_fast_sdiv_info m, unsigned num_bits) +{ + assert(sint_is_in_range(n, num_bits)); + assert(sint_is_in_range(d, num_bits)); + assert(sint_is_in_range(m.multiplier, num_bits)); + + int64_t res; + res = smul_high(n, m.multiplier, num_bits); + if (d > 0 && m.multiplier < 0) + res = strunc(res + n, num_bits); + if (d < 0 && m.multiplier > 0) + res = strunc(res - n, num_bits); + res = res >> m.shift; + res = res - (res >> (num_bits - 1)); + + return res; +} + +static uint64_t +rand_uint(unsigned bits, unsigned min) +{ + assert(bits >= 4); + + /* Make sure we get some small and large numbers and powers of two every + * once in a while + */ + int k = rand() % 64; + if (k == 17) { + return min + (rand() % 16); + } else if (k == 42) { + return MAX_UINT(bits) - (rand() % 16); + } else if (k == 9) { + uint64_t r; + do { + r = 1ull << (rand() % bits); + } while (r < min); + return r; + } + + if (min == 0) { + assert(bits <= 64); + uint64_t r = 0; + for (unsigned i = 0; i < 8; i++) + r |= ((uint64_t)rand() & 0xf) << i * 8; + return r >> (63 - (rand() % bits)); + } else { + uint64_t r; + do { + r = rand_uint(bits, 0); + } while (r < min); + return r; + } +} + +static int64_t +rand_sint(unsigned bits, unsigned min_abs) +{ + /* Make sure we hit MIN_INT every once in a while */ + if (rand() % 64 == 37) + return -(1 << (bits - 1)); + + int64_t s = rand_uint(bits - 1, min_abs); + return rand() & 1 ? s : -s; +} + +static uint64_t +udiv(uint64_t a, uint64_t b, unsigned bit_size) +{ + switch (bit_size) { + case 64: return (uint64_t)a / (uint64_t)b; + case 32: return (uint32_t)a / (uint32_t)b; + case 16: return (uint16_t)a / (uint16_t)b; + case 8: return (uint8_t)a / (uint8_t)b; + default: + assert(!"Invalid bit size"); + return 0; + } +} + +static int64_t +sdiv(int64_t a, int64_t b, unsigned bit_size) +{ + switch (bit_size) { + case 64: return (int64_t)a / (int64_t)b; + case 32: return (int32_t)a / (int32_t)b; + case 16: return (int16_t)a / (int16_t)b; + case 8: return (int8_t)a / (int8_t)b; + default: + assert(!"Invalid bit size"); + return 0; + } +} + +static void +random_udiv_add_sat_test(unsigned bits, bool bounded) +{ + for (unsigned i = 0; i < RAND_TEST_ITERATIONS; i++) { + uint64_t n = rand_uint(bits, 0); + uint64_t d = rand_uint(bits, 2); + assert(uint_is_in_range(n, bits)); + assert(uint_is_in_range(d, bits) && d >= 2); + + unsigned n_bits = bounded ? util_logbase2_64(MAX2(n, 1)) + 1 : bits; + + struct util_fast_udiv_info m = + util_compute_fast_udiv_info(d, n_bits, bits); + EXPECT_EQ(fast_udiv_add_sat(n, m, bits), udiv(n, d, bits)); + } +} + +static void +random_udiv_mul_add_test(unsigned bits, bool bounded) +{ + for (unsigned i = 0; i < RAND_TEST_ITERATIONS; i++) { + uint64_t n = rand_uint(bits, 0); + uint64_t d = rand_uint(bits, 1); + assert(uint_is_in_range(n, bits)); + assert(uint_is_in_range(d, bits) && d >= 1); + + unsigned n_bits = bounded ? util_logbase2_64(MAX2(n, 1)) + 1: bits; + + struct util_fast_udiv_info m = + util_compute_fast_udiv_info(d, n_bits, bits); + EXPECT_EQ(fast_udiv_mul_add(n, m, bits), udiv(n, d, bits)); + } +} + +static void +random_sdiv_test(unsigned bits) +{ + for (unsigned i = 0; i < RAND_TEST_ITERATIONS; i++) { + int64_t n = rand_sint(bits, 0); + int64_t d; + do { + d = rand_sint(bits, 2); + } while (util_is_power_of_two_or_zero64(llabs(d))); + + assert(sint_is_in_range(n, bits)); + assert(sint_is_in_range(d, bits) && llabs(d) >= 2); + + struct util_fast_sdiv_info m = + util_compute_fast_sdiv_info(d, bits); + EXPECT_EQ(fast_sdiv(n, d, m, bits), sdiv(n, d, bits)); + } +} + +TEST(fast_idiv_by_const, uint8_add_sat) +{ + /* 8-bit is small enough we can brute-force the entire space */ + for (unsigned d = 2; d < 256; d++) { + for (unsigned n_bits = 1; n_bits <= 8; n_bits++) { + struct util_fast_udiv_info m = + util_compute_fast_udiv_info(d, n_bits, 8); + + for (unsigned n = 0; n < (1u << n_bits); n++) + EXPECT_EQ(fast_udiv_add_sat(n, m, 8), udiv(n, d, 8)); + } + } +} + +TEST(fast_idiv_by_const, uint8_mul_add) +{ + /* 8-bit is small enough we can brute-force the entire space */ + for (unsigned d = 2; d < 256; d++) { + for (unsigned n_bits = 1; n_bits <= 8; n_bits++) { + struct util_fast_udiv_info m = + util_compute_fast_udiv_info(d, n_bits, 8); + + for (unsigned n = 0; n < (1u << n_bits); n++) + EXPECT_EQ(fast_udiv_mul_add(n, m, 8), udiv(n, d, 8)); + } + } +} + +TEST(fast_idiv_by_const, int8) +{ + /* 8-bit is small enough we can brute-force the entire space */ + for (int n = -128; n < 128; n++) { + for (int d = -128; d < 128; d++) { + if (util_is_power_of_two_or_zero(abs(d))) + continue; + + struct util_fast_sdiv_info m = + util_compute_fast_sdiv_info(d, 8); + EXPECT_EQ(fast_sdiv(n, d, m, 8), sdiv(n, d, 8)); + } + } +} + +TEST(fast_idiv_by_const, uint16_add_sat_bounded) +{ + random_udiv_add_sat_test(16, true); +} + +TEST(fast_idiv_by_const, uint16_add_sat_full) +{ + random_udiv_add_sat_test(16, false); +} + +TEST(fast_idiv_by_const, uint16_mul_add_bounded) +{ + random_udiv_mul_add_test(16, true); +} + +TEST(fast_idiv_by_const, uint16_mul_add_full) +{ + random_udiv_mul_add_test(16, false); +} + +TEST(fast_idiv_by_const, int16) +{ + random_sdiv_test(16); +} + +TEST(fast_idiv_by_const, uint32_add_sat_bounded) +{ + random_udiv_add_sat_test(32, true); +} + +TEST(fast_idiv_by_const, uint32_add_sat_full) +{ + random_udiv_add_sat_test(32, false); +} + +TEST(fast_idiv_by_const, uint32_mul_add_bounded) +{ + random_udiv_mul_add_test(32, true); +} + +TEST(fast_idiv_by_const, uint32_mul_add_full) +{ + random_udiv_mul_add_test(32, false); +} + +TEST(fast_idiv_by_const, int32) +{ + random_sdiv_test(32); +} + +TEST(fast_idiv_by_const, util_fast_udiv32) +{ + for (unsigned i = 0; i < RAND_TEST_ITERATIONS; i++) { + uint32_t n = rand_uint(32, 0); + uint32_t d = rand_uint(32, 1); + + struct util_fast_udiv_info m = + util_compute_fast_udiv_info(d, 32, 32); + EXPECT_EQ(util_fast_udiv32(n, m), n / d); + } +} + +TEST(fast_idiv_by_const, util_fast_udiv32_nuw) +{ + for (unsigned i = 0; i < RAND_TEST_ITERATIONS; i++) { + uint32_t n = rand_uint(32, 0); + if (n == UINT32_MAX) + continue; + uint32_t d = rand_uint(32, 1); + + struct util_fast_udiv_info m = + util_compute_fast_udiv_info(d, 32, 32); + EXPECT_EQ(util_fast_udiv32_nuw(n, m), n / d); + } +} + +TEST(fast_idiv_by_const, util_fast_udiv32_u31_d_not_one) +{ + for (unsigned i = 0; i < RAND_TEST_ITERATIONS; i++) { + uint32_t n = rand_uint(31, 0); + uint32_t d = rand_uint(31, 2); + + struct util_fast_udiv_info m = + util_compute_fast_udiv_info(d, 31, 32); + EXPECT_EQ(util_fast_udiv32_u31_d_not_one(n, m), n / d); + } +} + +TEST(fast_idiv_by_const, uint64_add_sat_bounded) +{ + random_udiv_add_sat_test(64, true); +} + +TEST(fast_idiv_by_const, uint64_add_sat_full) +{ + random_udiv_add_sat_test(64, false); +} + +TEST(fast_idiv_by_const, uint64_mul_add_bounded) +{ + random_udiv_mul_add_test(64, true); +} + +TEST(fast_idiv_by_const, uint64_mul_add_full) +{ + random_udiv_mul_add_test(64, false); +} + +TEST(fast_idiv_by_const, int64) +{ + random_sdiv_test(64); +} diff --git a/lib/mesa/src/util/tests/fast_idiv_by_const/meson.build b/lib/mesa/src/util/tests/fast_idiv_by_const/meson.build new file mode 100644 index 000000000..8c3b79493 --- /dev/null +++ b/lib/mesa/src/util/tests/fast_idiv_by_const/meson.build @@ -0,0 +1,30 @@ +# Copyright © 2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +test( + 'fast_idiv_by_const', + executable( + 'fast_idiv_by_const_test', + 'fast_idiv_by_const_test.cpp', + dependencies : [dep_thread, dep_dl, idep_gtest], + include_directories : inc_common, + link_with : [libmesa_util], + ) +) diff --git a/lib/mesa/src/util/tests/hash_table/Makefile.am b/lib/mesa/src/util/tests/hash_table/Makefile.am index 8f12240ce..526454cb1 100644 --- a/lib/mesa/src/util/tests/hash_table/Makefile.am +++ b/lib/mesa/src/util/tests/hash_table/Makefile.am @@ -38,8 +38,11 @@ TESTS = \ insert_many \ null_destroy \ random_entry \ + remove_key \ remove_null \ replacement \ $() check_PROGRAMS = $(TESTS) + +EXTRA_DIST = meson.build diff --git a/lib/mesa/src/util/tests/hash_table/clear.c b/lib/mesa/src/util/tests/hash_table/clear.c index 526700bfb..3d6bf80c0 100644 --- a/lib/mesa/src/util/tests/hash_table/clear.c +++ b/lib/mesa/src/util/tests/hash_table/clear.c @@ -53,7 +53,6 @@ static void delete_function(struct hash_entry *entry) int main() { struct hash_table *ht; - struct hash_entry *entry; const uint32_t size = 1000; bool flags[size]; uint32_t i; diff --git a/lib/mesa/src/util/tests/hash_table/collision.c b/lib/mesa/src/util/tests/hash_table/collision.c index 69a4c29ec..ba8913281 100644 --- a/lib/mesa/src/util/tests/hash_table/collision.c +++ b/lib/mesa/src/util/tests/hash_table/collision.c @@ -37,7 +37,7 @@ main(int argc, char **argv) const char *str1 = "test1"; const char *str2 = "test2"; const char *str3 = "test3"; - struct hash_entry *entry1, *entry2, *search_entry; + struct hash_entry *entry1, *entry2; uint32_t bad_hash = 5; int i; diff --git a/lib/mesa/src/util/tests/hash_table/meson.build b/lib/mesa/src/util/tests/hash_table/meson.build new file mode 100644 index 000000000..c7b03f19c --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/meson.build @@ -0,0 +1,35 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +foreach t : ['clear', 'collision', 'delete_and_lookup', 'delete_management', + 'destroy_callback', 'insert_and_lookup', 'insert_many', + 'null_destroy', 'random_entry', 'remove_key', 'remove_null', + 'replacement'] + test( + t, + executable( + '@0@_test'.format(t), + files('@0@.c'.format(t)), + dependencies : [dep_thread, dep_dl], + include_directories : [inc_include, inc_util], + link_with : libmesa_util, + ) + ) +endforeach diff --git a/lib/mesa/src/util/tests/hash_table/remove_key.c b/lib/mesa/src/util/tests/hash_table/remove_key.c new file mode 100644 index 000000000..906de6799 --- /dev/null +++ b/lib/mesa/src/util/tests/hash_table/remove_key.c @@ -0,0 +1,63 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include "hash_table.h" + +int +main(int argc, char **argv) +{ + struct hash_table *ht; + const char *str1 = "test1"; + const char *str2 = "test2"; + struct hash_entry *entry; + + (void) argc; + (void) argv; + + ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string, _mesa_key_string_equal); + + _mesa_hash_table_insert(ht, str1, NULL); + _mesa_hash_table_insert(ht, str2, NULL); + + entry = _mesa_hash_table_search(ht, str2); + assert(strcmp(entry->key, str2) == 0); + + entry = _mesa_hash_table_search(ht, str1); + assert(strcmp(entry->key, str1) == 0); + + _mesa_hash_table_remove_key(ht, str1); + + entry = _mesa_hash_table_search(ht, str1); + assert(entry == NULL); + + entry = _mesa_hash_table_search(ht, str2); + assert(strcmp(entry->key, str2) == 0); + + _mesa_hash_table_destroy(ht, NULL); + + return 0; +} diff --git a/lib/mesa/src/util/tests/set/Makefile.am b/lib/mesa/src/util/tests/set/Makefile.am new file mode 100644 index 000000000..5529f4c14 --- /dev/null +++ b/lib/mesa/src/util/tests/set/Makefile.am @@ -0,0 +1,42 @@ +# Copyright © 2018 Intel +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gtest/include \ + $(PTHREAD_CFLAGS) \ + $(DEFINES) + +TESTS = set_test + +check_PROGRAMS = $(TESTS) + +set_test_SOURCES = \ + set_test.cpp + +set_test_LDADD = \ + $(top_builddir)/src/gtest/libgtest.la \ + $(top_builddir)/src/util/libmesautil.la \ + $(PTHREAD_LIBS) \ + $(DLOPEN_LIBS) + +EXTRA_DIST = meson.build diff --git a/lib/mesa/src/util/tests/set/Makefile.in b/lib/mesa/src/util/tests/set/Makefile.in new file mode 100644 index 000000000..0d8f2b6de --- /dev/null +++ b/lib/mesa/src/util/tests/set/Makefile.in @@ -0,0 +1,1220 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright © 2018 Intel +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +TESTS = set_test$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) +subdir = src/util/tests/set +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_gnu_make.m4 \ + $(top_srcdir)/m4/ax_check_python_mako_module.m4 \ + $(top_srcdir)/m4/ax_gcc_builtin.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_prog_bison.m4 \ + $(top_srcdir)/m4/ax_prog_flex.m4 \ + $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/VERSION $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = set_test$(EXEEXT) +am_set_test_OBJECTS = set_test.$(OBJEXT) +set_test_OBJECTS = $(am_set_test_OBJECTS) +am__DEPENDENCIES_1 = +set_test_DEPENDENCIES = $(top_builddir)/src/gtest/libgtest.la \ + $(top_builddir)/src/util/libmesautil.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/set_test.Po +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(set_test_SOURCES) +DIST_SOURCES = $(set_test_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/bin/depcomp \ + $(top_srcdir)/bin/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDGPU_CFLAGS = @AMDGPU_CFLAGS@ +AMDGPU_LIBS = @AMDGPU_LIBS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +ANDROID_CFLAGS = @ANDROID_CFLAGS@ +ANDROID_LIBS = @ANDROID_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BACKTRACE_CFLAGS = @BACKTRACE_CFLAGS@ +BACKTRACE_LIBS = @BACKTRACE_LIBS@ +BSYMBOLIC = @BSYMBOLIC@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@ +CLOCK_LIB = @CLOCK_LIB@ +CLOVER_STD_OVERRIDE = @CLOVER_STD_OVERRIDE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXX11_CXXFLAGS = @CXX11_CXXFLAGS@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +D3D_DRIVER_INSTALL_DIR = @D3D_DRIVER_INSTALL_DIR@ +DEFINES = @DEFINES@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DLOPEN_LIBS = @DLOPEN_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRIGL_CFLAGS = @DRIGL_CFLAGS@ +DRIGL_LIBS = @DRIGL_LIBS@ +DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@ +DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@ +DRI_LIB_DEPS = @DRI_LIB_DEPS@ +DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGL_CFLAGS = @EGL_CFLAGS@ +EGL_LIB_DEPS = @EGL_LIB_DEPS@ +EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@ +EGREP = @EGREP@ +ETNAVIV_CFLAGS = @ETNAVIV_CFLAGS@ +ETNAVIV_LIBS = @ETNAVIV_LIBS@ +EXEEXT = @EXEEXT@ +EXPAT_CFLAGS = @EXPAT_CFLAGS@ +EXPAT_LIBS = @EXPAT_LIBS@ +FGREP = @FGREP@ +GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@ +GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@ +GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@ +GC_SECTIONS = @GC_SECTIONS@ +GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@ +GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@ +GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@ +GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@ +GLPROTO_CFLAGS = @GLPROTO_CFLAGS@ +GLPROTO_LIBS = @GLPROTO_LIBS@ +GLVND_CFLAGS = @GLVND_CFLAGS@ +GLVND_LIBS = @GLVND_LIBS@ +GLX_TLS = @GLX_TLS@ +GL_LIB = @GL_LIB@ +GL_LIB_DEPS = @GL_LIB_DEPS@ +GL_PC_CFLAGS = @GL_PC_CFLAGS@ +GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@ +GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@ +GL_PKGCONF_LIB = @GL_PKGCONF_LIB@ +GREP = @GREP@ +I915_CFLAGS = @I915_CFLAGS@ +I915_LIBS = @I915_LIBS@ +INDENT = @INDENT@ +INDENT_FLAGS = @INDENT_FLAGS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LD_BUILD_ID = @LD_BUILD_ID@ +LD_NO_UNDEFINED = @LD_NO_UNDEFINED@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBATOMIC_LIBS = @LIBATOMIC_LIBS@ +LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@ +LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBELF_CFLAGS = @LIBELF_CFLAGS@ +LIBELF_LIBS = @LIBELF_LIBS@ +LIBGLVND_DATADIR = @LIBGLVND_DATADIR@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSENSORS_LIBS = @LIBSENSORS_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ +LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ +LIB_DIR = @LIB_DIR@ +LIB_EXT = @LIB_EXT@ +LIPO = @LIPO@ +LLVM_CFLAGS = @LLVM_CFLAGS@ +LLVM_CONFIG = @LLVM_CONFIG@ +LLVM_CXXFLAGS = @LLVM_CXXFLAGS@ +LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@ +LLVM_LDFLAGS = @LLVM_LDFLAGS@ +LLVM_LIBS = @LLVM_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@ +MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@ +NINE_MAJOR = @NINE_MAJOR@ +NINE_MINOR = @NINE_MINOR@ +NINE_PATCH = @NINE_PATCH@ +NINE_VERSION = @NINE_VERSION@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@ +NOUVEAU_LIBS = @NOUVEAU_LIBS@ +NVVIEUX_CFLAGS = @NVVIEUX_CFLAGS@ +NVVIEUX_LIBS = @NVVIEUX_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OMX_BELLAGIO_CFLAGS = @OMX_BELLAGIO_CFLAGS@ +OMX_BELLAGIO_LIBS = @OMX_BELLAGIO_LIBS@ +OMX_BELLAGIO_LIB_INSTALL_DIR = @OMX_BELLAGIO_LIB_INSTALL_DIR@ +OMX_TIZONIA_CFLAGS = @OMX_TIZONIA_CFLAGS@ +OMX_TIZONIA_LIBS = @OMX_TIZONIA_LIBS@ +OMX_TIZONIA_LIB_INSTALL_DIR = @OMX_TIZONIA_LIB_INSTALL_DIR@ +OPENCL_LIBNAME = @OPENCL_LIBNAME@ +OPENCL_VERSION = @OPENCL_VERSION@ +OSMESA_LIB = @OSMESA_LIB@ +OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@ +OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@ +OSMESA_PC_REQ = @OSMESA_PC_REQ@ +OSMESA_VERSION = @OSMESA_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +PTHREADSTUBS_CFLAGS = @PTHREADSTUBS_CFLAGS@ +PTHREADSTUBS_LIBS = @PTHREADSTUBS_LIBS@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PWR8_CFLAGS = @PWR8_CFLAGS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RADEON_CFLAGS = @RADEON_CFLAGS@ +RADEON_LIBS = @RADEON_LIBS@ +RANLIB = @RANLIB@ +RM = @RM@ +SCANNER_ARG = @SCANNER_ARG@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIMPENROSE_CFLAGS = @SIMPENROSE_CFLAGS@ +SIMPENROSE_LIBS = @SIMPENROSE_LIBS@ +SSE41_CFLAGS = @SSE41_CFLAGS@ +STRIP = @STRIP@ +SWR_AVX2_CXXFLAGS = @SWR_AVX2_CXXFLAGS@ +SWR_AVX_CXXFLAGS = @SWR_AVX_CXXFLAGS@ +SWR_KNL_CXXFLAGS = @SWR_KNL_CXXFLAGS@ +SWR_SKX_CXXFLAGS = @SWR_SKX_CXXFLAGS@ +V3D_SIMULATOR_CFLAGS = @V3D_SIMULATOR_CFLAGS@ +V3D_SIMULATOR_LIBS = @V3D_SIMULATOR_LIBS@ +VALGRIND_CFLAGS = @VALGRIND_CFLAGS@ +VALGRIND_LIBS = @VALGRIND_LIBS@ +VA_CFLAGS = @VA_CFLAGS@ +VA_LIBS = @VA_LIBS@ +VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@ +VA_MAJOR = @VA_MAJOR@ +VA_MINOR = @VA_MINOR@ +VC4_CFLAGS = @VC4_CFLAGS@ +VC4_LIBS = @VC4_LIBS@ +VDPAU_CFLAGS = @VDPAU_CFLAGS@ +VDPAU_LIBS = @VDPAU_LIBS@ +VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@ +VDPAU_MAJOR = @VDPAU_MAJOR@ +VDPAU_MINOR = @VDPAU_MINOR@ +VERSION = @VERSION@ +VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ +VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@ +VL_CFLAGS = @VL_CFLAGS@ +VL_LIBS = @VL_LIBS@ +VULKAN_ICD_INSTALL_DIR = @VULKAN_ICD_INSTALL_DIR@ +WAYLAND_CLIENT_CFLAGS = @WAYLAND_CLIENT_CFLAGS@ +WAYLAND_CLIENT_LIBS = @WAYLAND_CLIENT_LIBS@ +WAYLAND_EGL_CFLAGS = @WAYLAND_EGL_CFLAGS@ +WAYLAND_EGL_LIBS = @WAYLAND_EGL_LIBS@ +WAYLAND_PROTOCOLS_CFLAGS = @WAYLAND_PROTOCOLS_CFLAGS@ +WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ +WAYLAND_PROTOCOLS_LIBS = @WAYLAND_PROTOCOLS_LIBS@ +WAYLAND_SCANNER = @WAYLAND_SCANNER@ +WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ +WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ +WAYLAND_SERVER_CFLAGS = @WAYLAND_SERVER_CFLAGS@ +WAYLAND_SERVER_LIBS = @WAYLAND_SERVER_LIBS@ +WNO_OVERRIDE_INIT = @WNO_OVERRIDE_INIT@ +X11_INCLUDES = @X11_INCLUDES@ +XA_MAJOR = @XA_MAJOR@ +XA_MINOR = @XA_MINOR@ +XA_PATCH = @XA_PATCH@ +XA_VERSION = @XA_VERSION@ +XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@ +XCB_DRI2_LIBS = @XCB_DRI2_LIBS@ +XCB_DRI3_CFLAGS = @XCB_DRI3_CFLAGS@ +XCB_DRI3_LIBS = @XCB_DRI3_LIBS@ +XCB_DRI3_MODIFIERS_CFLAGS = @XCB_DRI3_MODIFIERS_CFLAGS@ +XCB_DRI3_MODIFIERS_LIBS = @XCB_DRI3_MODIFIERS_LIBS@ +XCB_RANDR_CFLAGS = @XCB_RANDR_CFLAGS@ +XCB_RANDR_LIBS = @XCB_RANDR_LIBS@ +XLIBGL_CFLAGS = @XLIBGL_CFLAGS@ +XLIBGL_LIBS = @XLIBGL_LIBS@ +XLIB_RANDR_CFLAGS = @XLIB_RANDR_CFLAGS@ +XLIB_RANDR_LIBS = @XLIB_RANDR_LIBS@ +XVMC_CFLAGS = @XVMC_CFLAGS@ +XVMC_LIBS = @XVMC_LIBS@ +XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@ +XVMC_MAJOR = @XVMC_MAJOR@ +XVMC_MINOR = @XVMC_MINOR@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acv_mako_found = @acv_mako_found@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +ifGNUmake = @ifGNUmake@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gtest/include \ + $(PTHREAD_CFLAGS) \ + $(DEFINES) + +set_test_SOURCES = \ + set_test.cpp + +set_test_LDADD = \ + $(top_builddir)/src/gtest/libgtest.la \ + $(top_builddir)/src/util/libmesautil.la \ + $(PTHREAD_LIBS) \ + $(DLOPEN_LIBS) + +EXTRA_DIST = meson.build +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/util/tests/set/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/util/tests/set/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +set_test$(EXEEXT): $(set_test_OBJECTS) $(set_test_DEPENDENCIES) $(EXTRA_set_test_DEPENDENCIES) + @rm -f set_test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(set_test_OBJECTS) $(set_test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_test.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: $(check_PROGRAMS) + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +set_test.log: set_test$(EXEEXT) + @p='set_test$(EXEEXT)'; \ + b='set_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/set_test.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/set_test.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/mesa/src/util/tests/set/meson.build b/lib/mesa/src/util/tests/set/meson.build new file mode 100644 index 000000000..add3fc560 --- /dev/null +++ b/lib/mesa/src/util/tests/set/meson.build @@ -0,0 +1,30 @@ +# Copyright © 2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +test( + 'set', + executable( + 'set_test', + 'set_test.cpp', + dependencies : [dep_thread, dep_dl, idep_gtest], + include_directories : inc_common, + link_with : [libmesa_util], + ) +) diff --git a/lib/mesa/src/util/tests/set/set_test.cpp b/lib/mesa/src/util/tests/set/set_test.cpp new file mode 100644 index 000000000..a1eef0b3d --- /dev/null +++ b/lib/mesa/src/util/tests/set/set_test.cpp @@ -0,0 +1,115 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <gtest/gtest.h> +#include "util/hash_table.h" +#include "util/set.h" + +TEST(set, basic) +{ + struct set *s = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); + struct set_entry *entry; + + const void *a = (const void *)10; + const void *b = (const void *)20; + + _mesa_set_add(s, a); + _mesa_set_add(s, b); + EXPECT_EQ(s->entries, 2); + + _mesa_set_add(s, a); + EXPECT_EQ(s->entries, 2); + + entry = _mesa_set_search(s, a); + EXPECT_TRUE(entry); + EXPECT_EQ(entry->key, a); + + _mesa_set_remove(s, entry); + EXPECT_EQ(s->entries, 1); + + entry = _mesa_set_search(s, a); + EXPECT_FALSE(entry); + + _mesa_set_destroy(s, NULL); +} + +TEST(set, clone) +{ + struct set *s = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); + struct set_entry *entry; + + const void *a = (const void *)10; + const void *b = (const void *)20; + const void *c = (const void *)30; + + _mesa_set_add(s, a); + _mesa_set_add(s, b); + _mesa_set_add(s, c); + + entry = _mesa_set_search(s, c); + EXPECT_TRUE(entry); + EXPECT_EQ(entry->key, c); + + _mesa_set_remove(s, entry); + EXPECT_EQ(s->entries, 2); + + struct set *clone = _mesa_set_clone(s, NULL); + EXPECT_EQ(clone->entries, 2); + + EXPECT_TRUE(_mesa_set_search(clone, a)); + EXPECT_TRUE(_mesa_set_search(clone, b)); + EXPECT_FALSE(_mesa_set_search(clone, c)); + + _mesa_set_destroy(s, NULL); + _mesa_set_destroy(clone, NULL); +} + +TEST(set, remove_key) +{ + struct set *s = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); + + const void *a = (const void *)10; + const void *b = (const void *)20; + const void *c = (const void *)30; + + _mesa_set_add(s, a); + _mesa_set_add(s, b); + EXPECT_EQ(s->entries, 2); + + /* Remove existing key. */ + _mesa_set_remove_key(s, a); + EXPECT_EQ(s->entries, 1); + EXPECT_FALSE(_mesa_set_search(s, a)); + EXPECT_TRUE(_mesa_set_search(s, b)); + + /* Remove non-existing key. */ + _mesa_set_remove_key(s, c); + EXPECT_EQ(s->entries, 1); + EXPECT_FALSE(_mesa_set_search(s, a)); + EXPECT_TRUE(_mesa_set_search(s, b)); + + _mesa_set_destroy(s, NULL); +} diff --git a/lib/mesa/src/util/tests/string_buffer/Makefile.am b/lib/mesa/src/util/tests/string_buffer/Makefile.am index bd04d8634..8bc8a9c9b 100644 --- a/lib/mesa/src/util/tests/string_buffer/Makefile.am +++ b/lib/mesa/src/util/tests/string_buffer/Makefile.am @@ -38,3 +38,5 @@ string_buffer_test_LDADD = \ $(top_builddir)/src/util/libmesautil.la \ $(PTHREAD_LIBS) \ $(DLOPEN_LIBS) + +EXTRA_DIST = meson.build diff --git a/lib/mesa/src/util/tests/string_buffer/meson.build b/lib/mesa/src/util/tests/string_buffer/meson.build new file mode 100644 index 000000000..9f42e3550 --- /dev/null +++ b/lib/mesa/src/util/tests/string_buffer/meson.build @@ -0,0 +1,30 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +test( + 'string_buffer', + executable( + 'string_buffer_test', + 'string_buffer_test.cpp', + dependencies : [dep_thread, dep_dl, idep_gtest], + include_directories : inc_common, + link_with : [libmesa_util], + ) +) diff --git a/lib/mesa/src/util/tests/string_buffer/string_buffer_test.cpp b/lib/mesa/src/util/tests/string_buffer/string_buffer_test.cpp index 545f607fa..afb6dfb2a 100644 --- a/lib/mesa/src/util/tests/string_buffer/string_buffer_test.cpp +++ b/lib/mesa/src/util/tests/string_buffer/string_buffer_test.cpp @@ -95,15 +95,15 @@ TEST_F(string_buffer, string_buffer_tests) EXPECT_TRUE(strlen(buf->buf) == 0); /* Test a string with some formatting */ - sprintf(str4, "Testing formatting %d, %f", 100, 1.0); + snprintf(str4, sizeof(str4), "Testing formatting %d, %f", 100, 1.0); EXPECT_TRUE(_mesa_string_buffer_printf(buf, "Testing formatting %d, %f", 100, 1.0)); EXPECT_TRUE(strcmp(buf->buf, str4) == 0); /* Compile a string with some other formatting */ - sprintf(str5, "Testing formatting %d, %x", 100, 0xDEADBEAF); + snprintf(str5, sizeof(str5), "Testing formatting %d, %x", 100, 0xDEADBEAF); /* Concatenate str5 to str4 */ - strcat(str4, str5); + strncat(str4, str5, sizeof(str5)); /* Now use the formatted append function again */ EXPECT_TRUE(_mesa_string_buffer_printf(buf, "Testing formatting %d, %x", 100, 0xDEADBEAF)); diff --git a/lib/mesa/src/util/tests/vma/Makefile.am b/lib/mesa/src/util/tests/vma/Makefile.am new file mode 100644 index 000000000..b9ca8f597 --- /dev/null +++ b/lib/mesa/src/util/tests/vma/Makefile.am @@ -0,0 +1,39 @@ +# Copyright © 2018 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/util \ + $(DEFINES) + +TESTS = vma_random_test + +check_PROGRAMS = $(TESTS) + +vma_random_test_SOURCES = \ + vma_random_test.cpp + +vma_random_test_LDADD = \ + $(top_builddir)/src/util/libmesautil.la + +vma_random_test_CXXFLAGS = $(CXX11_CXXFLAGS) + +EXTRA_DIST = meson.build diff --git a/lib/mesa/src/util/tests/vma/Makefile.in b/lib/mesa/src/util/tests/vma/Makefile.in new file mode 100644 index 000000000..92afaa356 --- /dev/null +++ b/lib/mesa/src/util/tests/vma/Makefile.in @@ -0,0 +1,1233 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright © 2018 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +TESTS = vma_random_test$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) +subdir = src/util/tests/vma +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_gnu_make.m4 \ + $(top_srcdir)/m4/ax_check_python_mako_module.m4 \ + $(top_srcdir)/m4/ax_gcc_builtin.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_prog_bison.m4 \ + $(top_srcdir)/m4/ax_prog_flex.m4 \ + $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/VERSION $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = vma_random_test$(EXEEXT) +am_vma_random_test_OBJECTS = \ + vma_random_test-vma_random_test.$(OBJEXT) +vma_random_test_OBJECTS = $(am_vma_random_test_OBJECTS) +vma_random_test_DEPENDENCIES = \ + $(top_builddir)/src/util/libmesautil.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +vma_random_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(vma_random_test_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/bin/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/vma_random_test-vma_random_test.Po +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(vma_random_test_SOURCES) +DIST_SOURCES = $(vma_random_test_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/bin/depcomp \ + $(top_srcdir)/bin/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDGPU_CFLAGS = @AMDGPU_CFLAGS@ +AMDGPU_LIBS = @AMDGPU_LIBS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +ANDROID_CFLAGS = @ANDROID_CFLAGS@ +ANDROID_LIBS = @ANDROID_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BACKTRACE_CFLAGS = @BACKTRACE_CFLAGS@ +BACKTRACE_LIBS = @BACKTRACE_LIBS@ +BSYMBOLIC = @BSYMBOLIC@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@ +CLOCK_LIB = @CLOCK_LIB@ +CLOVER_STD_OVERRIDE = @CLOVER_STD_OVERRIDE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXX11_CXXFLAGS = @CXX11_CXXFLAGS@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +D3D_DRIVER_INSTALL_DIR = @D3D_DRIVER_INSTALL_DIR@ +DEFINES = @DEFINES@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DLOPEN_LIBS = @DLOPEN_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRIGL_CFLAGS = @DRIGL_CFLAGS@ +DRIGL_LIBS = @DRIGL_LIBS@ +DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@ +DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@ +DRI_LIB_DEPS = @DRI_LIB_DEPS@ +DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGL_CFLAGS = @EGL_CFLAGS@ +EGL_LIB_DEPS = @EGL_LIB_DEPS@ +EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@ +EGREP = @EGREP@ +ETNAVIV_CFLAGS = @ETNAVIV_CFLAGS@ +ETNAVIV_LIBS = @ETNAVIV_LIBS@ +EXEEXT = @EXEEXT@ +EXPAT_CFLAGS = @EXPAT_CFLAGS@ +EXPAT_LIBS = @EXPAT_LIBS@ +FGREP = @FGREP@ +GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@ +GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@ +GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@ +GC_SECTIONS = @GC_SECTIONS@ +GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@ +GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@ +GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@ +GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@ +GLPROTO_CFLAGS = @GLPROTO_CFLAGS@ +GLPROTO_LIBS = @GLPROTO_LIBS@ +GLVND_CFLAGS = @GLVND_CFLAGS@ +GLVND_LIBS = @GLVND_LIBS@ +GLX_TLS = @GLX_TLS@ +GL_LIB = @GL_LIB@ +GL_LIB_DEPS = @GL_LIB_DEPS@ +GL_PC_CFLAGS = @GL_PC_CFLAGS@ +GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@ +GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@ +GL_PKGCONF_LIB = @GL_PKGCONF_LIB@ +GREP = @GREP@ +I915_CFLAGS = @I915_CFLAGS@ +I915_LIBS = @I915_LIBS@ +INDENT = @INDENT@ +INDENT_FLAGS = @INDENT_FLAGS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LD_BUILD_ID = @LD_BUILD_ID@ +LD_NO_UNDEFINED = @LD_NO_UNDEFINED@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBATOMIC_LIBS = @LIBATOMIC_LIBS@ +LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@ +LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBELF_CFLAGS = @LIBELF_CFLAGS@ +LIBELF_LIBS = @LIBELF_LIBS@ +LIBGLVND_DATADIR = @LIBGLVND_DATADIR@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSENSORS_LIBS = @LIBSENSORS_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ +LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ +LIB_DIR = @LIB_DIR@ +LIB_EXT = @LIB_EXT@ +LIPO = @LIPO@ +LLVM_CFLAGS = @LLVM_CFLAGS@ +LLVM_CONFIG = @LLVM_CONFIG@ +LLVM_CXXFLAGS = @LLVM_CXXFLAGS@ +LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@ +LLVM_LDFLAGS = @LLVM_LDFLAGS@ +LLVM_LIBS = @LLVM_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@ +MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@ +NINE_MAJOR = @NINE_MAJOR@ +NINE_MINOR = @NINE_MINOR@ +NINE_PATCH = @NINE_PATCH@ +NINE_VERSION = @NINE_VERSION@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@ +NOUVEAU_LIBS = @NOUVEAU_LIBS@ +NVVIEUX_CFLAGS = @NVVIEUX_CFLAGS@ +NVVIEUX_LIBS = @NVVIEUX_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OMX_BELLAGIO_CFLAGS = @OMX_BELLAGIO_CFLAGS@ +OMX_BELLAGIO_LIBS = @OMX_BELLAGIO_LIBS@ +OMX_BELLAGIO_LIB_INSTALL_DIR = @OMX_BELLAGIO_LIB_INSTALL_DIR@ +OMX_TIZONIA_CFLAGS = @OMX_TIZONIA_CFLAGS@ +OMX_TIZONIA_LIBS = @OMX_TIZONIA_LIBS@ +OMX_TIZONIA_LIB_INSTALL_DIR = @OMX_TIZONIA_LIB_INSTALL_DIR@ +OPENCL_LIBNAME = @OPENCL_LIBNAME@ +OPENCL_VERSION = @OPENCL_VERSION@ +OSMESA_LIB = @OSMESA_LIB@ +OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@ +OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@ +OSMESA_PC_REQ = @OSMESA_PC_REQ@ +OSMESA_VERSION = @OSMESA_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +PTHREADSTUBS_CFLAGS = @PTHREADSTUBS_CFLAGS@ +PTHREADSTUBS_LIBS = @PTHREADSTUBS_LIBS@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PWR8_CFLAGS = @PWR8_CFLAGS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RADEON_CFLAGS = @RADEON_CFLAGS@ +RADEON_LIBS = @RADEON_LIBS@ +RANLIB = @RANLIB@ +RM = @RM@ +SCANNER_ARG = @SCANNER_ARG@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIMPENROSE_CFLAGS = @SIMPENROSE_CFLAGS@ +SIMPENROSE_LIBS = @SIMPENROSE_LIBS@ +SSE41_CFLAGS = @SSE41_CFLAGS@ +STRIP = @STRIP@ +SWR_AVX2_CXXFLAGS = @SWR_AVX2_CXXFLAGS@ +SWR_AVX_CXXFLAGS = @SWR_AVX_CXXFLAGS@ +SWR_KNL_CXXFLAGS = @SWR_KNL_CXXFLAGS@ +SWR_SKX_CXXFLAGS = @SWR_SKX_CXXFLAGS@ +V3D_SIMULATOR_CFLAGS = @V3D_SIMULATOR_CFLAGS@ +V3D_SIMULATOR_LIBS = @V3D_SIMULATOR_LIBS@ +VALGRIND_CFLAGS = @VALGRIND_CFLAGS@ +VALGRIND_LIBS = @VALGRIND_LIBS@ +VA_CFLAGS = @VA_CFLAGS@ +VA_LIBS = @VA_LIBS@ +VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@ +VA_MAJOR = @VA_MAJOR@ +VA_MINOR = @VA_MINOR@ +VC4_CFLAGS = @VC4_CFLAGS@ +VC4_LIBS = @VC4_LIBS@ +VDPAU_CFLAGS = @VDPAU_CFLAGS@ +VDPAU_LIBS = @VDPAU_LIBS@ +VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@ +VDPAU_MAJOR = @VDPAU_MAJOR@ +VDPAU_MINOR = @VDPAU_MINOR@ +VERSION = @VERSION@ +VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ +VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@ +VL_CFLAGS = @VL_CFLAGS@ +VL_LIBS = @VL_LIBS@ +VULKAN_ICD_INSTALL_DIR = @VULKAN_ICD_INSTALL_DIR@ +WAYLAND_CLIENT_CFLAGS = @WAYLAND_CLIENT_CFLAGS@ +WAYLAND_CLIENT_LIBS = @WAYLAND_CLIENT_LIBS@ +WAYLAND_EGL_CFLAGS = @WAYLAND_EGL_CFLAGS@ +WAYLAND_EGL_LIBS = @WAYLAND_EGL_LIBS@ +WAYLAND_PROTOCOLS_CFLAGS = @WAYLAND_PROTOCOLS_CFLAGS@ +WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ +WAYLAND_PROTOCOLS_LIBS = @WAYLAND_PROTOCOLS_LIBS@ +WAYLAND_SCANNER = @WAYLAND_SCANNER@ +WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ +WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ +WAYLAND_SERVER_CFLAGS = @WAYLAND_SERVER_CFLAGS@ +WAYLAND_SERVER_LIBS = @WAYLAND_SERVER_LIBS@ +WNO_OVERRIDE_INIT = @WNO_OVERRIDE_INIT@ +X11_INCLUDES = @X11_INCLUDES@ +XA_MAJOR = @XA_MAJOR@ +XA_MINOR = @XA_MINOR@ +XA_PATCH = @XA_PATCH@ +XA_VERSION = @XA_VERSION@ +XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@ +XCB_DRI2_LIBS = @XCB_DRI2_LIBS@ +XCB_DRI3_CFLAGS = @XCB_DRI3_CFLAGS@ +XCB_DRI3_LIBS = @XCB_DRI3_LIBS@ +XCB_DRI3_MODIFIERS_CFLAGS = @XCB_DRI3_MODIFIERS_CFLAGS@ +XCB_DRI3_MODIFIERS_LIBS = @XCB_DRI3_MODIFIERS_LIBS@ +XCB_RANDR_CFLAGS = @XCB_RANDR_CFLAGS@ +XCB_RANDR_LIBS = @XCB_RANDR_LIBS@ +XLIBGL_CFLAGS = @XLIBGL_CFLAGS@ +XLIBGL_LIBS = @XLIBGL_LIBS@ +XLIB_RANDR_CFLAGS = @XLIB_RANDR_CFLAGS@ +XLIB_RANDR_LIBS = @XLIB_RANDR_LIBS@ +XVMC_CFLAGS = @XVMC_CFLAGS@ +XVMC_LIBS = @XVMC_LIBS@ +XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@ +XVMC_MAJOR = @XVMC_MAJOR@ +XVMC_MINOR = @XVMC_MINOR@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acv_mako_found = @acv_mako_found@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +ifGNUmake = @ifGNUmake@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/util \ + $(DEFINES) + +vma_random_test_SOURCES = \ + vma_random_test.cpp + +vma_random_test_LDADD = \ + $(top_builddir)/src/util/libmesautil.la + +vma_random_test_CXXFLAGS = $(CXX11_CXXFLAGS) +EXTRA_DIST = meson.build +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/util/tests/vma/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/util/tests/vma/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +vma_random_test$(EXEEXT): $(vma_random_test_OBJECTS) $(vma_random_test_DEPENDENCIES) $(EXTRA_vma_random_test_DEPENDENCIES) + @rm -f vma_random_test$(EXEEXT) + $(AM_V_CXXLD)$(vma_random_test_LINK) $(vma_random_test_OBJECTS) $(vma_random_test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vma_random_test-vma_random_test.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +vma_random_test-vma_random_test.o: vma_random_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vma_random_test_CXXFLAGS) $(CXXFLAGS) -MT vma_random_test-vma_random_test.o -MD -MP -MF $(DEPDIR)/vma_random_test-vma_random_test.Tpo -c -o vma_random_test-vma_random_test.o `test -f 'vma_random_test.cpp' || echo '$(srcdir)/'`vma_random_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vma_random_test-vma_random_test.Tpo $(DEPDIR)/vma_random_test-vma_random_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='vma_random_test.cpp' object='vma_random_test-vma_random_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vma_random_test_CXXFLAGS) $(CXXFLAGS) -c -o vma_random_test-vma_random_test.o `test -f 'vma_random_test.cpp' || echo '$(srcdir)/'`vma_random_test.cpp + +vma_random_test-vma_random_test.obj: vma_random_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vma_random_test_CXXFLAGS) $(CXXFLAGS) -MT vma_random_test-vma_random_test.obj -MD -MP -MF $(DEPDIR)/vma_random_test-vma_random_test.Tpo -c -o vma_random_test-vma_random_test.obj `if test -f 'vma_random_test.cpp'; then $(CYGPATH_W) 'vma_random_test.cpp'; else $(CYGPATH_W) '$(srcdir)/vma_random_test.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vma_random_test-vma_random_test.Tpo $(DEPDIR)/vma_random_test-vma_random_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='vma_random_test.cpp' object='vma_random_test-vma_random_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vma_random_test_CXXFLAGS) $(CXXFLAGS) -c -o vma_random_test-vma_random_test.obj `if test -f 'vma_random_test.cpp'; then $(CYGPATH_W) 'vma_random_test.cpp'; else $(CYGPATH_W) '$(srcdir)/vma_random_test.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: $(check_PROGRAMS) + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +vma_random_test.log: vma_random_test$(EXEEXT) + @p='vma_random_test$(EXEEXT)'; \ + b='vma_random_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/vma_random_test-vma_random_test.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/vma_random_test-vma_random_test.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/mesa/src/util/tests/vma/meson.build b/lib/mesa/src/util/tests/vma/meson.build new file mode 100644 index 000000000..53562db31 --- /dev/null +++ b/lib/mesa/src/util/tests/vma/meson.build @@ -0,0 +1,29 @@ +# Copyright © 2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +test( + 'vma_random', + executable( + 'vma_random_test', + 'vma_random_test.cpp', + include_directories : [inc_include, inc_util], + link_with : [libmesa_util], + ) +) diff --git a/lib/mesa/src/util/tests/vma/vma_random_test.cpp b/lib/mesa/src/util/tests/vma/vma_random_test.cpp new file mode 100644 index 000000000..1f194fcdf --- /dev/null +++ b/lib/mesa/src/util/tests/vma/vma_random_test.cpp @@ -0,0 +1,244 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* it is a test after all */ +#undef NDEBUG + +#include <algorithm> +#include <cassert> +#include <climits> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <random> +#include <set> +#include <vector> + +#include <err.h> + +#include "vma.h" + +namespace { + +static const uint64_t MEM_PAGE_SIZE = 4096; + +struct allocation { + uint64_t start_page; + uint64_t num_pages; +}; + +struct allocation_less { + bool operator()(const allocation& lhs, const allocation& rhs) const + { + assert(lhs.start_page + lhs.num_pages > lhs.start_page); + return lhs.start_page + lhs.num_pages <= rhs.start_page; + } +}; + +constexpr uint64_t allocation_end_page(const allocation& a) { + return a.start_page + a.num_pages; +} + +struct random_test { + static const uint64_t MEM_START_PAGE = 1; + static const uint64_t MEM_SIZE = 0xfffffffffffff000; + static const uint64_t MEM_PAGES = MEM_SIZE / MEM_PAGE_SIZE; + + random_test(uint_fast32_t seed) + : heap_holes{allocation{MEM_START_PAGE, MEM_PAGES}}, rand{seed} + { + util_vma_heap_init(&heap, MEM_START_PAGE * MEM_PAGE_SIZE, MEM_SIZE); + } + + void test(unsigned long count) + { + std::uniform_int_distribution<> one_to_thousand(1, 1000); + while (count-- > 0) { + int action = one_to_thousand(rand); + if (action == 1) fill(); + else if (action == 2) empty(); + else if (action < 374) dealloc(); + else alloc(); + } + } + + bool alloc(uint64_t size_order=52, uint64_t align_order=52) + { + std::geometric_distribution<> dist; + + if (align_order > 51) + align_order = std::min(dist(rand), 51); + uint64_t align_pages = 1ULL << align_order; + uint64_t align = align_pages * MEM_PAGE_SIZE; + + if (size_order > 51) + size_order = std::min(dist(rand), 51); + uint64_t size_pages = 1ULL << size_order; + uint64_t size = size_pages * MEM_PAGE_SIZE; + + uint64_t addr = util_vma_heap_alloc(&heap, size, align); + + if (addr == 0) { + /* assert no gaps are present in the tracker that could satisfy this + * allocation. + */ + for (const auto& hole : heap_holes) { + uint64_t hole_alignment_pages = + (align_pages - (hole.start_page % align_pages)) % align_pages; + assert(hole.num_pages < size_pages + hole_alignment_pages); + } + return false; + } else { + assert(addr % align == 0); + uint64_t addr_page = addr / MEM_PAGE_SIZE; + allocation a{addr_page, size_pages}; + auto i = heap_holes.find(a); + assert(i != end(heap_holes)); + allocation hole = *i; + + assert(hole.start_page <= addr_page); + assert(hole.num_pages >= size_pages + addr_page - hole.start_page); + + heap_holes.erase(i); + if (hole.start_page < a.start_page) { + heap_holes.emplace(allocation{hole.start_page, + a.start_page - hole.start_page}); + } + if (allocation_end_page(hole) > allocation_end_page(a)) { + heap_holes.emplace(allocation{allocation_end_page(a), + allocation_end_page(hole) - allocation_end_page(a)}); + } + + allocations.push_back(a); + return true; + } + } + + void dealloc() + { + if (allocations.size() == 0) + return; + + std::uniform_int_distribution<> dist(0, allocations.size() - 1); + int to_dealloc = dist(rand); + + std::swap(allocations.at(to_dealloc), allocations.back()); + allocation a = allocations.back(); + allocations.pop_back(); + + util_vma_heap_free(&heap, a.start_page * MEM_PAGE_SIZE, + a.num_pages * MEM_PAGE_SIZE); + + assert(heap_holes.find(a) == end(heap_holes)); + auto next = heap_holes.upper_bound(a); + if (next != end(heap_holes)) { + if (next->start_page == allocation_end_page(a)) { + allocation x {a.start_page, a.num_pages + next->num_pages}; + next = heap_holes.erase(next); + next = heap_holes.insert(next, x); + + if (next != begin(heap_holes)) { + auto prev = next; + prev--; + if (allocation_end_page(*prev) == next->start_page) { + allocation x {prev->start_page, + prev->num_pages + next->num_pages}; + + heap_holes.erase(prev); + next = heap_holes.erase(next); + heap_holes.insert(next, x); + } + } + + return; + } + } + + if (next != begin(heap_holes)) { + auto prev = next; + prev--; + if (allocation_end_page(*prev) == a.start_page) { + allocation x {prev->start_page, prev->num_pages + a.num_pages}; + next = heap_holes.erase(prev); + heap_holes.insert(next, x); + + return; + } + } + + heap_holes.emplace(a); + } + + void fill() + { + for (int sz = 51; sz >= 0; sz--) { + while (alloc(sz, 0)) + ; + } + assert(heap_holes.empty()); + } + + void empty() + { + while (allocations.size() != 0) + dealloc(); + assert(heap_holes.size() == 1); + auto& hole = *begin(heap_holes); + assert(hole.start_page == MEM_START_PAGE && hole.num_pages == MEM_PAGES); + } + + struct util_vma_heap heap; + std::set<allocation, allocation_less> heap_holes; + std::default_random_engine rand; + std::vector<allocation> allocations; +}; + +} + +int main(int argc, char **argv) +{ + unsigned long seed, count; + if (argc == 3) { + char *arg_end = NULL; + seed = strtoul(argv[1], &arg_end, 0); + if (!arg_end || *arg_end || seed == ULONG_MAX) + errx(1, "invalid seed \"%s\"", argv[1]); + + arg_end = NULL; + count = strtoul(argv[2], &arg_end, 0); + if (!arg_end || *arg_end || count == ULONG_MAX) + errx(1, "invalid count \"%s\"", argv[2]); + } else if (argc == 1) { + /* importantly chosen prime numbers. */ + seed = 8675309; + count = 2459; + } else { + errx(1, "USAGE: %s seed iter_count\n", argv[0]); + } + + random_test r{(uint_fast32_t)seed}; + r.test(count); + + printf("ok\n"); + return 0; +} diff --git a/lib/mesa/src/util/u_cpu_detect.c b/lib/mesa/src/util/u_cpu_detect.c new file mode 100644 index 000000000..4dbb4d8fb --- /dev/null +++ b/lib/mesa/src/util/u_cpu_detect.c @@ -0,0 +1,593 @@ +/************************************************************************** + * + * Copyright 2008 Dennis Smit + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * CPU feature detection. + * + * @author Dennis Smit + * @author Based on the work of Eric Anholt <anholt@FreeBSD.org> + */ + +#include "pipe/p_config.h" + +#include "util/u_debug.h" +#include "u_cpu_detect.h" +#include "c11/threads.h" + +#if defined(PIPE_ARCH_PPC) +#if defined(PIPE_OS_APPLE) +#include <sys/sysctl.h> +#else +#include <signal.h> +#include <setjmp.h> +#endif +#endif + +#if defined(PIPE_OS_NETBSD) || defined(PIPE_OS_OPENBSD) +#include <sys/param.h> +#include <sys/sysctl.h> +#include <machine/cpu.h> +#endif + +#if defined(PIPE_OS_FREEBSD) || defined(PIPE_OS_DRAGONFLY) +#include <sys/types.h> +#include <sys/sysctl.h> +#endif + +#if defined(PIPE_OS_LINUX) +#include <signal.h> +#include <fcntl.h> +#include <elf.h> +#endif + +#ifdef PIPE_OS_UNIX +#include <unistd.h> +#endif + +#if defined(HAS_ANDROID_CPUFEATURES) +#include <cpu-features.h> +#endif + +#if defined(PIPE_OS_WINDOWS) +#include <windows.h> +#if defined(PIPE_CC_MSVC) +#include <intrin.h> +#endif +#endif + + +#ifdef DEBUG +DEBUG_GET_ONCE_BOOL_OPTION(dump_cpu, "GALLIUM_DUMP_CPU", FALSE) +#endif + + +struct util_cpu_caps util_cpu_caps; + +#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) +static int has_cpuid(void); +#endif + + +#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_APPLE) +static jmp_buf __lv_powerpc_jmpbuf; +static volatile sig_atomic_t __lv_powerpc_canjump = 0; + +static void +sigill_handler(int sig) +{ + if (!__lv_powerpc_canjump) { + signal (sig, SIG_DFL); + raise (sig); + } + + __lv_powerpc_canjump = 0; + longjmp(__lv_powerpc_jmpbuf, 1); +} +#endif + +#if defined(PIPE_ARCH_PPC) +static void +check_os_altivec_support(void) +{ +#if defined(PIPE_OS_APPLE) + int sels[2] = {CTL_HW, HW_VECTORUNIT}; + int has_vu = 0; + int len = sizeof (has_vu); + int err; + + err = sysctl(sels, 2, &has_vu, &len, NULL, 0); + + if (err == 0) { + if (has_vu != 0) { + util_cpu_caps.has_altivec = 1; + } + } +#else /* !PIPE_OS_APPLE */ + /* not on Apple/Darwin, do it the brute-force way */ + /* this is borrowed from the libmpeg2 library */ + signal(SIGILL, sigill_handler); + if (setjmp(__lv_powerpc_jmpbuf)) { + signal(SIGILL, SIG_DFL); + } else { + boolean enable_altivec = TRUE; /* Default: enable if available, and if not overridden */ + boolean enable_vsx = TRUE; +#ifdef DEBUG + /* Disabling Altivec code generation is not the same as disabling VSX code generation, + * which can be done simply by passing -mattr=-vsx to the LLVM compiler; cf. + * lp_build_create_jit_compiler_for_module(). + * If you want to disable Altivec code generation, the best place to do it is here. + */ + char *env_control = getenv("GALLIVM_ALTIVEC"); /* 1=enable (default); 0=disable */ + if (env_control && env_control[0] == '0') { + enable_altivec = FALSE; + } +#endif + /* VSX instructions can be explicitly enabled/disabled via GALLIVM_VSX=1 or 0 */ + char *env_vsx = getenv("GALLIVM_VSX"); + if (env_vsx && env_vsx[0] == '0') { + enable_vsx = FALSE; + } + if (enable_altivec) { + __lv_powerpc_canjump = 1; + + __asm __volatile + ("mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" + : + : "r" (-1)); + + util_cpu_caps.has_altivec = 1; + + if (enable_vsx) { + __asm __volatile("xxland %vs0, %vs0, %vs0"); + util_cpu_caps.has_vsx = 1; + } + signal(SIGILL, SIG_DFL); + } else { + util_cpu_caps.has_altivec = 0; + } + } +#endif /* !PIPE_OS_APPLE */ +} +#endif /* PIPE_ARCH_PPC */ + + +#if defined(PIPE_ARCH_X86) || defined (PIPE_ARCH_X86_64) +static int has_cpuid(void) +{ +#if defined(PIPE_ARCH_X86) +#if defined(PIPE_OS_GCC) + int a, c; + + __asm __volatile + ("pushf\n" + "popl %0\n" + "movl %0, %1\n" + "xorl $0x200000, %0\n" + "push %0\n" + "popf\n" + "pushf\n" + "popl %0\n" + : "=a" (a), "=c" (c) + : + : "cc"); + + return a != c; +#else + /* FIXME */ + return 1; +#endif +#elif defined(PIPE_ARCH_X86_64) + return 1; +#else + return 0; +#endif +} + + +/** + * @sa cpuid.h included in gcc-4.3 onwards. + * @sa http://msdn.microsoft.com/en-us/library/hskdteyh.aspx + */ +static inline void +cpuid(uint32_t ax, uint32_t *p) +{ +#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) + __asm __volatile ( + "xchgl %%ebx, %1\n\t" + "cpuid\n\t" + "xchgl %%ebx, %1" + : "=a" (p[0]), + "=S" (p[1]), + "=c" (p[2]), + "=d" (p[3]) + : "0" (ax) + ); +#elif defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86_64) + __asm __volatile ( + "cpuid\n\t" + : "=a" (p[0]), + "=b" (p[1]), + "=c" (p[2]), + "=d" (p[3]) + : "0" (ax) + ); +#elif defined(PIPE_CC_MSVC) + __cpuid(p, ax); +#else + p[0] = 0; + p[1] = 0; + p[2] = 0; + p[3] = 0; +#endif +} + +/** + * @sa cpuid.h included in gcc-4.4 onwards. + * @sa http://msdn.microsoft.com/en-us/library/hskdteyh%28v=vs.90%29.aspx + */ +static inline void +cpuid_count(uint32_t ax, uint32_t cx, uint32_t *p) +{ +#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) + __asm __volatile ( + "xchgl %%ebx, %1\n\t" + "cpuid\n\t" + "xchgl %%ebx, %1" + : "=a" (p[0]), + "=S" (p[1]), + "=c" (p[2]), + "=d" (p[3]) + : "0" (ax), "2" (cx) + ); +#elif defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86_64) + __asm __volatile ( + "cpuid\n\t" + : "=a" (p[0]), + "=b" (p[1]), + "=c" (p[2]), + "=d" (p[3]) + : "0" (ax), "2" (cx) + ); +#elif defined(PIPE_CC_MSVC) + __cpuidex(p, ax, cx); +#else + p[0] = 0; + p[1] = 0; + p[2] = 0; + p[3] = 0; +#endif +} + + +static inline uint64_t xgetbv(void) +{ +#if defined(PIPE_CC_GCC) + uint32_t eax, edx; + + __asm __volatile ( + ".byte 0x0f, 0x01, 0xd0" // xgetbv isn't supported on gcc < 4.4 + : "=a"(eax), + "=d"(edx) + : "c"(0) + ); + + return ((uint64_t)edx << 32) | eax; +#elif defined(PIPE_CC_MSVC) && defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) + return _xgetbv(_XCR_XFEATURE_ENABLED_MASK); +#else + return 0; +#endif +} + + +#if defined(PIPE_ARCH_X86) +PIPE_ALIGN_STACK static inline boolean sse2_has_daz(void) +{ + struct { + uint32_t pad1[7]; + uint32_t mxcsr_mask; + uint32_t pad2[128-8]; + } PIPE_ALIGN_VAR(16) fxarea; + + fxarea.mxcsr_mask = 0; +#if defined(PIPE_CC_GCC) + __asm __volatile ("fxsave %0" : "+m" (fxarea)); +#elif defined(PIPE_CC_MSVC) || defined(PIPE_CC_ICL) + _fxsave(&fxarea); +#else + fxarea.mxcsr_mask = 0; +#endif + return !!(fxarea.mxcsr_mask & (1 << 6)); +} +#endif + +#endif /* X86 or X86_64 */ + +#if defined(PIPE_ARCH_ARM) +static void +check_os_arm_support(void) +{ + /* + * On Android, the cpufeatures library is preferred way of checking + * CPU capabilities. However, it is not available for standalone Mesa + * builds, i.e. when Android build system (Android.mk-based) is not + * used. Because of this we cannot use PIPE_OS_ANDROID here, but rather + * have a separate macro that only gets enabled from respective Android.mk. + */ +#if defined(HAS_ANDROID_CPUFEATURES) + AndroidCpuFamily cpu_family = android_getCpuFamily(); + uint64_t cpu_features = android_getCpuFeatures(); + + if (cpu_family == ANDROID_CPU_FAMILY_ARM) { + if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) + util_cpu_caps.has_neon = 1; + } +#elif defined(PIPE_OS_LINUX) + Elf32_auxv_t aux; + int fd; + + fd = open("/proc/self/auxv", O_RDONLY | O_CLOEXEC); + if (fd >= 0) { + while (read(fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) { + if (aux.a_type == AT_HWCAP) { + uint32_t hwcap = aux.a_un.a_val; + + util_cpu_caps.has_neon = (hwcap >> 12) & 1; + break; + } + } + close (fd); + } +#endif /* PIPE_OS_LINUX */ +} +#endif /* PIPE_ARCH_ARM */ + +static void +get_cpu_topology(void) +{ + uint32_t regs[4]; + + /* Default. This is correct if L3 is not present or there is only one. */ + util_cpu_caps.cores_per_L3 = util_cpu_caps.nr_cpus; + +#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) + /* AMD Zen */ + if (util_cpu_caps.x86_cpu_type == 0x17) { + /* Query the L3 cache topology information. */ + cpuid_count(0x8000001D, 3, regs); + unsigned cache_level = (regs[0] >> 5) & 0x7; + unsigned cores_per_cache = ((regs[0] >> 14) & 0xfff) + 1; + + if (cache_level == 3) + util_cpu_caps.cores_per_L3 = cores_per_cache; + } +#endif +} + +static void +util_cpu_detect_once(void) +{ + memset(&util_cpu_caps, 0, sizeof util_cpu_caps); + + /* Count the number of CPUs in system */ +#if defined(PIPE_OS_WINDOWS) + { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + util_cpu_caps.nr_cpus = system_info.dwNumberOfProcessors; + } +#elif defined(PIPE_OS_UNIX) && defined(_SC_NPROCESSORS_ONLN) + util_cpu_caps.nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + if (util_cpu_caps.nr_cpus == ~0) + util_cpu_caps.nr_cpus = 1; +#elif defined(PIPE_OS_BSD) + { + int mib[2], ncpu; + int len; + + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + + len = sizeof (ncpu); + sysctl(mib, 2, &ncpu, &len, NULL, 0); + util_cpu_caps.nr_cpus = ncpu; + } +#else + util_cpu_caps.nr_cpus = 1; +#endif + + /* Make the fallback cacheline size nonzero so that it can be + * safely passed to align(). + */ + util_cpu_caps.cacheline = sizeof(void *); + +#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) + if (has_cpuid()) { + uint32_t regs[4]; + uint32_t regs2[4]; + + util_cpu_caps.cacheline = 32; + + /* Get max cpuid level */ + cpuid(0x00000000, regs); + + if (regs[0] >= 0x00000001) { + unsigned int cacheline; + + cpuid (0x00000001, regs2); + + util_cpu_caps.x86_cpu_type = (regs2[0] >> 8) & 0xf; + /* Add "extended family". */ + if (util_cpu_caps.x86_cpu_type == 0xf) + util_cpu_caps.x86_cpu_type += ((regs2[0] >> 20) & 0xff); + + /* general feature flags */ + util_cpu_caps.has_tsc = (regs2[3] >> 4) & 1; /* 0x0000010 */ + util_cpu_caps.has_mmx = (regs2[3] >> 23) & 1; /* 0x0800000 */ + util_cpu_caps.has_sse = (regs2[3] >> 25) & 1; /* 0x2000000 */ + util_cpu_caps.has_sse2 = (regs2[3] >> 26) & 1; /* 0x4000000 */ + util_cpu_caps.has_sse3 = (regs2[2] >> 0) & 1; /* 0x0000001 */ + util_cpu_caps.has_ssse3 = (regs2[2] >> 9) & 1; /* 0x0000020 */ + util_cpu_caps.has_sse4_1 = (regs2[2] >> 19) & 1; + util_cpu_caps.has_sse4_2 = (regs2[2] >> 20) & 1; + util_cpu_caps.has_popcnt = (regs2[2] >> 23) & 1; + util_cpu_caps.has_avx = ((regs2[2] >> 28) & 1) && // AVX + ((regs2[2] >> 27) & 1) && // OSXSAVE + ((xgetbv() & 6) == 6); // XMM & YMM + util_cpu_caps.has_f16c = ((regs2[2] >> 29) & 1) && util_cpu_caps.has_avx; + util_cpu_caps.has_fma = ((regs2[2] >> 12) & 1) && util_cpu_caps.has_avx; + util_cpu_caps.has_mmx2 = util_cpu_caps.has_sse; /* SSE cpus supports mmxext too */ +#if defined(PIPE_ARCH_X86_64) + util_cpu_caps.has_daz = 1; +#else + util_cpu_caps.has_daz = util_cpu_caps.has_sse3 || + (util_cpu_caps.has_sse2 && sse2_has_daz()); +#endif + + cacheline = ((regs2[1] >> 8) & 0xFF) * 8; + if (cacheline > 0) + util_cpu_caps.cacheline = cacheline; + } + if (util_cpu_caps.has_avx && regs[0] >= 0x00000007) { + uint32_t regs7[4]; + cpuid_count(0x00000007, 0x00000000, regs7); + util_cpu_caps.has_avx2 = (regs7[1] >> 5) & 1; + } + + // check for avx512 + if (((regs2[2] >> 27) & 1) && // OSXSAVE + (xgetbv() & (0x7 << 5)) && // OPMASK: upper-256 enabled by OS + ((xgetbv() & 6) == 6)) { // XMM/YMM enabled by OS + uint32_t regs3[4]; + cpuid_count(0x00000007, 0x00000000, regs3); + util_cpu_caps.has_avx512f = (regs3[1] >> 16) & 1; + util_cpu_caps.has_avx512dq = (regs3[1] >> 17) & 1; + util_cpu_caps.has_avx512ifma = (regs3[1] >> 21) & 1; + util_cpu_caps.has_avx512pf = (regs3[1] >> 26) & 1; + util_cpu_caps.has_avx512er = (regs3[1] >> 27) & 1; + util_cpu_caps.has_avx512cd = (regs3[1] >> 28) & 1; + util_cpu_caps.has_avx512bw = (regs3[1] >> 30) & 1; + util_cpu_caps.has_avx512vl = (regs3[1] >> 31) & 1; + util_cpu_caps.has_avx512vbmi = (regs3[2] >> 1) & 1; + } + + if (regs[1] == 0x756e6547 && regs[2] == 0x6c65746e && regs[3] == 0x49656e69) { + /* GenuineIntel */ + util_cpu_caps.has_intel = 1; + } + + cpuid(0x80000000, regs); + + if (regs[0] >= 0x80000001) { + + cpuid(0x80000001, regs2); + + util_cpu_caps.has_mmx |= (regs2[3] >> 23) & 1; + util_cpu_caps.has_mmx2 |= (regs2[3] >> 22) & 1; + util_cpu_caps.has_3dnow = (regs2[3] >> 31) & 1; + util_cpu_caps.has_3dnow_ext = (regs2[3] >> 30) & 1; + + util_cpu_caps.has_xop = util_cpu_caps.has_avx && + ((regs2[2] >> 11) & 1); + } + + if (regs[0] >= 0x80000006) { + /* should we really do this if the clflush size above worked? */ + unsigned int cacheline; + cpuid(0x80000006, regs2); + cacheline = regs2[2] & 0xFF; + if (cacheline > 0) + util_cpu_caps.cacheline = cacheline; + } + + if (!util_cpu_caps.has_sse) { + util_cpu_caps.has_sse2 = 0; + util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_ssse3 = 0; + util_cpu_caps.has_sse4_1 = 0; + } + } +#endif /* PIPE_ARCH_X86 || PIPE_ARCH_X86_64 */ + +#if defined(PIPE_ARCH_ARM) + check_os_arm_support(); +#endif + +#if defined(PIPE_ARCH_PPC) + check_os_altivec_support(); +#endif /* PIPE_ARCH_PPC */ + + get_cpu_topology(); + +#ifdef DEBUG + if (debug_get_option_dump_cpu()) { + debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus); + + debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type); + debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline); + + debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc); + debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx); + debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2); + debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse); + debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2); + debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3); + debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3); + debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1); + debug_printf("util_cpu_caps.has_sse4_2 = %u\n", util_cpu_caps.has_sse4_2); + debug_printf("util_cpu_caps.has_avx = %u\n", util_cpu_caps.has_avx); + debug_printf("util_cpu_caps.has_avx2 = %u\n", util_cpu_caps.has_avx2); + debug_printf("util_cpu_caps.has_f16c = %u\n", util_cpu_caps.has_f16c); + debug_printf("util_cpu_caps.has_popcnt = %u\n", util_cpu_caps.has_popcnt); + debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow); + debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext); + debug_printf("util_cpu_caps.has_xop = %u\n", util_cpu_caps.has_xop); + debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); + debug_printf("util_cpu_caps.has_vsx = %u\n", util_cpu_caps.has_vsx); + debug_printf("util_cpu_caps.has_neon = %u\n", util_cpu_caps.has_neon); + debug_printf("util_cpu_caps.has_daz = %u\n", util_cpu_caps.has_daz); + debug_printf("util_cpu_caps.has_avx512f = %u\n", util_cpu_caps.has_avx512f); + debug_printf("util_cpu_caps.has_avx512dq = %u\n", util_cpu_caps.has_avx512dq); + debug_printf("util_cpu_caps.has_avx512ifma = %u\n", util_cpu_caps.has_avx512ifma); + debug_printf("util_cpu_caps.has_avx512pf = %u\n", util_cpu_caps.has_avx512pf); + debug_printf("util_cpu_caps.has_avx512er = %u\n", util_cpu_caps.has_avx512er); + debug_printf("util_cpu_caps.has_avx512cd = %u\n", util_cpu_caps.has_avx512cd); + debug_printf("util_cpu_caps.has_avx512bw = %u\n", util_cpu_caps.has_avx512bw); + debug_printf("util_cpu_caps.has_avx512vl = %u\n", util_cpu_caps.has_avx512vl); + debug_printf("util_cpu_caps.has_avx512vbmi = %u\n", util_cpu_caps.has_avx512vbmi); + } +#endif +} + +static once_flag cpu_once_flag = ONCE_FLAG_INIT; + +void +util_cpu_detect(void) +{ + call_once(&cpu_once_flag, util_cpu_detect_once); +} diff --git a/lib/mesa/src/util/u_cpu_detect.h b/lib/mesa/src/util/u_cpu_detect.h new file mode 100644 index 000000000..efc910d14 --- /dev/null +++ b/lib/mesa/src/util/u_cpu_detect.h @@ -0,0 +1,101 @@ +/************************************************************************** + * + * Copyright 2008 Dennis Smit + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + ***************************************************************************/ + +/** + * @file + * CPU feature detection. + * + * @author Dennis Smit + * @author Based on the work of Eric Anholt <anholt@FreeBSD.org> + */ + +#ifndef _UTIL_CPU_DETECT_H +#define _UTIL_CPU_DETECT_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_config.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct util_cpu_caps { + int nr_cpus; + + /* Feature flags */ + int x86_cpu_type; + unsigned cacheline; + unsigned cores_per_L3; + + unsigned has_intel:1; + unsigned has_tsc:1; + unsigned has_mmx:1; + unsigned has_mmx2:1; + unsigned has_sse:1; + unsigned has_sse2:1; + unsigned has_sse3:1; + unsigned has_ssse3:1; + unsigned has_sse4_1:1; + unsigned has_sse4_2:1; + unsigned has_popcnt:1; + unsigned has_avx:1; + unsigned has_avx2:1; + unsigned has_f16c:1; + unsigned has_fma:1; + unsigned has_3dnow:1; + unsigned has_3dnow_ext:1; + unsigned has_xop:1; + unsigned has_altivec:1; + unsigned has_vsx:1; + unsigned has_daz:1; + unsigned has_neon:1; + + unsigned has_avx512f:1; + unsigned has_avx512dq:1; + unsigned has_avx512ifma:1; + unsigned has_avx512pf:1; + unsigned has_avx512er:1; + unsigned has_avx512cd:1; + unsigned has_avx512bw:1; + unsigned has_avx512vl:1; + unsigned has_avx512vbmi:1; +}; + +extern struct util_cpu_caps +util_cpu_caps; + +void util_cpu_detect(void); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _UTIL_CPU_DETECT_H */ diff --git a/lib/mesa/src/util/u_debug.c b/lib/mesa/src/util/u_debug.c new file mode 100644 index 000000000..f6ed0138c --- /dev/null +++ b/lib/mesa/src/util/u_debug.c @@ -0,0 +1,441 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * Copyright (c) 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_config.h" + +#include "pipe/p_compiler.h" +#include "util/u_debug.h" +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "util/u_string.h" +#include "util/u_math.h" +#include <inttypes.h> + +#include <stdio.h> +#include <limits.h> /* CHAR_BIT */ +#include <ctype.h> /* isalnum */ + +#ifdef _WIN32 +#include <windows.h> +#include <stdlib.h> +#endif + + +void +_debug_vprintf(const char *format, va_list ap) +{ + static char buf[4096] = {'\0'}; +#if defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_EMBEDDED) + /* We buffer until we find a newline. */ + size_t len = strlen(buf); + int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); + if (ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { + os_log_message(buf); + buf[0] = '\0'; + } +#else + util_vsnprintf(buf, sizeof(buf), format, ap); + os_log_message(buf); +#endif +} + + +void +_pipe_debug_message(struct pipe_debug_callback *cb, + unsigned *id, + enum pipe_debug_type type, + const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + if (cb && cb->debug_message) + cb->debug_message(cb->data, id, type, fmt, args); + va_end(args); +} + + +void +debug_disable_error_message_boxes(void) +{ +#ifdef _WIN32 + /* When Windows' error message boxes are disabled for this process (as is + * typically the case when running tests in an automated fashion) we disable + * CRT message boxes too. + */ + UINT uMode = SetErrorMode(0); + SetErrorMode(uMode); + if (uMode & SEM_FAILCRITICALERRORS) { + /* Disable assertion failure message box. + * http://msdn.microsoft.com/en-us/library/sas1dkb2.aspx + */ + _set_error_mode(_OUT_TO_STDERR); +#ifdef _MSC_VER + /* Disable abort message box. + * http://msdn.microsoft.com/en-us/library/e631wekh.aspx + */ + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +#endif + } +#endif /* _WIN32 */ +} + + +#ifdef DEBUG +void +debug_print_blob(const char *name, const void *blob, unsigned size) +{ + const unsigned *ublob = (const unsigned *)blob; + unsigned i; + + debug_printf("%s (%d dwords%s)\n", name, size/4, + size%4 ? "... plus a few bytes" : ""); + + for (i = 0; i < size/4; i++) { + debug_printf("%d:\t%08x\n", i, ublob[i]); + } +} +#endif + + +static boolean +debug_get_option_should_print(void) +{ + static boolean first = TRUE; + static boolean value = FALSE; + + if (!first) + return value; + + /* Oh hey this will call into this function, + * but its cool since we set first to false + */ + first = FALSE; + value = debug_get_bool_option("GALLIUM_PRINT_OPTIONS", FALSE); + /* XXX should we print this option? Currently it wont */ + return value; +} + + +const char * +debug_get_option(const char *name, const char *dfault) +{ + const char *result; + + result = os_get_option(name); + if (!result) + result = dfault; + + if (debug_get_option_should_print()) + debug_printf("%s: %s = %s\n", __FUNCTION__, name, + result ? result : "(null)"); + + return result; +} + + +boolean +debug_get_bool_option(const char *name, boolean dfault) +{ + const char *str = os_get_option(name); + boolean result; + + if (str == NULL) + result = dfault; + else if (!util_strcmp(str, "n")) + result = FALSE; + else if (!util_strcmp(str, "no")) + result = FALSE; + else if (!util_strcmp(str, "0")) + result = FALSE; + else if (!util_strcmp(str, "f")) + result = FALSE; + else if (!util_strcmp(str, "F")) + result = FALSE; + else if (!util_strcmp(str, "false")) + result = FALSE; + else if (!util_strcmp(str, "FALSE")) + result = FALSE; + else + result = TRUE; + + if (debug_get_option_should_print()) + debug_printf("%s: %s = %s\n", __FUNCTION__, name, + result ? "TRUE" : "FALSE"); + + return result; +} + + +long +debug_get_num_option(const char *name, long dfault) +{ + long result; + const char *str; + + str = os_get_option(name); + if (!str) { + result = dfault; + } else { + char *endptr; + + result = strtol(str, &endptr, 0); + if (str == endptr) { + /* Restore the default value when no digits were found. */ + result = dfault; + } + } + + if (debug_get_option_should_print()) + debug_printf("%s: %s = %li\n", __FUNCTION__, name, result); + + return result; +} + + +static boolean +str_has_option(const char *str, const char *name) +{ + /* Empty string. */ + if (!*str) { + return FALSE; + } + + /* OPTION=all */ + if (!util_strcmp(str, "all")) { + return TRUE; + } + + /* Find 'name' in 'str' surrounded by non-alphanumeric characters. */ + { + const char *start = str; + unsigned name_len = strlen(name); + + /* 'start' is the beginning of the currently-parsed word, + * we increment 'str' each iteration. + * if we find either the end of string or a non-alphanumeric character, + * we compare 'start' up to 'str-1' with 'name'. */ + + while (1) { + if (!*str || !(isalnum(*str) || *str == '_')) { + if (str-start == name_len && + !memcmp(start, name, name_len)) { + return TRUE; + } + + if (!*str) { + return FALSE; + } + + start = str+1; + } + + str++; + } + } + + return FALSE; +} + + +uint64_t +debug_get_flags_option(const char *name, + const struct debug_named_value *flags, + uint64_t dfault) +{ + uint64_t result; + const char *str; + const struct debug_named_value *orig = flags; + unsigned namealign = 0; + + str = os_get_option(name); + if (!str) + result = dfault; + else if (!util_strcmp(str, "help")) { + result = dfault; + _debug_printf("%s: help for %s:\n", __FUNCTION__, name); + for (; flags->name; ++flags) + namealign = MAX2(namealign, strlen(flags->name)); + for (flags = orig; flags->name; ++flags) + _debug_printf("| %*s [0x%0*"PRIx64"]%s%s\n", namealign, flags->name, + (int)sizeof(uint64_t)*CHAR_BIT/4, flags->value, + flags->desc ? " " : "", flags->desc ? flags->desc : ""); + } + else { + result = 0; + while (flags->name) { + if (str_has_option(str, flags->name)) + result |= flags->value; + ++flags; + } + } + + if (debug_get_option_should_print()) { + if (str) { + debug_printf("%s: %s = 0x%"PRIx64" (%s)\n", + __FUNCTION__, name, result, str); + } else { + debug_printf("%s: %s = 0x%"PRIx64"\n", __FUNCTION__, name, result); + } + } + + return result; +} + + +void +_debug_assert_fail(const char *expr, const char *file, unsigned line, + const char *function) +{ + _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", + file, line, function, expr); + os_abort(); +} + + +const char * +debug_dump_enum(const struct debug_named_value *names, + unsigned long value) +{ + static char rest[64]; + + while (names->name) { + if (names->value == value) + return names->name; + ++names; + } + + util_snprintf(rest, sizeof(rest), "0x%08lx", value); + return rest; +} + + +const char * +debug_dump_enum_noprefix(const struct debug_named_value *names, + const char *prefix, + unsigned long value) +{ + static char rest[64]; + + while (names->name) { + if (names->value == value) { + const char *name = names->name; + while (*name == *prefix) { + name++; + prefix++; + } + return name; + } + ++names; + } + + util_snprintf(rest, sizeof(rest), "0x%08lx", value); + return rest; +} + + +const char * +debug_dump_flags(const struct debug_named_value *names, unsigned long value) +{ + static char output[4096]; + static char rest[256]; + int first = 1; + + output[0] = '\0'; + + while (names->name) { + if ((names->value & value) == names->value) { + if (!first) + util_strncat(output, "|", sizeof(output) - strlen(output) - 1); + else + first = 0; + util_strncat(output, names->name, sizeof(output) - strlen(output) - 1); + output[sizeof(output) - 1] = '\0'; + value &= ~names->value; + } + ++names; + } + + if (value) { + if (!first) + util_strncat(output, "|", sizeof(output) - strlen(output) - 1); + else + first = 0; + + util_snprintf(rest, sizeof(rest), "0x%08lx", value); + util_strncat(output, rest, sizeof(output) - strlen(output) - 1); + output[sizeof(output) - 1] = '\0'; + } + + if (first) + return "0"; + + return output; +} + + + +#ifdef DEBUG +int fl_indent = 0; +const char* fl_function[1024]; + +int +debug_funclog_enter(const char* f, UNUSED const int line, + UNUSED const char* file) +{ + int i; + + for (i = 0; i < fl_indent; i++) + debug_printf(" "); + debug_printf("%s\n", f); + + assert(fl_indent < 1023); + fl_function[fl_indent++] = f; + + return 0; +} + +void +debug_funclog_exit(const char* f, UNUSED const int line, + UNUSED const char* file) +{ + --fl_indent; + assert(fl_indent >= 0); + assert(fl_function[fl_indent] == f); +} + +void +debug_funclog_enter_exit(const char* f, UNUSED const int line, + UNUSED const char* file) +{ + int i; + for (i = 0; i < fl_indent; i++) + debug_printf(" "); + debug_printf("%s\n", f); +} +#endif diff --git a/lib/mesa/src/util/u_debug.h b/lib/mesa/src/util/u_debug.h new file mode 100644 index 000000000..b3505caeb --- /dev/null +++ b/lib/mesa/src/util/u_debug.h @@ -0,0 +1,460 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Cross-platform debugging helpers. + * + * For now it just has assert and printf replacements, but it might be extended + * with stack trace reports and more advanced logging in the near future. + * + * @author Jose Fonseca <jfonseca@vmware.com> + */ + +#ifndef U_DEBUG_H_ +#define U_DEBUG_H_ + + +#include "util/os_misc.h" + +#if defined(PIPE_OS_HAIKU) +/* Haiku provides debug_printf in libroot with OS.h */ +#include <OS.h> +#endif + +#include "pipe/p_defines.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined(__GNUC__) +#define _util_printf_format(fmt, list) __attribute__ ((format (printf, fmt, list))) +#else +#define _util_printf_format(fmt, list) +#endif + +void _debug_vprintf(const char *format, va_list ap); + + +static inline void +_debug_printf(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + _debug_vprintf(format, ap); + va_end(ap); +} + + +/** + * Print debug messages. + * + * The actual channel used to output debug message is platform specific. To + * avoid misformating or truncation, follow these rules of thumb: + * - output whole lines + * - avoid outputing large strings (512 bytes is the current maximum length + * that is guaranteed to be printed in all platforms) + */ +#if !defined(PIPE_OS_HAIKU) +static inline void +debug_printf(const char *format, ...) _util_printf_format(1,2); + +static inline void +debug_printf(const char *format, ...) +{ +#ifdef DEBUG + va_list ap; + va_start(ap, format); + _debug_vprintf(format, ap); + va_end(ap); +#else + (void) format; /* silence warning */ +#endif +} +#endif + + +/* + * ... isn't portable so we need to pass arguments in parentheses. + * + * usage: + * debug_printf_once(("answer: %i\n", 42)); + */ +#define debug_printf_once(args) \ + do { \ + static boolean once = TRUE; \ + if (once) { \ + once = FALSE; \ + debug_printf args; \ + } \ + } while (0) + + +#ifdef DEBUG +#define debug_vprintf(_format, _ap) _debug_vprintf(_format, _ap) +#else +#define debug_vprintf(_format, _ap) ((void)0) +#endif + + +#ifdef DEBUG +/** + * Dump a blob in hex to the same place that debug_printf sends its + * messages. + */ +void debug_print_blob( const char *name, const void *blob, unsigned size ); +#else +#define debug_print_blob(_name, _blob, _size) ((void)0) +#endif + + +/** + * Disable interactive error message boxes. + * + * Should be called as soon as possible for effectiveness. + */ +void +debug_disable_error_message_boxes(void); + + +/** + * Hard-coded breakpoint. + */ +#ifdef DEBUG +#define debug_break() os_break() +#else /* !DEBUG */ +#define debug_break() ((void)0) +#endif /* !DEBUG */ + + +long +debug_get_num_option(const char *name, long dfault); + +#ifdef _MSC_VER +__declspec(noreturn) +#endif +void _debug_assert_fail(const char *expr, + const char *file, + unsigned line, + const char *function) +#if defined(__GNUC__) && !defined(DEBUG) + __attribute__((noreturn)) +#endif +; + + +/** + * Assert macro + * + * Do not expect that the assert call terminates -- errors must be handled + * regardless of assert behavior. + * + * For non debug builds the assert macro will expand to a no-op, so do not + * call functions with side effects in the assert expression. + */ +#ifndef NDEBUG +#define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__)) +#else +#define debug_assert(expr) (void)(0 && (expr)) +#endif + + +/** Override standard assert macro */ +#ifdef assert +#undef assert +#endif +#define assert(expr) debug_assert(expr) + + +/** + * Output the current function name. + */ +#ifdef DEBUG +#define debug_checkpoint() \ + _debug_printf("%s\n", __FUNCTION__) +#else +#define debug_checkpoint() \ + ((void)0) +#endif + + +/** + * Output the full source code position. + */ +#ifdef DEBUG +#define debug_checkpoint_full() \ + _debug_printf("%s:%u:%s\n", __FILE__, __LINE__, __FUNCTION__) +#else +#define debug_checkpoint_full() \ + ((void)0) +#endif + + +/** + * Output a warning message. Muted on release version. + */ +#ifdef DEBUG +#define debug_warning(__msg) \ + _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) +#else +#define debug_warning(__msg) \ + ((void)0) +#endif + + +/** + * Emit a warning message, but only once. + */ +#ifdef DEBUG +#define debug_warn_once(__msg) \ + do { \ + static bool warned = FALSE; \ + if (!warned) { \ + _debug_printf("%s:%u:%s: one time warning: %s\n", \ + __FILE__, __LINE__, __FUNCTION__, __msg); \ + warned = TRUE; \ + } \ + } while (0) +#else +#define debug_warn_once(__msg) \ + ((void)0) +#endif + + +/** + * Output an error message. Not muted on release version. + */ +#ifdef DEBUG +#define debug_error(__msg) \ + _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) +#else +#define debug_error(__msg) \ + _debug_printf("error: %s\n", __msg) +#endif + +/** + * Output a debug log message to the debug info callback. + */ +#define pipe_debug_message(cb, type, fmt, ...) do { \ + static unsigned id = 0; \ + if ((cb) && (cb)->debug_message) { \ + _pipe_debug_message(cb, &id, \ + PIPE_DEBUG_TYPE_ ## type, \ + fmt, ##__VA_ARGS__); \ + } \ +} while (0) + +struct pipe_debug_callback; + +void +_pipe_debug_message( + struct pipe_debug_callback *cb, + unsigned *id, + enum pipe_debug_type type, + const char *fmt, ...) _util_printf_format(4, 5); + + +/** + * Used by debug_dump_enum and debug_dump_flags to describe symbols. + */ +struct debug_named_value +{ + const char *name; + uint64_t value; + const char *desc; +}; + + +/** + * Some C pre-processor magic to simplify creating named values. + * + * Example: + * @code + * static const debug_named_value my_names[] = { + * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X), + * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y), + * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z), + * DEBUG_NAMED_VALUE_END + * }; + * + * ... + * debug_printf("%s = %s\n", + * name, + * debug_dump_enum(my_names, my_value)); + * ... + * @endcode + */ +#define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol, NULL} +#define DEBUG_NAMED_VALUE_WITH_DESCRIPTION(__symbol, __desc) {#__symbol, (unsigned long)__symbol, __desc} +#define DEBUG_NAMED_VALUE_END {NULL, 0, NULL} + + +/** + * Convert a enum value to a string. + */ +const char * +debug_dump_enum(const struct debug_named_value *names, + unsigned long value); + +const char * +debug_dump_enum_noprefix(const struct debug_named_value *names, + const char *prefix, + unsigned long value); + + +/** + * Convert binary flags value to a string. + */ +const char * +debug_dump_flags(const struct debug_named_value *names, + unsigned long value); + + +/** + * Function enter exit loggers + */ +#ifdef DEBUG +int debug_funclog_enter(const char* f, const int line, const char* file); +void debug_funclog_exit(const char* f, const int line, const char* file); +void debug_funclog_enter_exit(const char* f, const int line, const char* file); + +#define DEBUG_FUNCLOG_ENTER() \ + int __debug_decleration_work_around = \ + debug_funclog_enter(__FUNCTION__, __LINE__, __FILE__) +#define DEBUG_FUNCLOG_EXIT() \ + do { \ + (void)__debug_decleration_work_around; \ + debug_funclog_exit(__FUNCTION__, __LINE__, __FILE__); \ + return; \ + } while(0) +#define DEBUG_FUNCLOG_EXIT_RET(ret) \ + do { \ + (void)__debug_decleration_work_around; \ + debug_funclog_exit(__FUNCTION__, __LINE__, __FILE__); \ + return ret; \ + } while(0) +#define DEBUG_FUNCLOG_ENTER_EXIT() \ + debug_funclog_enter_exit(__FUNCTION__, __LINE__, __FILE__) + +#else +#define DEBUG_FUNCLOG_ENTER() \ + int __debug_decleration_work_around +#define DEBUG_FUNCLOG_EXIT() \ + do { (void)__debug_decleration_work_around; return; } while(0) +#define DEBUG_FUNCLOG_EXIT_RET(ret) \ + do { (void)__debug_decleration_work_around; return ret; } while(0) +#define DEBUG_FUNCLOG_ENTER_EXIT() +#endif + + +/** + * Get option. + * + * It is an alias for getenv on Linux. + * + * On Windows it reads C:\gallium.cfg, which is a text file with CR+LF line + * endings with one option per line as + * + * NAME=value + * + * This file must be terminated with an extra empty line. + */ +const char * +debug_get_option(const char *name, const char *dfault); + +boolean +debug_get_bool_option(const char *name, boolean dfault); + +long +debug_get_num_option(const char *name, long dfault); + +uint64_t +debug_get_flags_option(const char *name, + const struct debug_named_value *flags, + uint64_t dfault); + +#define DEBUG_GET_ONCE_OPTION(suffix, name, dfault) \ +static const char * \ +debug_get_option_ ## suffix (void) \ +{ \ + static boolean first = TRUE; \ + static const char * value; \ + if (first) { \ + first = FALSE; \ + value = debug_get_option(name, dfault); \ + } \ + return value; \ +} + +#define DEBUG_GET_ONCE_BOOL_OPTION(sufix, name, dfault) \ +static boolean \ +debug_get_option_ ## sufix (void) \ +{ \ + static boolean first = TRUE; \ + static boolean value; \ + if (first) { \ + first = FALSE; \ + value = debug_get_bool_option(name, dfault); \ + } \ + return value; \ +} + +#define DEBUG_GET_ONCE_NUM_OPTION(sufix, name, dfault) \ +static long \ +debug_get_option_ ## sufix (void) \ +{ \ + static boolean first = TRUE; \ + static long value; \ + if (first) { \ + first = FALSE; \ + value = debug_get_num_option(name, dfault); \ + } \ + return value; \ +} + +#define DEBUG_GET_ONCE_FLAGS_OPTION(sufix, name, flags, dfault) \ +static unsigned long \ +debug_get_option_ ## sufix (void) \ +{ \ + static boolean first = TRUE; \ + static unsigned long value; \ + if (first) { \ + first = FALSE; \ + value = debug_get_flags_option(name, flags, dfault); \ + } \ + return value; \ +} + + +#ifdef __cplusplus +} +#endif + +#endif /* U_DEBUG_H_ */ diff --git a/lib/mesa/src/util/u_math.c b/lib/mesa/src/util/u_math.c new file mode 100644 index 000000000..c58af911b --- /dev/null +++ b/lib/mesa/src/util/u_math.c @@ -0,0 +1,137 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + + +#include "pipe/p_config.h" +#include "util/u_math.h" +#include "util/u_cpu_detect.h" + +#if defined(PIPE_ARCH_SSE) +#include <xmmintrin.h> +/* This is defined in pmmintrin.h, but it can only be included when -msse3 is + * used, so just define it here to avoid further. */ +#define _MM_DENORMALS_ZERO_MASK 0x0040 +#endif + + +/** 2^x, for x in [-1.0, 1.0) */ +float pow2_table[POW2_TABLE_SIZE]; + + +static void +init_pow2_table(void) +{ + int i; + for (i = 0; i < POW2_TABLE_SIZE; i++) + pow2_table[i] = exp2f((i - POW2_TABLE_OFFSET) / POW2_TABLE_SCALE); +} + + +/** log2(x), for x in [1.0, 2.0) */ +float log2_table[LOG2_TABLE_SIZE]; + + +static void +init_log2_table(void) +{ + unsigned i; + for (i = 0; i < LOG2_TABLE_SIZE; i++) + log2_table[i] = (float) log2(1.0 + i * (1.0 / LOG2_TABLE_SCALE)); +} + + +/** + * One time init for math utilities. + */ +void +util_init_math(void) +{ + static boolean initialized = FALSE; + if (!initialized) { + init_pow2_table(); + init_log2_table(); + initialized = TRUE; + } +} + +/** + * Fetches the contents of the fpstate (mxcsr on x86) register. + * + * On platforms without support for it just returns 0. + */ +unsigned +util_fpstate_get(void) +{ + unsigned mxcsr = 0; + +#if defined(PIPE_ARCH_SSE) + if (util_cpu_caps.has_sse) { + mxcsr = _mm_getcsr(); + } +#endif + + return mxcsr; +} + +/** + * Make sure that the fp treats the denormalized floating + * point numbers as zero. + * + * This is the behavior required by D3D10. OpenGL doesn't care. + */ +unsigned +util_fpstate_set_denorms_to_zero(unsigned current_mxcsr) +{ +#if defined(PIPE_ARCH_SSE) + if (util_cpu_caps.has_sse) { + /* Enable flush to zero mode */ + current_mxcsr |= _MM_FLUSH_ZERO_MASK; + if (util_cpu_caps.has_daz) { + /* Enable denormals are zero mode */ + current_mxcsr |= _MM_DENORMALS_ZERO_MASK; + } + util_fpstate_set(current_mxcsr); + } +#endif + return current_mxcsr; +} + +/** + * Set the state of the fpstate (mxcsr on x86) register. + * + * On platforms without support for it's a noop. + */ +void +util_fpstate_set(unsigned mxcsr) +{ +#if defined(PIPE_ARCH_SSE) + if (util_cpu_caps.has_sse) { + _mm_setcsr(mxcsr); + } +#endif +} diff --git a/lib/mesa/src/util/u_math.h b/lib/mesa/src/util/u_math.h new file mode 100644 index 000000000..e7dbbe5ca --- /dev/null +++ b/lib/mesa/src/util/u_math.h @@ -0,0 +1,752 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Math utilities and approximations for common math functions. + * Reduced precision is usually acceptable in shaders... + * + * "fast" is used in the names of functions which are low-precision, + * or at least lower-precision than the normal C lib functions. + */ + + +#ifndef U_MATH_H +#define U_MATH_H + + +#include "pipe/p_compiler.h" + +#include "c99_math.h" +#include <assert.h> +#include <float.h> +#include <stdarg.h> + +#include "bitscan.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 +#endif + +#define POW2_TABLE_SIZE_LOG2 9 +#define POW2_TABLE_SIZE (1 << POW2_TABLE_SIZE_LOG2) +#define POW2_TABLE_OFFSET (POW2_TABLE_SIZE/2) +#define POW2_TABLE_SCALE ((float)(POW2_TABLE_SIZE/2)) +extern float pow2_table[POW2_TABLE_SIZE]; + + +/** + * Initialize math module. This should be called before using any + * other functions in this module. + */ +extern void +util_init_math(void); + + +union fi { + float f; + int32_t i; + uint32_t ui; +}; + + +union di { + double d; + int64_t i; + uint64_t ui; +}; + + +/** + * Extract the IEEE float32 exponent. + */ +static inline signed +util_get_float32_exponent(float x) +{ + union fi f; + + f.f = x; + + return ((f.ui >> 23) & 0xff) - 127; +} + + +/** + * Fast version of 2^x + * Identity: exp2(a + b) = exp2(a) * exp2(b) + * Let ipart = int(x) + * Let fpart = x - ipart; + * So, exp2(x) = exp2(ipart) * exp2(fpart) + * Compute exp2(ipart) with i << ipart + * Compute exp2(fpart) with lookup table. + */ +static inline float +util_fast_exp2(float x) +{ + int32_t ipart; + float fpart, mpart; + union fi epart; + + if(x > 129.00000f) + return 3.402823466e+38f; + + if (x < -126.99999f) + return 0.0f; + + ipart = (int32_t) x; + fpart = x - (float) ipart; + + /* same as + * epart.f = (float) (1 << ipart) + * but faster and without integer overflow for ipart > 31 + */ + epart.i = (ipart + 127 ) << 23; + + mpart = pow2_table[POW2_TABLE_OFFSET + (int)(fpart * POW2_TABLE_SCALE)]; + + return epart.f * mpart; +} + + +/** + * Fast approximation to exp(x). + */ +static inline float +util_fast_exp(float x) +{ + const float k = 1.44269f; /* = log2(e) */ + return util_fast_exp2(k * x); +} + + +#define LOG2_TABLE_SIZE_LOG2 16 +#define LOG2_TABLE_SCALE (1 << LOG2_TABLE_SIZE_LOG2) +#define LOG2_TABLE_SIZE (LOG2_TABLE_SCALE + 1) +extern float log2_table[LOG2_TABLE_SIZE]; + + +/** + * Fast approximation to log2(x). + */ +static inline float +util_fast_log2(float x) +{ + union fi num; + float epart, mpart; + num.f = x; + epart = (float)(((num.i & 0x7f800000) >> 23) - 127); + /* mpart = log2_table[mantissa*LOG2_TABLE_SCALE + 0.5] */ + mpart = log2_table[((num.i & 0x007fffff) + (1 << (22 - LOG2_TABLE_SIZE_LOG2))) >> (23 - LOG2_TABLE_SIZE_LOG2)]; + return epart + mpart; +} + + +/** + * Fast approximation to x^y. + */ +static inline float +util_fast_pow(float x, float y) +{ + return util_fast_exp2(util_fast_log2(x) * y); +} + + +/** + * Floor(x), returned as int. + */ +static inline int +util_ifloor(float f) +{ + int ai, bi; + double af, bf; + union fi u; + af = (3 << 22) + 0.5 + (double) f; + bf = (3 << 22) + 0.5 - (double) f; + u.f = (float) af; ai = u.i; + u.f = (float) bf; bi = u.i; + return (ai - bi) >> 1; +} + + +/** + * Round float to nearest int. + */ +static inline int +util_iround(float f) +{ +#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) + int r; + __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); + return r; +#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) + int r; + _asm { + fld f + fistp r + } + return r; +#else + if (f >= 0.0f) + return (int) (f + 0.5f); + else + return (int) (f - 0.5f); +#endif +} + + +/** + * Approximate floating point comparison + */ +static inline boolean +util_is_approx(float a, float b, float tol) +{ + return fabsf(b - a) <= tol; +} + + +/** + * util_is_X_inf_or_nan = test if x is NaN or +/- Inf + * util_is_X_nan = test if x is NaN + * util_X_inf_sign = return +1 for +Inf, -1 for -Inf, or 0 for not Inf + * + * NaN can be checked with x != x, however this fails with the fast math flag + **/ + + +/** + * Single-float + */ +static inline boolean +util_is_inf_or_nan(float x) +{ + union fi tmp; + tmp.f = x; + return (tmp.ui & 0x7f800000) == 0x7f800000; +} + + +static inline boolean +util_is_nan(float x) +{ + union fi tmp; + tmp.f = x; + return (tmp.ui & 0x7fffffff) > 0x7f800000; +} + + +static inline int +util_inf_sign(float x) +{ + union fi tmp; + tmp.f = x; + if ((tmp.ui & 0x7fffffff) != 0x7f800000) { + return 0; + } + + return (x < 0) ? -1 : 1; +} + + +/** + * Double-float + */ +static inline boolean +util_is_double_inf_or_nan(double x) +{ + union di tmp; + tmp.d = x; + return (tmp.ui & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL; +} + + +static inline boolean +util_is_double_nan(double x) +{ + union di tmp; + tmp.d = x; + return (tmp.ui & 0x7fffffffffffffffULL) > 0x7ff0000000000000ULL; +} + + +static inline int +util_double_inf_sign(double x) +{ + union di tmp; + tmp.d = x; + if ((tmp.ui & 0x7fffffffffffffffULL) != 0x7ff0000000000000ULL) { + return 0; + } + + return (x < 0) ? -1 : 1; +} + + +/** + * Half-float + */ +static inline boolean +util_is_half_inf_or_nan(int16_t x) +{ + return (x & 0x7c00) == 0x7c00; +} + + +static inline boolean +util_is_half_nan(int16_t x) +{ + return (x & 0x7fff) > 0x7c00; +} + + +static inline int +util_half_inf_sign(int16_t x) +{ + if ((x & 0x7fff) != 0x7c00) { + return 0; + } + + return (x < 0) ? -1 : 1; +} + + +/** + * Return float bits. + */ +static inline unsigned +fui( float f ) +{ + union fi fi; + fi.f = f; + return fi.ui; +} + +static inline float +uif(uint32_t ui) +{ + union fi fi; + fi.ui = ui; + return fi.f; +} + + +/** + * Convert ubyte to float in [0, 1]. + */ +static inline float +ubyte_to_float(ubyte ub) +{ + return (float) ub * (1.0f / 255.0f); +} + + +/** + * Convert float in [0,1] to ubyte in [0,255] with clamping. + */ +static inline ubyte +float_to_ubyte(float f) +{ + /* return 0 for NaN too */ + if (!(f > 0.0f)) { + return (ubyte) 0; + } + else if (f >= 1.0f) { + return (ubyte) 255; + } + else { + union fi tmp; + tmp.f = f; + tmp.f = tmp.f * (255.0f/256.0f) + 32768.0f; + return (ubyte) tmp.i; + } +} + +static inline float +byte_to_float_tex(int8_t b) +{ + return (b == -128) ? -1.0F : b * 1.0F / 127.0F; +} + +static inline int8_t +float_to_byte_tex(float f) +{ + return (int8_t) (127.0F * f); +} + +/** + * Calc log base 2 + */ +static inline unsigned +util_logbase2(unsigned n) +{ +#if defined(HAVE___BUILTIN_CLZ) + return ((sizeof(unsigned) * 8 - 1) - __builtin_clz(n | 1)); +#else + unsigned pos = 0; + if (n >= 1<<16) { n >>= 16; pos += 16; } + if (n >= 1<< 8) { n >>= 8; pos += 8; } + if (n >= 1<< 4) { n >>= 4; pos += 4; } + if (n >= 1<< 2) { n >>= 2; pos += 2; } + if (n >= 1<< 1) { pos += 1; } + return pos; +#endif +} + +static inline uint64_t +util_logbase2_64(uint64_t n) +{ +#if defined(HAVE___BUILTIN_CLZLL) + return ((sizeof(uint64_t) * 8 - 1) - __builtin_clzll(n | 1)); +#else + uint64_t pos = 0ull; + if (n >= 1ull<<32) { n >>= 32; pos += 32; } + if (n >= 1ull<<16) { n >>= 16; pos += 16; } + if (n >= 1ull<< 8) { n >>= 8; pos += 8; } + if (n >= 1ull<< 4) { n >>= 4; pos += 4; } + if (n >= 1ull<< 2) { n >>= 2; pos += 2; } + if (n >= 1ull<< 1) { pos += 1; } + return pos; +#endif +} + +/** + * Returns the ceiling of log n base 2, and 0 when n == 0. Equivalently, + * returns the smallest x such that n <= 2**x. + */ +static inline unsigned +util_logbase2_ceil(unsigned n) +{ + if (n <= 1) + return 0; + + return 1 + util_logbase2(n - 1); +} + +static inline uint64_t +util_logbase2_ceil64(uint64_t n) +{ + if (n <= 1) + return 0; + + return 1ull + util_logbase2_64(n - 1); +} + +/** + * Returns the smallest power of two >= x + */ +static inline unsigned +util_next_power_of_two(unsigned x) +{ +#if defined(HAVE___BUILTIN_CLZ) + if (x <= 1) + return 1; + + return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1))); +#else + unsigned val = x; + + if (x <= 1) + return 1; + + if (util_is_power_of_two_or_zero(x)) + return x; + + val--; + val = (val >> 1) | val; + val = (val >> 2) | val; + val = (val >> 4) | val; + val = (val >> 8) | val; + val = (val >> 16) | val; + val++; + return val; +#endif +} + +static inline uint64_t +util_next_power_of_two64(uint64_t x) +{ +#if defined(HAVE___BUILTIN_CLZLL) + if (x <= 1) + return 1; + + return (1ull << ((sizeof(uint64_t) * 8) - __builtin_clzll(x - 1))); +#else + uint64_t val = x; + + if (x <= 1) + return 1; + + if (util_is_power_of_two_or_zero64(x)) + return x; + + val--; + val = (val >> 1) | val; + val = (val >> 2) | val; + val = (val >> 4) | val; + val = (val >> 8) | val; + val = (val >> 16) | val; + val = (val >> 32) | val; + val++; + return val; +#endif +} + + +/** + * Return number of bits set in n. + */ +static inline unsigned +util_bitcount(unsigned n) +{ +#if defined(HAVE___BUILTIN_POPCOUNT) + return __builtin_popcount(n); +#else + /* K&R classic bitcount. + * + * For each iteration, clear the LSB from the bitfield. + * Requires only one iteration per set bit, instead of + * one iteration per bit less than highest set bit. + */ + unsigned bits; + for (bits = 0; n; bits++) { + n &= n - 1; + } + return bits; +#endif +} + + +static inline unsigned +util_bitcount64(uint64_t n) +{ +#ifdef HAVE___BUILTIN_POPCOUNTLL + return __builtin_popcountll(n); +#else + return util_bitcount(n) + util_bitcount(n >> 32); +#endif +} + + +/** + * Reverse bits in n + * Algorithm taken from: + * http://stackoverflow.com/questions/9144800/c-reverse-bits-in-unsigned-integer + */ +static inline unsigned +util_bitreverse(unsigned n) +{ + n = ((n >> 1) & 0x55555555u) | ((n & 0x55555555u) << 1); + n = ((n >> 2) & 0x33333333u) | ((n & 0x33333333u) << 2); + n = ((n >> 4) & 0x0f0f0f0fu) | ((n & 0x0f0f0f0fu) << 4); + n = ((n >> 8) & 0x00ff00ffu) | ((n & 0x00ff00ffu) << 8); + n = ((n >> 16) & 0xffffu) | ((n & 0xffffu) << 16); + return n; +} + +/** + * Convert from little endian to CPU byte order. + */ + +#ifdef PIPE_ARCH_BIG_ENDIAN +#define util_le64_to_cpu(x) util_bswap64(x) +#define util_le32_to_cpu(x) util_bswap32(x) +#define util_le16_to_cpu(x) util_bswap16(x) +#else +#define util_le64_to_cpu(x) (x) +#define util_le32_to_cpu(x) (x) +#define util_le16_to_cpu(x) (x) +#endif + +#define util_cpu_to_le64(x) util_le64_to_cpu(x) +#define util_cpu_to_le32(x) util_le32_to_cpu(x) +#define util_cpu_to_le16(x) util_le16_to_cpu(x) + +/** + * Reverse byte order of a 32 bit word. + */ +static inline uint32_t +util_bswap32(uint32_t n) +{ +#if defined(HAVE___BUILTIN_BSWAP32) + return __builtin_bswap32(n); +#else + return (n >> 24) | + ((n >> 8) & 0x0000ff00) | + ((n << 8) & 0x00ff0000) | + (n << 24); +#endif +} + +/** + * Reverse byte order of a 64bit word. + */ +static inline uint64_t +util_bswap64(uint64_t n) +{ +#if defined(HAVE___BUILTIN_BSWAP64) + return __builtin_bswap64(n); +#else + return ((uint64_t)util_bswap32((uint32_t)n) << 32) | + util_bswap32((n >> 32)); +#endif +} + + +/** + * Reverse byte order of a 16 bit word. + */ +static inline uint16_t +util_bswap16(uint16_t n) +{ + return (n >> 8) | + (n << 8); +} + +static inline void* +util_memcpy_cpu_to_le32(void * restrict dest, const void * restrict src, size_t n) +{ +#ifdef PIPE_ARCH_BIG_ENDIAN + size_t i, e; + assert(n % 4 == 0); + + for (i = 0, e = n / 4; i < e; i++) { + uint32_t * restrict d = (uint32_t* restrict)dest; + const uint32_t * restrict s = (const uint32_t* restrict)src; + d[i] = util_bswap32(s[i]); + } + return dest; +#else + return memcpy(dest, src, n); +#endif +} + +/** + * Clamp X to [MIN, MAX]. + * This is a macro to allow float, int, uint, etc. types. + * We arbitrarily turn NaN into MIN. + */ +#define CLAMP( X, MIN, MAX ) ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) : (MIN) ) + +#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) +#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) + +#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C)) +#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C)) + +#define MIN4( A, B, C, D ) ((A) < (B) ? MIN3(A, C, D) : MIN3(B, C, D)) +#define MAX4( A, B, C, D ) ((A) > (B) ? MAX3(A, C, D) : MAX3(B, C, D)) + + +/** + * Align a value, only works pot alignemnts. + */ +static inline int +align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + +static inline uint64_t +align64(uint64_t value, unsigned alignment) +{ + return (value + alignment - 1) & ~((uint64_t)alignment - 1); +} + +/** + * Works like align but on npot alignments. + */ +static inline size_t +util_align_npot(size_t value, size_t alignment) +{ + if (value % alignment) + return value + (alignment - (value % alignment)); + return value; +} + +static inline unsigned +u_minify(unsigned value, unsigned levels) +{ + return MAX2(1, value >> levels); +} + +#ifndef COPY_4V +#define COPY_4V( DST, SRC ) \ +do { \ + (DST)[0] = (SRC)[0]; \ + (DST)[1] = (SRC)[1]; \ + (DST)[2] = (SRC)[2]; \ + (DST)[3] = (SRC)[3]; \ +} while (0) +#endif + + +#ifndef COPY_4FV +#define COPY_4FV( DST, SRC ) COPY_4V(DST, SRC) +#endif + + +#ifndef ASSIGN_4V +#define ASSIGN_4V( DST, V0, V1, V2, V3 ) \ +do { \ + (DST)[0] = (V0); \ + (DST)[1] = (V1); \ + (DST)[2] = (V2); \ + (DST)[3] = (V3); \ +} while (0) +#endif + + +static inline uint32_t +util_unsigned_fixed(float value, unsigned frac_bits) +{ + return value < 0 ? 0 : (uint32_t)(value * (1<<frac_bits)); +} + +static inline int32_t +util_signed_fixed(float value, unsigned frac_bits) +{ + return (int32_t)(value * (1<<frac_bits)); +} + +unsigned +util_fpstate_get(void); +unsigned +util_fpstate_set_denorms_to_zero(unsigned current_fpstate); +void +util_fpstate_set(unsigned fpstate); + + + +#ifdef __cplusplus +} +#endif + +#endif /* U_MATH_H */ diff --git a/lib/mesa/src/util/u_process.c b/lib/mesa/src/util/u_process.c new file mode 100644 index 000000000..5e5927678 --- /dev/null +++ b/lib/mesa/src/util/u_process.c @@ -0,0 +1,125 @@ +/* + * Copyright © 2003 Felix Kuehling + * Copyright © 2018 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS + * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ + +#include "u_process.h" +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +#undef GET_PROGRAM_NAME + +#if (defined(__GNU_LIBRARY__) || defined(__GLIBC__)) && !defined(__UCLIBC__) +# if !defined(__GLIBC__) || (__GLIBC__ < 2) +/* These aren't declared in any libc5 header */ +extern char *program_invocation_name, *program_invocation_short_name; +# endif +static const char * +__getProgramName() +{ + char * arg = strrchr(program_invocation_name, '/'); + if (arg) + return arg+1; + + /* If there was no '/' at all we likely have a windows like path from + * a wine application. + */ + arg = strrchr(program_invocation_name, '\\'); + if (arg) + return arg+1; + + return program_invocation_name; +} +# define GET_PROGRAM_NAME() __getProgramName() +#elif defined(__CYGWIN__) +# define GET_PROGRAM_NAME() program_invocation_short_name +#elif defined(__FreeBSD__) && (__FreeBSD__ >= 2) +# include <osreldate.h> +# if (__FreeBSD_version >= 440000) +# define GET_PROGRAM_NAME() getprogname() +# endif +#elif defined(__NetBSD__) && defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106000100) +# define GET_PROGRAM_NAME() getprogname() +#elif defined(__DragonFly__) +# define GET_PROGRAM_NAME() getprogname() +#elif defined(__APPLE__) +# define GET_PROGRAM_NAME() getprogname() +#elif defined(ANDROID) +# define GET_PROGRAM_NAME() getprogname() +#elif defined(__sun) +/* Solaris has getexecname() which returns the full path - return just + the basename to match BSD getprogname() */ +# include <libgen.h> + +static const char * +__getProgramName() +{ + static const char *progname; + + if (progname == NULL) { + const char *e = getexecname(); + if (e != NULL) { + /* Have to make a copy since getexecname can return a readonly + string, but basename expects to be able to modify its arg. */ + char *n = strdup(e); + if (n != NULL) { + progname = basename(n); + } + } + } + return progname; +} + +# define GET_PROGRAM_NAME() __getProgramName() +#endif + +#if !defined(GET_PROGRAM_NAME) +# if defined(__OpenBSD__) || defined(NetBSD) || defined(__UCLIBC__) || defined(ANDROID) +/* This is a hack. It's said to work on OpenBSD, NetBSD and GNU. + * Rogelio M.Serrano Jr. reported it's also working with UCLIBC. It's + * used as a last resort, if there is no documented facility available. */ +static const char * +__getProgramName() +{ + extern const char *__progname; + char * arg = strrchr(__progname, '/'); + if (arg) + return arg+1; + else + return __progname; +} +# define GET_PROGRAM_NAME() __getProgramName() +# else +# define GET_PROGRAM_NAME() "" +# pragma message ( "Warning: Per application configuration won't work with your OS version." ) +# endif +#endif + +const char * +util_get_process_name(void) +{ + return GET_PROGRAM_NAME(); +} diff --git a/lib/mesa/src/util/u_process.h b/lib/mesa/src/util/u_process.h new file mode 100644 index 000000000..77f7cb1cb --- /dev/null +++ b/lib/mesa/src/util/u_process.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2003 Felix Kuehling + * Copyright © 2018 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS + * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ + +#ifndef PROCESS_H +#define PROCESS_H + +const char * +util_get_process_name(void); + +#endif diff --git a/lib/mesa/src/util/vma.c b/lib/mesa/src/util/vma.c new file mode 100644 index 000000000..c8f55031c --- /dev/null +++ b/lib/mesa/src/util/vma.c @@ -0,0 +1,234 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <stdlib.h> + +#include "util/u_math.h" +#include "util/vma.h" + +struct util_vma_hole { + struct list_head link; + uint64_t offset; + uint64_t size; +}; + +#define util_vma_foreach_hole(_hole, _heap) \ + list_for_each_entry(struct util_vma_hole, _hole, &(_heap)->holes, link) + +#define util_vma_foreach_hole_safe(_hole, _heap) \ + list_for_each_entry_safe(struct util_vma_hole, _hole, &(_heap)->holes, link) + +void +util_vma_heap_init(struct util_vma_heap *heap, + uint64_t start, uint64_t size) +{ + list_inithead(&heap->holes); + util_vma_heap_free(heap, start, size); +} + +void +util_vma_heap_finish(struct util_vma_heap *heap) +{ + util_vma_foreach_hole_safe(hole, heap) + free(hole); +} + +#ifndef NDEBUG +static void +util_vma_heap_validate(struct util_vma_heap *heap) +{ + uint64_t prev_offset = 0; + util_vma_foreach_hole(hole, heap) { + assert(hole->offset > 0); + assert(hole->size > 0); + + if (&hole->link == heap->holes.next) { + /* This must be the top-most hole. Assert that, if it overflows, it + * overflows to 0, i.e. 2^64. + */ + assert(hole->size + hole->offset == 0 || + hole->size + hole->offset > hole->offset); + } else { + /* This is not the top-most hole so it must not overflow and, in + * fact, must be strictly lower than the top-most hole. If + * hole->size + hole->offset == prev_offset, then we failed to join + * holes during a util_vma_heap_free. + */ + assert(hole->size + hole->offset > hole->offset && + hole->size + hole->offset < prev_offset); + } + prev_offset = hole->offset; + } +} +#else +#define util_vma_heap_validate(heap) +#endif + +uint64_t +util_vma_heap_alloc(struct util_vma_heap *heap, + uint64_t size, uint64_t alignment) +{ + /* The caller is expected to reject zero-size allocations */ + assert(size > 0); + assert(alignment > 0); + + util_vma_heap_validate(heap); + + util_vma_foreach_hole_safe(hole, heap) { + if (size > hole->size) + continue; + + /* Compute the offset as the highest address where a chunk of the given + * size can be without going over the top of the hole. + * + * This calculation is known to not overflow because we know that + * hole->size + hole->offset can only overflow to 0 and size > 0. + */ + uint64_t offset = (hole->size - size) + hole->offset; + + /* Align the offset. We align down and not up because we are allocating + * from the top of the hole and not the bottom. + */ + offset = (offset / alignment) * alignment; + + if (offset < hole->offset) + continue; + + if (offset == hole->offset && size == hole->size) { + /* Just get rid of the hole. */ + list_del(&hole->link); + free(hole); + util_vma_heap_validate(heap); + return offset; + } + + assert(offset - hole->offset <= hole->size - size); + uint64_t waste = (hole->size - size) - (offset - hole->offset); + if (waste == 0) { + /* We allocated at the top. Shrink the hole down. */ + hole->size -= size; + util_vma_heap_validate(heap); + return offset; + } + + if (offset == hole->offset) { + /* We allocated at the bottom. Shrink the hole up. */ + hole->offset += size; + hole->size -= size; + util_vma_heap_validate(heap); + return offset; + } + + /* We allocated in the middle. We need to split the old hole into two + * holes, one high and one low. + */ + struct util_vma_hole *high_hole = calloc(1, sizeof(*hole)); + high_hole->offset = offset + size; + high_hole->size = waste; + + /* Adjust the hole to be the amount of space left at he bottom of the + * original hole. + */ + hole->size = offset - hole->offset; + + /* Place the new hole before the old hole so that the list is in order + * from high to low. + */ + list_addtail(&high_hole->link, &hole->link); + + util_vma_heap_validate(heap); + + return offset; + } + + /* Failed to allocate */ + return 0; +} + +void +util_vma_heap_free(struct util_vma_heap *heap, + uint64_t offset, uint64_t size) +{ + /* An offset of 0 is reserved for allocation failure. It is not a valid + * address and cannot be freed. + */ + assert(offset > 0); + + /* Freeing something with a size of 0 is also not valid. */ + assert(size > 0); + + /* It's possible for offset + size to wrap around if we touch the top of + * the 64-bit address space, but we cannot go any higher than 2^64. + */ + assert(offset + size == 0 || offset + size > offset); + + util_vma_heap_validate(heap); + + /* Find immediately higher and lower holes if they exist. */ + struct util_vma_hole *high_hole = NULL, *low_hole = NULL; + util_vma_foreach_hole(hole, heap) { + if (hole->offset <= offset) { + low_hole = hole; + break; + } + high_hole = hole; + } + + if (high_hole) + assert(offset + size <= high_hole->offset); + bool high_adjacent = high_hole && offset + size == high_hole->offset; + + if (low_hole) { + assert(low_hole->offset + low_hole->size > low_hole->offset); + assert(low_hole->offset + low_hole->size <= offset); + } + bool low_adjacent = low_hole && low_hole->offset + low_hole->size == offset; + + if (low_adjacent && high_adjacent) { + /* Merge the two holes */ + low_hole->size += size + high_hole->size; + list_del(&high_hole->link); + free(high_hole); + } else if (low_adjacent) { + /* Merge into the low hole */ + low_hole->size += size; + } else if (high_adjacent) { + /* Merge into the high hole */ + high_hole->offset = offset; + high_hole->size += size; + } else { + /* Neither hole is adjacent; make a new one */ + struct util_vma_hole *hole = calloc(1, sizeof(*hole)); + + hole->offset = offset; + hole->size = size; + + /* Add it after the high hole so we maintain high-to-low ordering */ + if (high_hole) + list_add(&hole->link, &high_hole->link); + else + list_add(&hole->link, &heap->holes); + } + + util_vma_heap_validate(heap); +} diff --git a/lib/mesa/src/util/vma.h b/lib/mesa/src/util/vma.h new file mode 100644 index 000000000..ed69914e4 --- /dev/null +++ b/lib/mesa/src/util/vma.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _UTIL_VMA_H +#define _UTIL_VMA_H + +#include <stdint.h> + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct util_vma_heap { + struct list_head holes; +}; + +void util_vma_heap_init(struct util_vma_heap *heap, + uint64_t start, uint64_t size); +void util_vma_heap_finish(struct util_vma_heap *heap); + +uint64_t util_vma_heap_alloc(struct util_vma_heap *heap, + uint64_t size, uint64_t alignment); + +void util_vma_heap_free(struct util_vma_heap *heap, + uint64_t offset, uint64_t size); + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif /* _UTIL_DEBUG_H */ diff --git a/lib/mesa/src/util/xmlconfig.h b/lib/mesa/src/util/xmlconfig.h index 77aa14c20..cc8c6ef09 100644 --- a/lib/mesa/src/util/xmlconfig.h +++ b/lib/mesa/src/util/xmlconfig.h @@ -32,6 +32,7 @@ #include "util/mesa-sha1.h" #include "util/ralloc.h" +#include <string.h> #define STRING_CONF_MAXLEN 25 @@ -101,10 +102,11 @@ void driParseOptionInfo (driOptionCache *info, const char *configOptions); /** \brief Initialize option cache from info and parse configuration files * - * To be called in <driver>CreateContext. screenNum and driverName select - * device sections. */ + * To be called in <driver>CreateContext. screenNum, driverName and + * kernelDriverName select device sections. */ void driParseConfigFiles (driOptionCache *cache, const driOptionCache *info, - int screenNum, const char *driverName); + int screenNum, const char *driverName, + const char *kernelDriverName); /** \brief Destroy option info * * To be called in <driver>DestroyScreen */ diff --git a/lib/mesa/src/util/xmlpool/LINGUAS b/lib/mesa/src/util/xmlpool/LINGUAS new file mode 100644 index 000000000..362017651 --- /dev/null +++ b/lib/mesa/src/util/xmlpool/LINGUAS @@ -0,0 +1 @@ +ca es de nl sv fr diff --git a/lib/mesa/src/util/xmlpool/POTFILES b/lib/mesa/src/util/xmlpool/POTFILES new file mode 100644 index 000000000..d68d7009b --- /dev/null +++ b/lib/mesa/src/util/xmlpool/POTFILES @@ -0,0 +1 @@ +src/util/xmlpool/t_options.h diff --git a/lib/mesa/src/util/xmlpool/SConscript b/lib/mesa/src/util/xmlpool/SConscript index fa42554d3..0a00cefa6 100644 --- a/lib/mesa/src/util/xmlpool/SConscript +++ b/lib/mesa/src/util/xmlpool/SConscript @@ -8,7 +8,7 @@ xmlpool_options, = env.CodeGenerate( target = 'options.h', script = 'gen_xmlpool.py', source = ['t_options.h'], - command = python_cmd + ' $SCRIPT $SOURCE ' + LOCALEDIR + ' > $TARGET' + command = python_cmd + ' $SCRIPT --template $SOURCE --output $TARGET --localedir ' + LOCALEDIR ) Export('xmlpool_options') diff --git a/lib/mesa/src/util/xmlpool/ca.gmo b/lib/mesa/src/util/xmlpool/ca.gmo Binary files differnew file mode 100644 index 000000000..2786d3f4d --- /dev/null +++ b/lib/mesa/src/util/xmlpool/ca.gmo diff --git a/lib/mesa/src/util/xmlpool/ca.po b/lib/mesa/src/util/xmlpool/ca.po index 03bf29613..91621f283 100644 --- a/lib/mesa/src/util/xmlpool/ca.po +++ b/lib/mesa/src/util/xmlpool/ca.po @@ -39,14 +39,6 @@ msgstr "" msgid "Debugging" msgstr "Depuració" -#: t_options.h:60 -msgid "Disable 3D acceleration" -msgstr "Deshabilita l'acceleració 3D" - -#: t_options.h:65 -msgid "Show performance boxes" -msgstr "Mostra les caixes de rendiment" - #: t_options.h:70 msgid "Enable flushing batchbuffer after each draw call" msgstr "Habilita el buidatge del batchbuffer després de cada trucada de dibuix" @@ -75,10 +67,6 @@ msgstr "" "Deshabilita les continuacions de línia basades en barra invertida en la font " "GLSL" -#: t_options.h:100 -msgid "Disable GL_ARB_shader_bit_encoding" -msgstr "Deshabilita el GL_ARB_shader_bit_encoding" - #: t_options.h:105 msgid "" "Force a default GLSL version for shaders that lack an explicit #version line" @@ -94,87 +82,6 @@ msgstr "Permet les directives #extension GLSL en el mitjà dels shaders" msgid "Image Quality" msgstr "Qualitat d'imatge" -#: t_options.h:133 -msgid "Texture color depth" -msgstr "Profunditat de color de textura" - -#: t_options.h:134 -msgid "Prefer frame buffer color depth" -msgstr "Prefereix profunditat de color del framebuffer" - -#: t_options.h:135 -msgid "Prefer 32 bits per texel" -msgstr "Prefereix 32 bits per texel" - -#: t_options.h:136 -msgid "Prefer 16 bits per texel" -msgstr "Prefereix 16 bits per texel" - -#: t_options.h:137 -msgid "Force 16 bits per texel" -msgstr "Força 16 bits per texel" - -#: t_options.h:143 -msgid "Initial maximum value for anisotropic texture filtering" -msgstr "Valor màxim inicial per a la filtració de textura anisòtropa" - -#: t_options.h:148 -msgid "Forbid negative texture LOD bias" -msgstr "" -"Prohibeix una parcialitat negativa del Nivell de Detalle (LOD) de les " -"textures" - -#: t_options.h:153 -msgid "" -"Enable S3TC texture compression even if software support is not available" -msgstr "" -"Habilita la compressió de textures S3TC encara que el suport de programari " -"no estigui disponible" - -#: t_options.h:160 -msgid "Initial color reduction method" -msgstr "Mètode inicial de reducció de color" - -#: t_options.h:161 -msgid "Round colors" -msgstr "Colors arrodonits" - -#: t_options.h:162 -msgid "Dither colors" -msgstr "Colors tramats" - -#: t_options.h:170 -msgid "Color rounding method" -msgstr "Mètode d'arrodoniment de color" - -#: t_options.h:171 -msgid "Round color components downward" -msgstr "Arrodoneix els components de color a baix" - -#: t_options.h:172 -msgid "Round to nearest color" -msgstr "Arrodoneix al color més proper" - -#: t_options.h:181 -msgid "Color dithering method" -msgstr "Mètode de tramat de color" - -#: t_options.h:182 -msgid "Horizontal error diffusion" -msgstr "Difusió d'error horitzontal" - -#: t_options.h:183 -msgid "Horizontal error diffusion, reset error at line start" -msgstr "Difusió d'error horitzontal, reinicia l'error a l'inici de la línia" - -#: t_options.h:184 -msgid "Ordered 2D color dithering" -msgstr "Tramat de color 2D ordenat" - -#: t_options.h:190 -msgid "Floating point depth buffer" -msgstr "Buffer de profunditat de punt flotant" - #: t_options.h:195 msgid "A post-processing filter to cel-shade the output" msgstr "Un filtre de postprocessament per a aplicar cel shading a la sortida" @@ -212,46 +119,6 @@ msgstr "" msgid "Performance" msgstr "Rendiment" -#: t_options.h:238 -msgid "TCL mode (Transformation, Clipping, Lighting)" -msgstr "Mode TCL (Transformació, Retall, Il·luminació)" - -#: t_options.h:239 -msgid "Use software TCL pipeline" -msgstr "Utilitza la canonada TCL de programari" - -#: t_options.h:240 -msgid "Use hardware TCL as first TCL pipeline stage" -msgstr "Utilitza el TCL de maquinari com a la primera fase de la canonada TCL" - -#: t_options.h:241 -msgid "Bypass the TCL pipeline" -msgstr "Passa per alt la canonada TCL" - -#: t_options.h:242 -msgid "" -"Bypass the TCL pipeline with state-based machine code generated on-the-fly" -msgstr "" -"Passa per alt la canonada TCL amb codi de màquina basat en estats, generat " -"sobre la marxa" - -#: t_options.h:251 -msgid "Method to limit rendering latency" -msgstr "Mètode per a limitar la latència de renderització" - -#: t_options.h:252 -msgid "Busy waiting for the graphics hardware" -msgstr "Espera activa pel maquinari de gràfics" - -#: t_options.h:253 -msgid "Sleep for brief intervals while waiting for the graphics hardware" -msgstr "Dorm per intervals breus mentre s'espera al maquinari de gràfics" - -#: t_options.h:254 -msgid "Let the graphics hardware emit a software interrupt and sleep" -msgstr "" -"Deixa que el maquinari de gràfics emeti una interrupció de programari i dormi" - #: t_options.h:264 msgid "Synchronization with vertical refresh (swap intervals)" msgstr "Sincronització amb refresc vertical (intervals d'intercanvi)" @@ -277,44 +144,6 @@ msgstr "" "Sempre sincronitza amb el refresc vertical, l'aplicació tria l'interval " "mínim d'intercanvi" -#: t_options.h:276 -msgid "Use HyperZ to boost performance" -msgstr "Utilitza el HyperZ per a augmentar el rendiment" - -#: t_options.h:281 -msgid "Number of texture units used" -msgstr "Nombre d'unitats de textura utilitzades" - -#: t_options.h:286 -msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" -msgstr "" -"Qualitat vs. velocitat de filtració de textura, àlies filtració \"brilinear" -"\" de textura" - -#: t_options.h:294 -msgid "Used types of texture memory" -msgstr "Tipus utilitzats de memòria de textura" - -#: t_options.h:295 -msgid "All available memory" -msgstr "Tota la memòria disponible" - -#: t_options.h:296 -msgid "Only card memory (if available)" -msgstr "Només memòria de targeta (si està disponible)" - -#: t_options.h:297 -msgid "Only GART (AGP/PCIE) memory (if available)" -msgstr "Només memòria GART (AGP/PCIE) (si està disponible)" - -#: t_options.h:309 -msgid "Features that are not hardware-accelerated" -msgstr "Característiques no accelerades per maquinari" - -#: t_options.h:313 -msgid "Enable extension GL_ARB_vertex_program" -msgstr "Habilita l'extensió GL_ARB_vertex_program" - #: t_options.h:323 msgid "Miscellaneous" msgstr "Miscel·lània" diff --git a/lib/mesa/src/util/xmlpool/de.gmo b/lib/mesa/src/util/xmlpool/de.gmo Binary files differnew file mode 100644 index 000000000..313e4b779 --- /dev/null +++ b/lib/mesa/src/util/xmlpool/de.gmo diff --git a/lib/mesa/src/util/xmlpool/de.po b/lib/mesa/src/util/xmlpool/de.po index 7b20d00a6..8c1d3df3f 100644 --- a/lib/mesa/src/util/xmlpool/de.po +++ b/lib/mesa/src/util/xmlpool/de.po @@ -21,14 +21,6 @@ msgstr "" msgid "Debugging" msgstr "Fehlersuche" -#: t_options.h:60 -msgid "Disable 3D acceleration" -msgstr "3D-Beschleunigung abschalten" - -#: t_options.h:65 -msgid "Show performance boxes" -msgstr "Zeige Performanceboxen" - #: t_options.h:70 msgid "Enable flushing batchbuffer after each draw call" msgstr "Aktiviere sofortige Leerung des Stapelpuffers nach jedem Zeichenaufruf" @@ -54,10 +46,6 @@ msgstr "" msgid "Disable backslash-based line continuations in GLSL source" msgstr "" -#: t_options.h:100 -msgid "Disable GL_ARB_shader_bit_encoding" -msgstr "" - #: t_options.h:105 msgid "" "Force a default GLSL version for shaders that lack an explicit #version line" @@ -71,85 +59,6 @@ msgstr "" msgid "Image Quality" msgstr "Bildqualität" -#: t_options.h:133 -msgid "Texture color depth" -msgstr "Texturfarbtiefe" - -#: t_options.h:134 -msgid "Prefer frame buffer color depth" -msgstr "Bevorzuge Farbtiefe des Framebuffers" - -#: t_options.h:135 -msgid "Prefer 32 bits per texel" -msgstr "Bevorzuge 32 bits pro Texel" - -#: t_options.h:136 -msgid "Prefer 16 bits per texel" -msgstr "Bevorzuge 16 bits pro Texel" - -#: t_options.h:137 -msgid "Force 16 bits per texel" -msgstr "Erzwinge 16 bits pro Texel" - -#: t_options.h:143 -msgid "Initial maximum value for anisotropic texture filtering" -msgstr "Initialer Maximalwert für anisotropische Texturfilterung" - -#: t_options.h:148 -msgid "Forbid negative texture LOD bias" -msgstr "Verbiete negative Textur-Detailgradverschiebung" - -#: t_options.h:153 -msgid "" -"Enable S3TC texture compression even if software support is not available" -msgstr "" -"Aktiviere S3TC Texturkomprimierung auch wenn die nötige " -"Softwareunterstützung fehlt" - -#: t_options.h:160 -msgid "Initial color reduction method" -msgstr "Initiale Farbreduktionsmethode" - -#: t_options.h:161 -msgid "Round colors" -msgstr "Farben runden" - -#: t_options.h:162 -msgid "Dither colors" -msgstr "Farben rastern" - -#: t_options.h:170 -msgid "Color rounding method" -msgstr "Farbrundungsmethode" - -#: t_options.h:171 -msgid "Round color components downward" -msgstr "Farbkomponenten abrunden" - -#: t_options.h:172 -msgid "Round to nearest color" -msgstr "Zur ähnlichsten Farbe runden" - -#: t_options.h:181 -msgid "Color dithering method" -msgstr "Farbrasterungsmethode" - -#: t_options.h:182 -msgid "Horizontal error diffusion" -msgstr "Horizontale Fehlerstreuung" - -#: t_options.h:183 -msgid "Horizontal error diffusion, reset error at line start" -msgstr "Horizontale Fehlerstreuung, Fehler am Zeilenanfang zurücksetzen" - -#: t_options.h:184 -msgid "Ordered 2D color dithering" -msgstr "Geordnete 2D Farbrasterung" - -#: t_options.h:190 -msgid "Floating point depth buffer" -msgstr "Fließkomma z-Puffer" - #: t_options.h:195 msgid "A post-processing filter to cel-shade the output" msgstr "Nachbearbeitungsfilter für Cell Shading" @@ -186,46 +95,6 @@ msgstr "" msgid "Performance" msgstr "Leistung" -#: t_options.h:238 -msgid "TCL mode (Transformation, Clipping, Lighting)" -msgstr "TCL-Modus (Transformation, Clipping, Licht)" - -#: t_options.h:239 -msgid "Use software TCL pipeline" -msgstr "Benutze die Software-TCL-Pipeline" - -#: t_options.h:240 -msgid "Use hardware TCL as first TCL pipeline stage" -msgstr "Benutze Hardware TCL als erste Stufe der TCL-Pipeline" - -#: t_options.h:241 -msgid "Bypass the TCL pipeline" -msgstr "Umgehe die TCL-Pipeline" - -#: t_options.h:242 -msgid "" -"Bypass the TCL pipeline with state-based machine code generated on-the-fly" -msgstr "" -"Umgehe die TCL-Pipeline mit zur Laufzeit erzeugtem, zustandsbasiertem " -"Maschinencode" - -#: t_options.h:251 -msgid "Method to limit rendering latency" -msgstr "Methode zur Begrenzung der Bildverzögerung" - -#: t_options.h:252 -msgid "Busy waiting for the graphics hardware" -msgstr "Aktives Warten auf die Grafikhardware" - -#: t_options.h:253 -msgid "Sleep for brief intervals while waiting for the graphics hardware" -msgstr "Kurze Schlafintervalle beim Warten auf die Grafikhardware" - -#: t_options.h:254 -msgid "Let the graphics hardware emit a software interrupt and sleep" -msgstr "" -"Die Grafikhardware eine Softwareunterbrechnung erzeugen lassen und schlafen" - #: t_options.h:264 msgid "Synchronization with vertical refresh (swap intervals)" msgstr "Synchronisation mit der vertikalen Bildwiederholung" @@ -252,44 +121,6 @@ msgstr "" "Immer mit der Bildwiederholung synchronisieren, Anwendung wählt das minimale " "Bildintervall" -#: t_options.h:276 -msgid "Use HyperZ to boost performance" -msgstr "HyperZ zur Leistungssteigerung verwenden" - -#: t_options.h:281 -msgid "Number of texture units used" -msgstr "Anzahl der benutzten Textureinheiten" - -#: t_options.h:286 -msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" -msgstr "" -"Texturfilterqualität versus -geschwindigkeit, auch bekannt als „brilineare“ " -"Texturfilterung" - -#: t_options.h:294 -msgid "Used types of texture memory" -msgstr "Benutzte Arten von Texturspeicher" - -#: t_options.h:295 -msgid "All available memory" -msgstr "Aller verfügbarer Speicher" - -#: t_options.h:296 -msgid "Only card memory (if available)" -msgstr "Nur Grafikspeicher (falls verfügbar)" - -#: t_options.h:297 -msgid "Only GART (AGP/PCIE) memory (if available)" -msgstr "Nur GART-Speicher (AGP/PCIE) (falls verfügbar)" - -#: t_options.h:309 -msgid "Features that are not hardware-accelerated" -msgstr "Funktionalität, die nicht hardwarebeschleunigt ist" - -#: t_options.h:313 -msgid "Enable extension GL_ARB_vertex_program" -msgstr "Erweiterung GL_ARB_vertex_program aktivieren" - #: t_options.h:323 msgid "Miscellaneous" msgstr "" diff --git a/lib/mesa/src/util/xmlpool/es.gmo b/lib/mesa/src/util/xmlpool/es.gmo Binary files differnew file mode 100644 index 000000000..f4732492f --- /dev/null +++ b/lib/mesa/src/util/xmlpool/es.gmo diff --git a/lib/mesa/src/util/xmlpool/es.po b/lib/mesa/src/util/xmlpool/es.po index f9d950ac1..e5f44c8ef 100644 --- a/lib/mesa/src/util/xmlpool/es.po +++ b/lib/mesa/src/util/xmlpool/es.po @@ -24,14 +24,6 @@ msgstr "" msgid "Debugging" msgstr "Depuración" -#: t_options.h:60 -msgid "Disable 3D acceleration" -msgstr "Deshabilitar aceleración 3D" - -#: t_options.h:65 -msgid "Show performance boxes" -msgstr "Mostrar cajas de rendimiento" - #: t_options.h:70 msgid "Enable flushing batchbuffer after each draw call" msgstr "Habilitar vaciado del batchbuffer después de cada llamada de dibujo" @@ -59,10 +51,6 @@ msgstr "" "Deshabilitar continuaciones de línea basadas en barra inversa en el código " "GLSL" -#: t_options.h:100 -msgid "Disable GL_ARB_shader_bit_encoding" -msgstr "Deshabilitar GL_ARB_shader_bit_encoding" - #: t_options.h:105 msgid "" "Force a default GLSL version for shaders that lack an explicit #version line" @@ -78,85 +66,6 @@ msgstr "Permite directivas #extension GLSL en medio de los shaders" msgid "Image Quality" msgstr "Calidad de imagen" -#: t_options.h:133 -msgid "Texture color depth" -msgstr "Profundidad de color de textura" - -#: t_options.h:134 -msgid "Prefer frame buffer color depth" -msgstr "Preferir profundidad de color del framebuffer" - -#: t_options.h:135 -msgid "Prefer 32 bits per texel" -msgstr "Preferir 32 bits por texel" - -#: t_options.h:136 -msgid "Prefer 16 bits per texel" -msgstr "Preferir 16 bits por texel" - -#: t_options.h:137 -msgid "Force 16 bits per texel" -msgstr "Forzar a 16 bits por texel" - -#: t_options.h:143 -msgid "Initial maximum value for anisotropic texture filtering" -msgstr "Valor máximo inicial para filtrado anisotrópico de textura" - -#: t_options.h:148 -msgid "Forbid negative texture LOD bias" -msgstr "Prohibir valores negativos de Nivel De Detalle (LOD) de texturas" - -#: t_options.h:153 -msgid "" -"Enable S3TC texture compression even if software support is not available" -msgstr "" -"Habilitar la compresión de texturas S3TC incluso si el soporte por software " -"no está disponible" - -#: t_options.h:160 -msgid "Initial color reduction method" -msgstr "Método inicial de reducción de color" - -#: t_options.h:161 -msgid "Round colors" -msgstr "Colores redondeados" - -#: t_options.h:162 -msgid "Dither colors" -msgstr "Colores suavizados" - -#: t_options.h:170 -msgid "Color rounding method" -msgstr "Método de redondeo de colores" - -#: t_options.h:171 -msgid "Round color components downward" -msgstr "Redondear hacia abajo los componentes de color" - -#: t_options.h:172 -msgid "Round to nearest color" -msgstr "Redondear al color más cercano" - -#: t_options.h:181 -msgid "Color dithering method" -msgstr "Método de suavizado de color" - -#: t_options.h:182 -msgid "Horizontal error diffusion" -msgstr "Difusión de error horizontal" - -#: t_options.h:183 -msgid "Horizontal error diffusion, reset error at line start" -msgstr "Difusión de error horizontal, reiniciar error al comienzo de línea" - -#: t_options.h:184 -msgid "Ordered 2D color dithering" -msgstr "Suavizado de color 2D ordenado" - -#: t_options.h:190 -msgid "Floating point depth buffer" -msgstr "Búfer de profundidad en coma flotante" - #: t_options.h:195 msgid "A post-processing filter to cel-shade the output" msgstr "Un filtro de postprocesamiento para aplicar cel shading a la salida" @@ -193,46 +102,6 @@ msgstr "" msgid "Performance" msgstr "Rendimiento" -#: t_options.h:238 -msgid "TCL mode (Transformation, Clipping, Lighting)" -msgstr "Modo TCL (Transformación, Recorte, Iluminación)" - -#: t_options.h:239 -msgid "Use software TCL pipeline" -msgstr "Usar tubería TCL por software" - -#: t_options.h:240 -msgid "Use hardware TCL as first TCL pipeline stage" -msgstr "Usar TCL por hardware en la primera fase de la tubería TCL" - -#: t_options.h:241 -msgid "Bypass the TCL pipeline" -msgstr "Pasar por alto la tubería TCL" - -#: t_options.h:242 -msgid "" -"Bypass the TCL pipeline with state-based machine code generated on-the-fly" -msgstr "" -"Pasar por alto la tubería TCL con código máquina basado en estados, generado " -"al vuelo" - -#: t_options.h:251 -msgid "Method to limit rendering latency" -msgstr "Método para limitar la latencia de renderización" - -#: t_options.h:252 -msgid "Busy waiting for the graphics hardware" -msgstr "Esperar activamente al hardware gráfico" - -#: t_options.h:253 -msgid "Sleep for brief intervals while waiting for the graphics hardware" -msgstr "Dormir en intervalos cortos mientras se espera al hardware gráfico" - -#: t_options.h:254 -msgid "Let the graphics hardware emit a software interrupt and sleep" -msgstr "" -"Permitir que el hardware gráfico emita una interrupción de software y duerma" - #: t_options.h:264 msgid "Synchronization with vertical refresh (swap intervals)" msgstr "Sincronización con el refresco vertical (intervalos de intercambio)" @@ -261,44 +130,6 @@ msgstr "" "Sincronizar siempre con el refresco vertical, la aplicación elige el " "intervalo de intercambio mínimo" -#: t_options.h:276 -msgid "Use HyperZ to boost performance" -msgstr "Usar HyperZ para potenciar rendimiento" - -#: t_options.h:281 -msgid "Number of texture units used" -msgstr "Número de unidades de textura usadas" - -#: t_options.h:286 -msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" -msgstr "" -"Calidad de filtrado de textura vs. velocidad, alias filtrado \"brilinear\" " -"de textura" - -#: t_options.h:294 -msgid "Used types of texture memory" -msgstr "Tipos de memoria de textura usados" - -#: t_options.h:295 -msgid "All available memory" -msgstr "Toda la memoria disponible" - -#: t_options.h:296 -msgid "Only card memory (if available)" -msgstr "Solo memoria de tarjeta (si está disponible)" - -#: t_options.h:297 -msgid "Only GART (AGP/PCIE) memory (if available)" -msgstr "Solo memoria GART (AGP/PCIE) (si está disponible)" - -#: t_options.h:309 -msgid "Features that are not hardware-accelerated" -msgstr "Características no aceleradas por hardware" - -#: t_options.h:313 -msgid "Enable extension GL_ARB_vertex_program" -msgstr "Habilitar la extensión GL_ARB_vertex_program" - #: t_options.h:323 msgid "Miscellaneous" msgstr "Misceláneos" diff --git a/lib/mesa/src/util/xmlpool/fr.gmo b/lib/mesa/src/util/xmlpool/fr.gmo Binary files differnew file mode 100644 index 000000000..380d43cd9 --- /dev/null +++ b/lib/mesa/src/util/xmlpool/fr.gmo diff --git a/lib/mesa/src/util/xmlpool/fr.po b/lib/mesa/src/util/xmlpool/fr.po index fa069652c..aa8706cbb 100644 --- a/lib/mesa/src/util/xmlpool/fr.po +++ b/lib/mesa/src/util/xmlpool/fr.po @@ -21,14 +21,6 @@ msgstr "" msgid "Debugging" msgstr "Debogage" -#: t_options.h:60 -msgid "Disable 3D acceleration" -msgstr "Désactiver l'accélération 3D" - -#: t_options.h:65 -msgid "Show performance boxes" -msgstr "Afficher les boîtes de performance" - #: t_options.h:70 msgid "Enable flushing batchbuffer after each draw call" msgstr "" @@ -53,10 +45,6 @@ msgstr "" msgid "Disable backslash-based line continuations in GLSL source" msgstr "" -#: t_options.h:100 -msgid "Disable GL_ARB_shader_bit_encoding" -msgstr "" - #: t_options.h:105 msgid "" "Force a default GLSL version for shaders that lack an explicit #version line" @@ -70,84 +58,6 @@ msgstr "" msgid "Image Quality" msgstr "Qualité d'image" -#: t_options.h:133 -msgid "Texture color depth" -msgstr "Profondeur de texture" - -#: t_options.h:134 -msgid "Prefer frame buffer color depth" -msgstr "Profondeur de couleur" - -#: t_options.h:135 -msgid "Prefer 32 bits per texel" -msgstr "Préférer 32 bits par texel" - -#: t_options.h:136 -msgid "Prefer 16 bits per texel" -msgstr "Prérérer 16 bits par texel" - -#: t_options.h:137 -msgid "Force 16 bits per texel" -msgstr "Forcer 16 bits par texel" - -#: t_options.h:143 -msgid "Initial maximum value for anisotropic texture filtering" -msgstr "Valeur maximale initiale pour le filtrage anisotropique de texture" - -#: t_options.h:148 -msgid "Forbid negative texture LOD bias" -msgstr "Interdire le LOD bias negatif" - -#: t_options.h:153 -msgid "" -"Enable S3TC texture compression even if software support is not available" -msgstr "" -"Activer la compression de texture S3TC même si le support logiciel est absent" - -#: t_options.h:160 -msgid "Initial color reduction method" -msgstr "Technique de réduction de couleurs" - -#: t_options.h:161 -msgid "Round colors" -msgstr "Arrondir les valeurs de couleur" - -#: t_options.h:162 -msgid "Dither colors" -msgstr "Tramer les couleurs" - -#: t_options.h:170 -msgid "Color rounding method" -msgstr "Méthode d'arrondi des couleurs" - -#: t_options.h:171 -msgid "Round color components downward" -msgstr "Arrondi à l'inférieur" - -#: t_options.h:172 -msgid "Round to nearest color" -msgstr "Arrondi au plus proche" - -#: t_options.h:181 -msgid "Color dithering method" -msgstr "Méthode de tramage" - -#: t_options.h:182 -msgid "Horizontal error diffusion" -msgstr "Diffusion d'erreur horizontale" - -#: t_options.h:183 -msgid "Horizontal error diffusion, reset error at line start" -msgstr "Diffusion d'erreur horizontale, réinitialisé pour chaque ligne" - -#: t_options.h:184 -msgid "Ordered 2D color dithering" -msgstr "Tramage ordonné des couleurs" - -#: t_options.h:190 -msgid "Floating point depth buffer" -msgstr "Z-buffer en virgule flottante" - #: t_options.h:195 msgid "A post-processing filter to cel-shade the output" msgstr "" @@ -180,45 +90,6 @@ msgstr "" msgid "Performance" msgstr "Performance" -#: t_options.h:238 -msgid "TCL mode (Transformation, Clipping, Lighting)" -msgstr "Mode de TCL (Transformation, Clipping, Eclairage)" - -#: t_options.h:239 -msgid "Use software TCL pipeline" -msgstr "Utiliser un pipeline TCL logiciel" - -#: t_options.h:240 -msgid "Use hardware TCL as first TCL pipeline stage" -msgstr "Utiliser le TCL matériel pour le premier niveau de pipeline" - -#: t_options.h:241 -msgid "Bypass the TCL pipeline" -msgstr "Court-circuiter le pipeline TCL" - -#: t_options.h:242 -msgid "" -"Bypass the TCL pipeline with state-based machine code generated on-the-fly" -msgstr "" -"Court-circuiter le pipeline TCL par une machine à états qui génère le codede " -"TCL à la volée" - -#: t_options.h:251 -msgid "Method to limit rendering latency" -msgstr "Méthode d'attente de la carte graphique" - -#: t_options.h:252 -msgid "Busy waiting for the graphics hardware" -msgstr "Attente active de la carte graphique" - -#: t_options.h:253 -msgid "Sleep for brief intervals while waiting for the graphics hardware" -msgstr "Attente utilisant usleep()" - -#: t_options.h:254 -msgid "Let the graphics hardware emit a software interrupt and sleep" -msgstr "Utiliser les interruptions" - #: t_options.h:264 msgid "Synchronization with vertical refresh (swap intervals)" msgstr "Synchronisation de l'affichage avec le balayage vertical" @@ -249,43 +120,6 @@ msgstr "" "Toujours synchroniser avec le balayage vertical, l'application choisit " "l'intervalle minimal" -#: t_options.h:276 -msgid "Use HyperZ to boost performance" -msgstr "Utiliser le HyperZ pour améliorer les performances" - -#: t_options.h:281 -msgid "Number of texture units used" -msgstr "Nombre d'unités de texture" - -#: t_options.h:286 -msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" -msgstr "" -"Qualité/performance du filtrage trilinéaire de texture (filtrage brilinéaire)" - -#: t_options.h:294 -msgid "Used types of texture memory" -msgstr "Types de mémoire de texture" - -#: t_options.h:295 -msgid "All available memory" -msgstr "Utiliser toute la mémoire disponible" - -#: t_options.h:296 -msgid "Only card memory (if available)" -msgstr "Utiliser uniquement la mémoire graphique (si disponible)" - -#: t_options.h:297 -msgid "Only GART (AGP/PCIE) memory (if available)" -msgstr "Utiliser uniquement la mémoire GART (AGP/PCIE) (si disponible)" - -#: t_options.h:309 -msgid "Features that are not hardware-accelerated" -msgstr "Fonctionnalités ne bénéficiant pas d'une accélération matérielle" - -#: t_options.h:313 -msgid "Enable extension GL_ARB_vertex_program" -msgstr "Activer l'extension GL_ARB_vertex_program" - #: t_options.h:323 msgid "Miscellaneous" msgstr "" diff --git a/lib/mesa/src/util/xmlpool/gen_xmlpool.py b/lib/mesa/src/util/xmlpool/gen_xmlpool.py index eb68a6517..3a3523126 100644 --- a/lib/mesa/src/util/xmlpool/gen_xmlpool.py +++ b/lib/mesa/src/util/xmlpool/gen_xmlpool.py @@ -1,4 +1,4 @@ - +# encoding=utf-8 # # Usage: # gen_xmlpool.py /path/to/t_option.h localedir lang lang lang ... @@ -7,69 +7,68 @@ # `{localedir}/{language}/LC_MESSAGES/options.mo`. # -import sys +from __future__ import print_function, unicode_literals +import argparse import gettext +import io +import os import re +import sys -# Path to t_options.h -template_header_path = sys.argv[1] - -localedir = sys.argv[2] - -# List of supported languages -languages = sys.argv[3:] +if sys.version_info < (3, 0): + gettext_method = 'ugettext' +else: + gettext_method = 'gettext' # Escape special characters in C strings -def escapeCString (s): +def escapeCString(s): escapeSeqs = {'\a' : '\\a', '\b' : '\\b', '\f' : '\\f', '\n' : '\\n', '\r' : '\\r', '\t' : '\\t', '\v' : '\\v', '\\' : '\\\\'} # " -> '' is a hack. Quotes (") aren't possible in XML attributes. # Better use Unicode characters for typographic quotes in option # descriptions and translations. + last_quote = '”' i = 0 r = '' - while i < len(s): - # Special case: escape double quote with \u201c or \u201d, depending + for c in s: + # Special case: escape double quote with “ or ”, depending # on whether it's an open or close quote. This is needed because plain # double quotes are not possible in XML attributes. - if s[i] == '"': - if i == len(s)-1 or s[i+1].isspace(): - # close quote - q = u'\u201c' + if c == '"': + if last_quote == '”': + q = '“' else: - # open quote - q = u'\u201d' + q = '”' + last_quote = q r = r + q - elif escapeSeqs.has_key(s[i]): - r = r + escapeSeqs[s[i]] + elif c in escapeSeqs: + r = r + escapeSeqs[c] else: - r = r + s[i] - i = i + 1 + r = r + c return r # Expand escape sequences in C strings (needed for gettext lookup) -def expandCString (s): +def expandCString(s): escapeSeqs = {'a' : '\a', 'b' : '\b', 'f' : '\f', 'n' : '\n', 'r' : '\r', 't' : '\t', 'v' : '\v', '"' : '"', '\\' : '\\'} - i = 0 escape = False hexa = False octa = False num = 0 digits = 0 - r = '' - while i < len(s): + r = u'' + for c in s: if not escape: - if s[i] == '\\': + if c == '\\': escape = True else: - r = r + s[i] + r = r + c elif hexa: - if (s[i] >= '0' and s[i] <= '9') or \ - (s[i] >= 'a' and s[i] <= 'f') or \ - (s[i] >= 'A' and s[i] <= 'F'): - num = num * 16 + int(s[i],16) + if (c >= '0' and c <= '9') or \ + (c >= 'a' and c <= 'f') or \ + (c >= 'A' and c <= 'F'): + num = num * 16 + int(c, 16) digits = digits + 1 else: digits = 2 @@ -78,8 +77,8 @@ def expandCString (s): escape = False r = r + chr(num) elif octa: - if s[i] >= '0' and s[i] <= '7': - num = num * 8 + int(s[i],8) + if c >= '0' and c <= '7': + num = num * 8 + int(c, 8) digits = digits + 1 else: digits = 3 @@ -88,24 +87,23 @@ def expandCString (s): escape = False r = r + chr(num) else: - if escapeSeqs.has_key(s[i]): - r = r + escapeSeqs[s[i]] + if c in escapeSeqs: + r = r + escapeSeqs[c] escape = False - elif s[i] >= '0' and s[i] <= '7': + elif c >= '0' and c <= '7': octa = True - num = int(s[i],8) + num = int(c, 8) if num <= 3: digits = 1 else: digits = 2 - elif s[i] == 'x' or s[i] == 'X': + elif c == 'x' or c == 'X': hexa = True num = 0 digits = 0 else: - r = r + s[i] + r = r + c escape = False - i = i + 1 return r # Expand matches. The first match is always a DESC or DESC_BEGIN match. @@ -113,7 +111,7 @@ def expandCString (s): # # DESC, DESC_BEGIN format: \1 \2=<lang> \3 \4=gettext(" \5=<text> \6=") \7 # ENUM format: \1 \2=gettext(" \3=<text> \4=") \5 -def expandMatches (matches, translations, end=None): +def expandMatches(matches, translations, outfile, end=None): assert len(matches) > 0 nTranslations = len(translations) i = 0 @@ -124,80 +122,95 @@ def expandMatches (matches, translations, end=None): # are extended with a backslash. suffix = '' if len(matches) == 1 and i < len(translations) and \ - not matches[0].expand (r'\7').endswith('\\'): + not matches[0].expand(r'\7').endswith('\\'): suffix = ' \\' - # Expand the description line. Need to use ugettext in order to allow - # non-ascii unicode chars in the original English descriptions. - text = escapeCString (trans.ugettext (unicode (expandCString ( - matches[0].expand (r'\5')), "utf-8"))).encode("utf-8") - print matches[0].expand (r'\1' + lang + r'\3"' + text + r'"\7') + suffix + text = escapeCString(getattr(trans, gettext_method)(expandCString( + matches[0].expand (r'\5')))) + text = (matches[0].expand(r'\1' + lang + r'\3"' + text + r'"\7') + suffix) + + outfile.write(text + '\n') + # Expand any subsequent enum lines for match in matches[1:]: - text = escapeCString (trans.ugettext (unicode (expandCString ( - match.expand (r'\3')), "utf-8"))).encode("utf-8") - print match.expand (r'\1"' + text + r'"\5') + text = escapeCString(getattr(trans, gettext_method)(expandCString( + match.expand(r'\3')))) + text = match.expand(r'\1"' + text + r'"\5') + + outfile.write(text + '\n') # Expand description end if end: - print end, - -# Compile a list of translation classes to all supported languages. -# The first translation is always a NullTranslations. -translations = [("en", gettext.NullTranslations())] -for lang in languages: - try: - trans = gettext.translation ("options", localedir, [lang]) - except IOError: - sys.stderr.write ("Warning: language '%s' not found.\n" % lang) - continue - translations.append ((lang, trans)) + outfile.write(end) # Regular expressions: -reLibintl_h = re.compile (r'#\s*include\s*<libintl.h>') -reDESC = re.compile (r'(\s*DRI_CONF_DESC\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') -reDESC_BEGIN = re.compile (r'(\s*DRI_CONF_DESC_BEGIN\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') -reENUM = re.compile (r'(\s*DRI_CONF_ENUM\s*\([^,]+,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') -reDESC_END = re.compile (r'\s*DRI_CONF_DESC_END') - -# Print a header -print \ -"/***********************************************************************\n" \ -" *** THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT! ***\n" \ -" ***********************************************************************/" - -# Process the options template and generate options.h with all -# translations. -template = file (template_header_path, "r") -descMatches = [] -for line in template: - if len(descMatches) > 0: - matchENUM = reENUM .match (line) - matchDESC_END = reDESC_END.match (line) - if matchENUM: - descMatches.append (matchENUM) - elif matchDESC_END: - expandMatches (descMatches, translations, line) +reLibintl_h = re.compile(r'#\s*include\s*<libintl.h>') +reDESC = re.compile(r'(\s*DRI_CONF_DESC\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') +reDESC_BEGIN = re.compile(r'(\s*DRI_CONF_DESC_BEGIN\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') +reENUM = re.compile(r'(\s*DRI_CONF_ENUM\s*\([^,]+,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') +reDESC_END = re.compile(r'\s*DRI_CONF_DESC_END') + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--template', required=True) + parser.add_argument('--output', required=True) + parser.add_argument('--localedir', required=True) + parser.add_argument('--languages', nargs='*', default=[]) + args = parser.parse_args() + + # Compile a list of translation classes to all supported languages. + # The first translation is always a NullTranslations. + translations = [("en", gettext.NullTranslations())] + for lang in args.languages: + try: + filename = os.path.join(args.localedir, '{}.gmo'.format(lang)) + with io.open(filename, 'rb') as f: + trans = gettext.GNUTranslations(f) + except (IOError, OSError): + print("Warning: language '%s' not found." % lang, file=sys.stderr) + continue + translations.append((lang, trans)) + + with io.open(args.output, mode='wt', encoding='utf-8') as output: + output.write("/* This is file is generated automatically. Don't edit! */\n") + + # Process the options template and generate options.h with all + # translations. + with io.open(args.template, mode="rt", encoding='utf-8') as template: descMatches = [] - else: - sys.stderr.write ( - "Warning: unexpected line inside description dropped:\n%s\n" \ - % line) - continue - if reLibintl_h.search (line): - # Ignore (comment out) #include <libintl.h> - print "/* %s * commented out by gen_xmlpool.py */" % line - continue - matchDESC = reDESC .match (line) - matchDESC_BEGIN = reDESC_BEGIN.match (line) - if matchDESC: - assert len(descMatches) == 0 - expandMatches ([matchDESC], translations) - elif matchDESC_BEGIN: - assert len(descMatches) == 0 - descMatches = [matchDESC_BEGIN] - else: - print line, - -if len(descMatches) > 0: - sys.stderr.write ("Warning: unterminated description at end of file.\n") - expandMatches (descMatches, translations) + for line in template: + if descMatches: + matchENUM = reENUM.match(line) + matchDESC_END = reDESC_END.match(line) + if matchENUM: + descMatches.append(matchENUM) + elif matchDESC_END: + expandMatches(descMatches, translations, output, line) + descMatches = [] + else: + print("Warning: unexpected line inside description dropped:\n", + line, file=sys.stderr) + continue + if reLibintl_h.search(line): + # Ignore (comment out) #include <libintl.h> + output.write("/* %s * commented out by gen_xmlpool.py */\n" % line) + continue + matchDESC = reDESC.match(line) + matchDESC_BEGIN = reDESC_BEGIN.match(line) + if matchDESC: + assert not descMatches + expandMatches([matchDESC], translations, output) + elif matchDESC_BEGIN: + assert not descMatches + descMatches = [matchDESC_BEGIN] + else: + + output.write(line) + + if descMatches: + print("Warning: unterminated description at end of file.", file=sys.stderr) + expandMatches(descMatches, translations, output) + + +if __name__ == '__main__': + main() diff --git a/lib/mesa/src/util/xmlpool/meson.build b/lib/mesa/src/util/xmlpool/meson.build new file mode 100644 index 000000000..81184fa6b --- /dev/null +++ b/lib/mesa/src/util/xmlpool/meson.build @@ -0,0 +1,40 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +_langs = ['ca', 'es', 'de', 'nl', 'sv', 'fr'] + +_langs_po_files = [] +foreach lang : _langs + _langs_po_files += files(lang + '.po') +endforeach + +xmlpool_options_h = custom_target( + 'xmlpool_options.h', + input : ['gen_xmlpool.py', 't_options.h'], + output : 'options.h', + command : [ + prog_python, '@INPUT0@', '--template', '@INPUT1@', '--output', '@OUTPUT@', + '--localedir', meson.current_build_dir(), '--languages', _langs, + ], + depend_files : _langs_po_files, +) + +i18n = import('i18n') +i18n.gettext('xmlpool', install : false) diff --git a/lib/mesa/src/util/xmlpool/nl.gmo b/lib/mesa/src/util/xmlpool/nl.gmo Binary files differnew file mode 100644 index 000000000..a67fb5a8a --- /dev/null +++ b/lib/mesa/src/util/xmlpool/nl.gmo diff --git a/lib/mesa/src/util/xmlpool/nl.po b/lib/mesa/src/util/xmlpool/nl.po index 86cb6e96d..50a53cc9c 100644 --- a/lib/mesa/src/util/xmlpool/nl.po +++ b/lib/mesa/src/util/xmlpool/nl.po @@ -21,14 +21,6 @@ msgstr "" msgid "Debugging" msgstr "Debuggen" -#: t_options.h:60 -msgid "Disable 3D acceleration" -msgstr "3D versnelling uitschakelen" - -#: t_options.h:65 -msgid "Show performance boxes" -msgstr "Laat prestatie boxjes zien" - #: t_options.h:70 msgid "Enable flushing batchbuffer after each draw call" msgstr "" @@ -53,10 +45,6 @@ msgstr "" msgid "Disable backslash-based line continuations in GLSL source" msgstr "" -#: t_options.h:100 -msgid "Disable GL_ARB_shader_bit_encoding" -msgstr "" - #: t_options.h:105 msgid "" "Force a default GLSL version for shaders that lack an explicit #version line" @@ -70,69 +58,6 @@ msgstr "" msgid "Image Quality" msgstr "Beeldkwaliteit" -#: t_options.h:133 -msgid "Texture color depth" -msgstr "Textuurkleurendiepte" - -#: t_options.h:134 -msgid "Prefer frame buffer color depth" -msgstr "Prefereer kaderbufferkleurdiepte" - -#: t_options.h:135 -msgid "Prefer 32 bits per texel" -msgstr "Prefereer 32 bits per texel" - -#: t_options.h:136 -msgid "Prefer 16 bits per texel" -msgstr "Prefereer 16 bits per texel" - -#: t_options.h:137 -msgid "Force 16 bits per texel" -msgstr "Dwing 16 bits per texel af" - -#: t_options.h:143 -msgid "Initial maximum value for anisotropic texture filtering" -msgstr "Initïele maximum waarde voor anisotrophische textuur filtering" - -#: t_options.h:148 -msgid "Forbid negative texture LOD bias" -msgstr "Verbied negatief niveau detailonderscheid (LOD) van texturen" - -#: t_options.h:153 -msgid "" -"Enable S3TC texture compression even if software support is not available" -msgstr "" -"Schakel S3TC textuurcompressie in, zelfs als softwareondersteuning niet " -"aanwezig is" - -#: t_options.h:160 -msgid "Initial color reduction method" -msgstr "Initïele kleurreductie methode" - -#: t_options.h:161 -msgid "Round colors" -msgstr "Rond kleuren af" - -#: t_options.h:162 -msgid "Dither colors" -msgstr "Rasteriseer kleuren" - -#: t_options.h:170 -msgid "Color rounding method" -msgstr "Kleurafrondingmethode" - -#: t_options.h:171 -msgid "Round color components downward" -msgstr "Rond kleurencomponenten af naar beneden" - -#: t_options.h:172 -msgid "Round to nearest color" -msgstr "Rond af naar dichtsbijzijnde kleur" - -#: t_options.h:181 -msgid "Color dithering method" -msgstr "Kleurrasteriseringsmethode" - #: t_options.h:182 msgid "Horizontal error diffusion" msgstr "Horizontale foutdiffusie" @@ -145,10 +70,6 @@ msgstr "Horizontale foutdiffusie, zet fout bij lijnbegin terug" msgid "Ordered 2D color dithering" msgstr "Geordende 2D kleurrasterisering" -#: t_options.h:190 -msgid "Floating point depth buffer" -msgstr "Dieptebuffer als commagetal" - #: t_options.h:195 msgid "A post-processing filter to cel-shade the output" msgstr "" @@ -181,48 +102,6 @@ msgstr "" msgid "Performance" msgstr "Prestatie" -#: t_options.h:238 -msgid "TCL mode (Transformation, Clipping, Lighting)" -msgstr "TCL-modus (Transformatie, Clipping, Licht)" - -#: t_options.h:239 -msgid "Use software TCL pipeline" -msgstr "Gebruik software TCL pijpleiding" - -#: t_options.h:240 -msgid "Use hardware TCL as first TCL pipeline stage" -msgstr "Gebruik hardware TCL as eerste TCL pijpleiding trap" - -#: t_options.h:241 -msgid "Bypass the TCL pipeline" -msgstr "Omzeil de TCL pijpleiding" - -#: t_options.h:242 -msgid "" -"Bypass the TCL pipeline with state-based machine code generated on-the-fly" -msgstr "" -"Omzeil de TCL pijpleiding met staatgebaseerde machinecode die tijdens " -"executie gegenereerd wordt" - -#: t_options.h:251 -msgid "Method to limit rendering latency" -msgstr "Methode om beeldopbouwvertraging te onderdrukken" - -#: t_options.h:252 -msgid "Busy waiting for the graphics hardware" -msgstr "Actief wachten voor de grafische hardware" - -#: t_options.h:253 -msgid "Sleep for brief intervals while waiting for the graphics hardware" -msgstr "" -"Slaap voor korte intervallen tijdens het wachten op de grafische hardware" - -#: t_options.h:254 -msgid "Let the graphics hardware emit a software interrupt and sleep" -msgstr "" -"Laat de grafische hardware een software onderbreking uitzenden en in slaap " -"vallen" - #: t_options.h:264 msgid "Synchronization with vertical refresh (swap intervals)" msgstr "Synchronisatie met verticale verversing (interval omwisselen)" @@ -249,44 +128,6 @@ msgstr "" "Synchroniseer altijd met verticale verversing, de applicatie kiest het " "minimum omwisselingsinterval" -#: t_options.h:276 -msgid "Use HyperZ to boost performance" -msgstr "Gebruik HyperZ om de prestaties te verbeteren" - -#: t_options.h:281 -msgid "Number of texture units used" -msgstr "Aantal textuureenheden in gebruik" - -#: t_options.h:286 -msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" -msgstr "" -"Textuurfilterkwaliteit versus -snelheid, ookwel bekend als “brilineaire” " -"textuurfiltering" - -#: t_options.h:294 -msgid "Used types of texture memory" -msgstr "Gebruikte soorten textuurgeheugen" - -#: t_options.h:295 -msgid "All available memory" -msgstr "Al het beschikbaar geheugen" - -#: t_options.h:296 -msgid "Only card memory (if available)" -msgstr "Alleen geheugen op de kaart (als het aanwezig is)" - -#: t_options.h:297 -msgid "Only GART (AGP/PCIE) memory (if available)" -msgstr "Alleen GART (AGP/PCIE) geheugen (als het aanwezig is)" - -#: t_options.h:309 -msgid "Features that are not hardware-accelerated" -msgstr "Eigenschappen die niet hardwareversneld zijn" - -#: t_options.h:313 -msgid "Enable extension GL_ARB_vertex_program" -msgstr "Zet uitbreiding GL_ARB_vertex_program aan" - #: t_options.h:323 msgid "Miscellaneous" msgstr "" diff --git a/lib/mesa/src/util/xmlpool/options.h b/lib/mesa/src/util/xmlpool/options.h index ebf969d46..0c3fa9e4a 100644 --- a/lib/mesa/src/util/xmlpool/options.h +++ b/lib/mesa/src/util/xmlpool/options.h @@ -1,6 +1,4 @@ -/*********************************************************************** - *** THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT! *** - ***********************************************************************/ +/* This is file is generated automatically. Don't edit! */ /* * XML DRI client-side driver configuration * Copyright (C) 2003 Felix Kuehling @@ -57,35 +55,13 @@ */ #define DRI_CONF_SECTION_DEBUG \ DRI_CONF_SECTION_BEGIN \ - DRI_CONF_DESC(en,"Debugging") \ - DRI_CONF_DESC(ca,"Depuració") \ - DRI_CONF_DESC(de,"Fehlersuche") \ - DRI_CONF_DESC(es,"Depuración") \ - DRI_CONF_DESC(nl,"Debuggen") \ - DRI_CONF_DESC(fr,"Debogage") \ - DRI_CONF_DESC(sv,"Felsökning") - -#define DRI_CONF_NO_RAST(def) \ -DRI_CONF_OPT_BEGIN_B(no_rast, def) \ - DRI_CONF_DESC(en,"Disable 3D acceleration") \ - DRI_CONF_DESC(ca,"Deshabilita l'acceleració 3D") \ - DRI_CONF_DESC(de,"3D-Beschleunigung abschalten") \ - DRI_CONF_DESC(es,"Deshabilitar aceleración 3D") \ - DRI_CONF_DESC(nl,"3D versnelling uitschakelen") \ - DRI_CONF_DESC(fr,"Désactiver l'accélération 3D") \ - DRI_CONF_DESC(sv,"Inaktivera 3D-accelerering") \ -DRI_CONF_OPT_END - -#define DRI_CONF_PERFORMANCE_BOXES(def) \ -DRI_CONF_OPT_BEGIN_B(performance_boxes, def) \ - DRI_CONF_DESC(en,"Show performance boxes") \ - DRI_CONF_DESC(ca,"Mostra les caixes de rendiment") \ - DRI_CONF_DESC(de,"Zeige Performanceboxen") \ - DRI_CONF_DESC(es,"Mostrar cajas de rendimiento") \ - DRI_CONF_DESC(nl,"Laat prestatie boxjes zien") \ - DRI_CONF_DESC(fr,"Afficher les boîtes de performance") \ - DRI_CONF_DESC(sv,"Visa prestandarutor") \ -DRI_CONF_OPT_END + DRI_CONF_DESC(en,"Debugging") \ + DRI_CONF_DESC(ca,"Depuració") \ + DRI_CONF_DESC(de,"Fehlersuche") \ + DRI_CONF_DESC(es,"Depuración") \ + DRI_CONF_DESC(nl,"Debuggen") \ + DRI_CONF_DESC(fr,"Debogage") \ + DRI_CONF_DESC(sv,"Felsökning") #define DRI_CONF_ALWAYS_FLUSH_BATCH(def) \ DRI_CONF_OPT_BEGIN_B(always_flush_batch, def) \ @@ -111,13 +87,13 @@ DRI_CONF_OPT_END #define DRI_CONF_DISABLE_THROTTLING(def) \ DRI_CONF_OPT_BEGIN_B(disable_throttling, def) \ - DRI_CONF_DESC(en,"Disable throttling on first batch after flush") \ - DRI_CONF_DESC(ca,"Deshabilita la regulació en el primer lot després de buidar") \ - DRI_CONF_DESC(de,"Disable throttling on first batch after flush") \ - DRI_CONF_DESC(es,"Deshabilitar regulación del primer lote después de vaciar") \ - DRI_CONF_DESC(nl,"Disable throttling on first batch after flush") \ - DRI_CONF_DESC(fr,"Disable throttling on first batch after flush") \ - DRI_CONF_DESC(sv,"Disable throttling on first batch after flush") \ + DRI_CONF_DESC(en,"Disable throttling on first batch after flush") \ + DRI_CONF_DESC(ca,"Deshabilita la regulació en el primer lot després de buidar") \ + DRI_CONF_DESC(de,"Disable throttling on first batch after flush") \ + DRI_CONF_DESC(es,"Deshabilitar regulación del primer lote después de vaciar") \ + DRI_CONF_DESC(nl,"Disable throttling on first batch after flush") \ + DRI_CONF_DESC(fr,"Disable throttling on first batch after flush") \ + DRI_CONF_DESC(sv,"Disable throttling on first batch after flush") \ DRI_CONF_OPT_END #define DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(def) \ @@ -164,17 +140,6 @@ DRI_CONF_OPT_BEGIN_B(disable_glsl_line_continuations, def) \ DRI_CONF_DESC(sv,"Disable backslash-based line continuations in GLSL source") \ DRI_CONF_OPT_END -#define DRI_CONF_DISABLE_SHADER_BIT_ENCODING(def) \ -DRI_CONF_OPT_BEGIN_B(disable_shader_bit_encoding, def) \ - DRI_CONF_DESC(en,"Disable GL_ARB_shader_bit_encoding") \ - DRI_CONF_DESC(ca,"Deshabilita el GL_ARB_shader_bit_encoding") \ - DRI_CONF_DESC(de,"Disable GL_ARB_shader_bit_encoding") \ - DRI_CONF_DESC(es,"Deshabilitar GL_ARB_shader_bit_encoding") \ - DRI_CONF_DESC(nl,"Disable GL_ARB_shader_bit_encoding") \ - DRI_CONF_DESC(fr,"Disable GL_ARB_shader_bit_encoding") \ - DRI_CONF_DESC(sv,"Disable GL_ARB_shader_bit_encoding") \ -DRI_CONF_OPT_END - #define DRI_CONF_FORCE_GLSL_VERSION(def) \ DRI_CONF_OPT_BEGIN_V(force_glsl_version, int, def, "0:999") \ DRI_CONF_DESC(en,"Force a default GLSL version for shaders that lack an explicit #version line") \ @@ -197,6 +162,28 @@ DRI_CONF_OPT_BEGIN_B(allow_glsl_extension_directive_midshader, def) \ DRI_CONF_DESC(sv,"Allow GLSL #extension directives in the middle of shaders") \ DRI_CONF_OPT_END +#define DRI_CONF_ALLOW_GLSL_BUILTIN_CONST_EXPRESSION(def) \ +DRI_CONF_OPT_BEGIN_B(allow_glsl_builtin_const_expression, def) \ + DRI_CONF_DESC(en,"Allow builtins as part of constant expressions") \ + DRI_CONF_DESC(ca,"Allow builtins as part of constant expressions") \ + DRI_CONF_DESC(de,"Allow builtins as part of constant expressions") \ + DRI_CONF_DESC(es,"Allow builtins as part of constant expressions") \ + DRI_CONF_DESC(nl,"Allow builtins as part of constant expressions") \ + DRI_CONF_DESC(fr,"Allow builtins as part of constant expressions") \ + DRI_CONF_DESC(sv,"Allow builtins as part of constant expressions") \ +DRI_CONF_OPT_END + +#define DRI_CONF_ALLOW_GLSL_RELAXED_ES(def) \ +DRI_CONF_OPT_BEGIN_B(allow_glsl_relaxed_es, def) \ + DRI_CONF_DESC(en,"Allow some relaxation of GLSL ES shader restrictions") \ + DRI_CONF_DESC(ca,"Allow some relaxation of GLSL ES shader restrictions") \ + DRI_CONF_DESC(de,"Allow some relaxation of GLSL ES shader restrictions") \ + DRI_CONF_DESC(es,"Allow some relaxation of GLSL ES shader restrictions") \ + DRI_CONF_DESC(nl,"Allow some relaxation of GLSL ES shader restrictions") \ + DRI_CONF_DESC(fr,"Allow some relaxation of GLSL ES shader restrictions") \ + DRI_CONF_DESC(sv,"Allow some relaxation of GLSL ES shader restrictions") \ +DRI_CONF_OPT_END + #define DRI_CONF_ALLOW_GLSL_BUILTIN_VARIABLE_REDECLARATION(def) \ DRI_CONF_OPT_BEGIN_B(allow_glsl_builtin_variable_redeclaration, def) \ DRI_CONF_DESC(en,"Allow GLSL built-in variables to be redeclared verbatim") \ @@ -252,95 +239,40 @@ DRI_CONF_OPT_BEGIN_B(allow_glsl_cross_stage_interpolation_mismatch, def) \ DRI_CONF_DESC(sv,"Allow interpolation qualifier mismatch across shader stages") \ DRI_CONF_OPT_END +#define DRI_CONF_ALLOW_GLSL_LAYOUT_QUALIFIER_ON_FUNCTION_PARAMETERS(def) \ +DRI_CONF_OPT_BEGIN_B(allow_glsl_layout_qualifier_on_function_parameters, def) \ + DRI_CONF_DESC(en,"Allow layout qualifiers on function parameters.") \ + DRI_CONF_DESC(ca,"Allow layout qualifiers on function parameters.") \ + DRI_CONF_DESC(de,"Allow layout qualifiers on function parameters.") \ + DRI_CONF_DESC(es,"Allow layout qualifiers on function parameters.") \ + DRI_CONF_DESC(nl,"Allow layout qualifiers on function parameters.") \ + DRI_CONF_DESC(fr,"Allow layout qualifiers on function parameters.") \ + DRI_CONF_DESC(sv,"Allow layout qualifiers on function parameters.") \ +DRI_CONF_OPT_END + +#define DRI_CONF_FORCE_COMPAT_PROFILE(def) \ +DRI_CONF_OPT_BEGIN_B(force_compat_profile, def) \ + DRI_CONF_DESC(en,"Force an OpenGL compatibility context") \ + DRI_CONF_DESC(ca,"Force an OpenGL compatibility context") \ + DRI_CONF_DESC(de,"Force an OpenGL compatibility context") \ + DRI_CONF_DESC(es,"Force an OpenGL compatibility context") \ + DRI_CONF_DESC(nl,"Force an OpenGL compatibility context") \ + DRI_CONF_DESC(fr,"Force an OpenGL compatibility context") \ + DRI_CONF_DESC(sv,"Force an OpenGL compatibility context") \ +DRI_CONF_OPT_END + /** * \brief Image quality-related options */ #define DRI_CONF_SECTION_QUALITY \ DRI_CONF_SECTION_BEGIN \ - DRI_CONF_DESC(en,"Image Quality") \ - DRI_CONF_DESC(ca,"Qualitat d'imatge") \ - DRI_CONF_DESC(de,"Bildqualität") \ - DRI_CONF_DESC(es,"Calidad de imagen") \ - DRI_CONF_DESC(nl,"Beeldkwaliteit") \ - DRI_CONF_DESC(fr,"Qualité d'image") \ - DRI_CONF_DESC(sv,"Bildkvalitet") - -#define DRI_CONF_EXCESS_MIPMAP(def) \ -DRI_CONF_OPT_BEGIN_B(excess_mipmap, def) \ - DRI_CONF_DESC(en,"Enable extra mipmap level") \ -DRI_CONF_OPT_END - -#define DRI_CONF_TEXTURE_DEPTH_FB 0 -#define DRI_CONF_TEXTURE_DEPTH_32 1 -#define DRI_CONF_TEXTURE_DEPTH_16 2 -#define DRI_CONF_TEXTURE_DEPTH_FORCE_16 3 -#define DRI_CONF_TEXTURE_DEPTH(def) \ -DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \ - DRI_CONF_DESC_BEGIN(en,"Texture color depth") \ - DRI_CONF_ENUM(0,"Prefer frame buffer color depth") \ - DRI_CONF_ENUM(1,"Prefer 32 bits per texel") \ - DRI_CONF_ENUM(2,"Prefer 16 bits per texel") \ - DRI_CONF_ENUM(3,"Force 16 bits per texel") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(ca,"Profunditat de color de textura") \ - DRI_CONF_ENUM(0,"Prefereix profunditat de color del framebuffer") \ - DRI_CONF_ENUM(1,"Prefereix 32 bits per texel") \ - DRI_CONF_ENUM(2,"Prefereix 16 bits per texel") \ - DRI_CONF_ENUM(3,"Força 16 bits per texel") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(de,"Texturfarbtiefe") \ - DRI_CONF_ENUM(0,"Bevorzuge Farbtiefe des Framebuffers") \ - DRI_CONF_ENUM(1,"Bevorzuge 32 bits pro Texel") \ - DRI_CONF_ENUM(2,"Bevorzuge 16 bits pro Texel") \ - DRI_CONF_ENUM(3,"Erzwinge 16 bits pro Texel") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(es,"Profundidad de color de textura") \ - DRI_CONF_ENUM(0,"Preferir profundidad de color del framebuffer") \ - DRI_CONF_ENUM(1,"Preferir 32 bits por texel") \ - DRI_CONF_ENUM(2,"Preferir 16 bits por texel") \ - DRI_CONF_ENUM(3,"Forzar a 16 bits por texel") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(nl,"Textuurkleurendiepte") \ - DRI_CONF_ENUM(0,"Prefereer kaderbufferkleurdiepte") \ - DRI_CONF_ENUM(1,"Prefereer 32 bits per texel") \ - DRI_CONF_ENUM(2,"Prefereer 16 bits per texel") \ - DRI_CONF_ENUM(3,"Dwing 16 bits per texel af") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(fr,"Profondeur de texture") \ - DRI_CONF_ENUM(0,"Profondeur de couleur") \ - DRI_CONF_ENUM(1,"Préférer 32 bits par texel") \ - DRI_CONF_ENUM(2,"Prérérer 16 bits par texel") \ - DRI_CONF_ENUM(3,"Forcer 16 bits par texel") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(sv,"Färgdjup för texturer") \ - DRI_CONF_ENUM(0,"Föredra färgdjupet för framebuffer") \ - DRI_CONF_ENUM(1,"Föredra 32 bitar per texel") \ - DRI_CONF_ENUM(2,"Föredra 16 bitar per texel") \ - DRI_CONF_ENUM(3,"Tvinga 16 bitar per texel") \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_DEF_MAX_ANISOTROPY(def,range) \ -DRI_CONF_OPT_BEGIN_V(def_max_anisotropy,float,def,range) \ - DRI_CONF_DESC(en,"Initial maximum value for anisotropic texture filtering") \ - DRI_CONF_DESC(ca,"Valor màxim inicial per a la filtració de textura anisòtropa") \ - DRI_CONF_DESC(de,"Initialer Maximalwert für anisotropische Texturfilterung") \ - DRI_CONF_DESC(es,"Valor máximo inicial para filtrado anisotrópico de textura") \ - DRI_CONF_DESC(nl,"Initïele maximum waarde voor anisotrophische textuur filtering") \ - DRI_CONF_DESC(fr,"Valeur maximale initiale pour le filtrage anisotropique de texture") \ - DRI_CONF_DESC(sv,"Initialt maximalt värde för anisotropisk texturfiltrering") \ -DRI_CONF_OPT_END - -#define DRI_CONF_NO_NEG_LOD_BIAS(def) \ -DRI_CONF_OPT_BEGIN_B(no_neg_lod_bias, def) \ - DRI_CONF_DESC(en,"Forbid negative texture LOD bias") \ - DRI_CONF_DESC(ca,"Prohibeix una parcialitat negativa del Nivell de Detalle (LOD) de les textures") \ - DRI_CONF_DESC(de,"Verbiete negative Textur-Detailgradverschiebung") \ - DRI_CONF_DESC(es,"Prohibir valores negativos de Nivel De Detalle (LOD) de texturas") \ - DRI_CONF_DESC(nl,"Verbied negatief niveau detailonderscheid (LOD) van texturen") \ - DRI_CONF_DESC(fr,"Interdire le LOD bias negatif") \ - DRI_CONF_DESC(sv,"Förbjud negativ LOD-kompensation för texturer") \ -DRI_CONF_OPT_END + DRI_CONF_DESC(en,"Image Quality") \ + DRI_CONF_DESC(ca,"Qualitat d'imatge") \ + DRI_CONF_DESC(de,"Bildqualität") \ + DRI_CONF_DESC(es,"Calidad de imagen") \ + DRI_CONF_DESC(nl,"Beeldkwaliteit") \ + DRI_CONF_DESC(fr,"Qualité d'image") \ + DRI_CONF_DESC(sv,"Bildkvalitet") #define DRI_CONF_PRECISE_TRIG(def) \ DRI_CONF_OPT_BEGIN_B(precise_trig, def) \ @@ -353,127 +285,6 @@ DRI_CONF_OPT_BEGIN_B(precise_trig, def) \ DRI_CONF_DESC(sv,"Prefer accuracy over performance in trig functions") \ DRI_CONF_OPT_END -#define DRI_CONF_COLOR_REDUCTION_ROUND 0 -#define DRI_CONF_COLOR_REDUCTION_DITHER 1 -#define DRI_CONF_COLOR_REDUCTION(def) \ -DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \ - DRI_CONF_DESC_BEGIN(en,"Initial color reduction method") \ - DRI_CONF_ENUM(0,"Round colors") \ - DRI_CONF_ENUM(1,"Dither colors") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(ca,"Mètode inicial de reducció de color") \ - DRI_CONF_ENUM(0,"Colors arrodonits") \ - DRI_CONF_ENUM(1,"Colors tramats") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(de,"Initiale Farbreduktionsmethode") \ - DRI_CONF_ENUM(0,"Farben runden") \ - DRI_CONF_ENUM(1,"Farben rastern") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(es,"Método inicial de reducción de color") \ - DRI_CONF_ENUM(0,"Colores redondeados") \ - DRI_CONF_ENUM(1,"Colores suavizados") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(nl,"Initïele kleurreductie methode") \ - DRI_CONF_ENUM(0,"Rond kleuren af") \ - DRI_CONF_ENUM(1,"Rasteriseer kleuren") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(fr,"Technique de réduction de couleurs") \ - DRI_CONF_ENUM(0,"Arrondir les valeurs de couleur") \ - DRI_CONF_ENUM(1,"Tramer les couleurs") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(sv,"Initial färgminskningsmetod") \ - DRI_CONF_ENUM(0,"Avrunda färger") \ - DRI_CONF_ENUM(1,"Utjämna färger") \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_ROUND_TRUNC 0 -#define DRI_CONF_ROUND_ROUND 1 -#define DRI_CONF_ROUND_MODE(def) \ -DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \ - DRI_CONF_DESC_BEGIN(en,"Color rounding method") \ - DRI_CONF_ENUM(0,"Round color components downward") \ - DRI_CONF_ENUM(1,"Round to nearest color") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(ca,"Mètode d'arrodoniment de color") \ - DRI_CONF_ENUM(0,"Arrodoneix els components de color a baix") \ - DRI_CONF_ENUM(1,"Arrodoneix al color més proper") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(de,"Farbrundungsmethode") \ - DRI_CONF_ENUM(0,"Farbkomponenten abrunden") \ - DRI_CONF_ENUM(1,"Zur ähnlichsten Farbe runden") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(es,"Método de redondeo de colores") \ - DRI_CONF_ENUM(0,"Redondear hacia abajo los componentes de color") \ - DRI_CONF_ENUM(1,"Redondear al color más cercano") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(nl,"Kleurafrondingmethode") \ - DRI_CONF_ENUM(0,"Rond kleurencomponenten af naar beneden") \ - DRI_CONF_ENUM(1,"Rond af naar dichtsbijzijnde kleur") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(fr,"Méthode d'arrondi des couleurs") \ - DRI_CONF_ENUM(0,"Arrondi à l'inférieur") \ - DRI_CONF_ENUM(1,"Arrondi au plus proche") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(sv,"Färgavrundningsmetod") \ - DRI_CONF_ENUM(0,"Avrunda färdkomponenter nedåt") \ - DRI_CONF_ENUM(1,"Avrunda till närmsta färg") \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_DITHER_XERRORDIFF 0 -#define DRI_CONF_DITHER_XERRORDIFFRESET 1 -#define DRI_CONF_DITHER_ORDERED 2 -#define DRI_CONF_DITHER_MODE(def) \ -DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \ - DRI_CONF_DESC_BEGIN(en,"Color dithering method") \ - DRI_CONF_ENUM(0,"Horizontal error diffusion") \ - DRI_CONF_ENUM(1,"Horizontal error diffusion, reset error at line start") \ - DRI_CONF_ENUM(2,"Ordered 2D color dithering") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(ca,"Mètode de tramat de color") \ - DRI_CONF_ENUM(0,"Difusió d'error horitzontal") \ - DRI_CONF_ENUM(1,"Difusió d'error horitzontal, reinicia l'error a l'inici de la línia") \ - DRI_CONF_ENUM(2,"Tramat de color 2D ordenat") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(de,"Farbrasterungsmethode") \ - DRI_CONF_ENUM(0,"Horizontale Fehlerstreuung") \ - DRI_CONF_ENUM(1,"Horizontale Fehlerstreuung, Fehler am Zeilenanfang zurücksetzen") \ - DRI_CONF_ENUM(2,"Geordnete 2D Farbrasterung") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(es,"Método de suavizado de color") \ - DRI_CONF_ENUM(0,"Difusión de error horizontal") \ - DRI_CONF_ENUM(1,"Difusión de error horizontal, reiniciar error al comienzo de línea") \ - DRI_CONF_ENUM(2,"Suavizado de color 2D ordenado") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(nl,"Kleurrasteriseringsmethode") \ - DRI_CONF_ENUM(0,"Horizontale foutdiffusie") \ - DRI_CONF_ENUM(1,"Horizontale foutdiffusie, zet fout bij lijnbegin terug") \ - DRI_CONF_ENUM(2,"Geordende 2D kleurrasterisering") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(fr,"Méthode de tramage") \ - DRI_CONF_ENUM(0,"Diffusion d'erreur horizontale") \ - DRI_CONF_ENUM(1,"Diffusion d'erreur horizontale, réinitialisé pour chaque ligne") \ - DRI_CONF_ENUM(2,"Tramage ordonné des couleurs") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(sv,"Färgutjämningsmetod") \ - DRI_CONF_ENUM(0,"Horisontell felspridning") \ - DRI_CONF_ENUM(1,"Horisontell felspridning, återställ fel vid radbörjan") \ - DRI_CONF_ENUM(2,"Ordnad 2D-färgutjämning") \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_FLOAT_DEPTH(def) \ -DRI_CONF_OPT_BEGIN_B(float_depth, def) \ - DRI_CONF_DESC(en,"Floating point depth buffer") \ - DRI_CONF_DESC(ca,"Buffer de profunditat de punt flotant") \ - DRI_CONF_DESC(de,"Fließkomma z-Puffer") \ - DRI_CONF_DESC(es,"Búfer de profundidad en coma flotante") \ - DRI_CONF_DESC(nl,"Dieptebuffer als commagetal") \ - DRI_CONF_DESC(fr,"Z-buffer en virgule flottante") \ - DRI_CONF_DESC(sv,"Buffert för flytande punktdjup") \ -DRI_CONF_OPT_END - #define DRI_CONF_PP_CELSHADE(def) \ DRI_CONF_OPT_BEGIN_V(pp_celshade,enum,def,"0:1") \ DRI_CONF_DESC(en,"A post-processing filter to cel-shade the output") \ @@ -555,98 +366,6 @@ DRI_CONF_SECTION_BEGIN \ DRI_CONF_DESC(fr,"Performance") \ DRI_CONF_DESC(sv,"Prestanda") -#define DRI_CONF_TCL_SW 0 -#define DRI_CONF_TCL_PIPELINED 1 -#define DRI_CONF_TCL_VTXFMT 2 -#define DRI_CONF_TCL_CODEGEN 3 -#define DRI_CONF_TCL_MODE(def) \ -DRI_CONF_OPT_BEGIN_V(tcl_mode,enum,def,"0:3") \ - DRI_CONF_DESC_BEGIN(en,"TCL mode (Transformation, Clipping, Lighting)") \ - DRI_CONF_ENUM(0,"Use software TCL pipeline") \ - DRI_CONF_ENUM(1,"Use hardware TCL as first TCL pipeline stage") \ - DRI_CONF_ENUM(2,"Bypass the TCL pipeline") \ - DRI_CONF_ENUM(3,"Bypass the TCL pipeline with state-based machine code generated on-the-fly") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(ca,"Mode TCL (Transformació, Retall, Il·luminació)") \ - DRI_CONF_ENUM(0,"Utilitza la canonada TCL de programari") \ - DRI_CONF_ENUM(1,"Utilitza el TCL de maquinari com a la primera fase de la canonada TCL") \ - DRI_CONF_ENUM(2,"Passa per alt la canonada TCL") \ - DRI_CONF_ENUM(3,"Passa per alt la canonada TCL amb codi de màquina basat en estats, generat sobre la marxa") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(de,"TCL-Modus (Transformation, Clipping, Licht)") \ - DRI_CONF_ENUM(0,"Benutze die Software-TCL-Pipeline") \ - DRI_CONF_ENUM(1,"Benutze Hardware TCL als erste Stufe der TCL-Pipeline") \ - DRI_CONF_ENUM(2,"Umgehe die TCL-Pipeline") \ - DRI_CONF_ENUM(3,"Umgehe die TCL-Pipeline mit zur Laufzeit erzeugtem, zustandsbasiertem Maschinencode") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(es,"Modo TCL (Transformación, Recorte, Iluminación)") \ - DRI_CONF_ENUM(0,"Usar tubería TCL por software") \ - DRI_CONF_ENUM(1,"Usar TCL por hardware en la primera fase de la tubería TCL") \ - DRI_CONF_ENUM(2,"Pasar por alto la tubería TCL") \ - DRI_CONF_ENUM(3,"Pasar por alto la tubería TCL con código máquina basado en estados, generado al vuelo") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(nl,"TCL-modus (Transformatie, Clipping, Licht)") \ - DRI_CONF_ENUM(0,"Gebruik software TCL pijpleiding") \ - DRI_CONF_ENUM(1,"Gebruik hardware TCL as eerste TCL pijpleiding trap") \ - DRI_CONF_ENUM(2,"Omzeil de TCL pijpleiding") \ - DRI_CONF_ENUM(3,"Omzeil de TCL pijpleiding met staatgebaseerde machinecode die tijdens executie gegenereerd wordt") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(fr,"Mode de TCL (Transformation, Clipping, Eclairage)") \ - DRI_CONF_ENUM(0,"Utiliser un pipeline TCL logiciel") \ - DRI_CONF_ENUM(1,"Utiliser le TCL matériel pour le premier niveau de pipeline") \ - DRI_CONF_ENUM(2,"Court-circuiter le pipeline TCL") \ - DRI_CONF_ENUM(3,"Court-circuiter le pipeline TCL par une machine à états qui génère le codede TCL à la volée") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(sv,"TCL-läge (Transformation, Clipping, Lighting)") \ - DRI_CONF_ENUM(0,"Använd programvaru-TCL-rörledning") \ - DRI_CONF_ENUM(1,"Använd maskinvaru-TCL som första TCL-rörledningssteg") \ - DRI_CONF_ENUM(2,"Kringgå TCL-rörledningen") \ - DRI_CONF_ENUM(3,"Kringgå TCL-rörledningen med tillståndsbaserad maskinkod som direktgenereras") \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_FTHROTTLE_BUSY 0 -#define DRI_CONF_FTHROTTLE_USLEEPS 1 -#define DRI_CONF_FTHROTTLE_IRQS 2 -#define DRI_CONF_FTHROTTLE_MODE(def) \ -DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \ - DRI_CONF_DESC_BEGIN(en,"Method to limit rendering latency") \ - DRI_CONF_ENUM(0,"Busy waiting for the graphics hardware") \ - DRI_CONF_ENUM(1,"Sleep for brief intervals while waiting for the graphics hardware") \ - DRI_CONF_ENUM(2,"Let the graphics hardware emit a software interrupt and sleep") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(ca,"Mètode per a limitar la latència de renderització") \ - DRI_CONF_ENUM(0,"Espera activa pel maquinari de gràfics") \ - DRI_CONF_ENUM(1,"Dorm per intervals breus mentre s'espera al maquinari de gràfics") \ - DRI_CONF_ENUM(2,"Deixa que el maquinari de gràfics emeti una interrupció de programari i dormi") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(de,"Methode zur Begrenzung der Bildverzögerung") \ - DRI_CONF_ENUM(0,"Aktives Warten auf die Grafikhardware") \ - DRI_CONF_ENUM(1,"Kurze Schlafintervalle beim Warten auf die Grafikhardware") \ - DRI_CONF_ENUM(2,"Die Grafikhardware eine Softwareunterbrechnung erzeugen lassen und schlafen") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(es,"Método para limitar la latencia de renderización") \ - DRI_CONF_ENUM(0,"Esperar activamente al hardware gráfico") \ - DRI_CONF_ENUM(1,"Dormir en intervalos cortos mientras se espera al hardware gráfico") \ - DRI_CONF_ENUM(2,"Permitir que el hardware gráfico emita una interrupción de software y duerma") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(nl,"Methode om beeldopbouwvertraging te onderdrukken") \ - DRI_CONF_ENUM(0,"Actief wachten voor de grafische hardware") \ - DRI_CONF_ENUM(1,"Slaap voor korte intervallen tijdens het wachten op de grafische hardware") \ - DRI_CONF_ENUM(2,"Laat de grafische hardware een software onderbreking uitzenden en in slaap vallen") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(fr,"Méthode d'attente de la carte graphique") \ - DRI_CONF_ENUM(0,"Attente active de la carte graphique") \ - DRI_CONF_ENUM(1,"Attente utilisant usleep()") \ - DRI_CONF_ENUM(2,"Utiliser les interruptions") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(sv,"Metod för att begränsa renderingslatens") \ - DRI_CONF_ENUM(0,"Upptagen med att vänta på grafikhårdvaran") \ - DRI_CONF_ENUM(1,"Sov i korta intervall under väntan på grafikhårdvaran") \ - DRI_CONF_ENUM(2,"Låt grafikhårdvaran sända ut ett programvaruavbrott och sov") \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - #define DRI_CONF_VBLANK_NEVER 0 #define DRI_CONF_VBLANK_DEF_INTERVAL_0 1 #define DRI_CONF_VBLANK_DEF_INTERVAL_1 2 @@ -697,83 +416,6 @@ DRI_CONF_OPT_BEGIN_V(vblank_mode,enum,def,"0:3") \ DRI_CONF_DESC_END \ DRI_CONF_OPT_END -#define DRI_CONF_HYPERZ_DISABLED 0 -#define DRI_CONF_HYPERZ_ENABLED 1 -#define DRI_CONF_HYPERZ(def) \ -DRI_CONF_OPT_BEGIN_B(hyperz, def) \ - DRI_CONF_DESC(en,"Use HyperZ to boost performance") \ - DRI_CONF_DESC(ca,"Utilitza el HyperZ per a augmentar el rendiment") \ - DRI_CONF_DESC(de,"HyperZ zur Leistungssteigerung verwenden") \ - DRI_CONF_DESC(es,"Usar HyperZ para potenciar rendimiento") \ - DRI_CONF_DESC(nl,"Gebruik HyperZ om de prestaties te verbeteren") \ - DRI_CONF_DESC(fr,"Utiliser le HyperZ pour améliorer les performances") \ - DRI_CONF_DESC(sv,"Använd HyperZ för att maximera prestandan") \ -DRI_CONF_OPT_END - -#define DRI_CONF_MAX_TEXTURE_UNITS(def,min,max) \ -DRI_CONF_OPT_BEGIN_V(texture_units,int,def, # min ":" # max ) \ - DRI_CONF_DESC(en,"Number of texture units used") \ - DRI_CONF_DESC(ca,"Nombre d'unitats de textura utilitzades") \ - DRI_CONF_DESC(de,"Anzahl der benutzten Textureinheiten") \ - DRI_CONF_DESC(es,"Número de unidades de textura usadas") \ - DRI_CONF_DESC(nl,"Aantal textuureenheden in gebruik") \ - DRI_CONF_DESC(fr,"Nombre d'unités de texture") \ - DRI_CONF_DESC(sv,"Antal använda texturenheter") \ -DRI_CONF_OPT_END - -#define DRI_CONF_TEXTURE_BLEND_QUALITY(def,range) \ -DRI_CONF_OPT_BEGIN_V(texture_blend_quality,float,def,range) \ - DRI_CONF_DESC(en,"Texture filtering quality vs. speed, AKA “brilinear” texture filtering") \ - DRI_CONF_DESC(ca,"Qualitat vs. velocitat de filtració de textura, àlies filtració ”brilinear“ de textura") \ - DRI_CONF_DESC(de,"Texturfilterqualität versus -geschwindigkeit, auch bekannt als „brilineare“ Texturfilterung") \ - DRI_CONF_DESC(es,"Calidad de filtrado de textura vs. velocidad, alias filtrado ”brilinear“ de textura") \ - DRI_CONF_DESC(nl,"Textuurfilterkwaliteit versus -snelheid, ookwel bekend als “brilineaire” textuurfiltering") \ - DRI_CONF_DESC(fr,"Qualité/performance du filtrage trilinéaire de texture (filtrage brilinéaire)") \ - DRI_CONF_DESC(sv,"Texturfiltreringskvalitet mot hastighet, även kallad ”brilinear”-texturfiltrering") \ -DRI_CONF_OPT_END - -#define DRI_CONF_TEXTURE_HEAPS_ALL 0 -#define DRI_CONF_TEXTURE_HEAPS_CARD 1 -#define DRI_CONF_TEXTURE_HEAPS_GART 2 -#define DRI_CONF_TEXTURE_HEAPS(def) \ -DRI_CONF_OPT_BEGIN_V(texture_heaps,enum,def,"0:2") \ - DRI_CONF_DESC_BEGIN(en,"Used types of texture memory") \ - DRI_CONF_ENUM(0,"All available memory") \ - DRI_CONF_ENUM(1,"Only card memory (if available)") \ - DRI_CONF_ENUM(2,"Only GART (AGP/PCIE) memory (if available)") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(ca,"Tipus utilitzats de memòria de textura") \ - DRI_CONF_ENUM(0,"Tota la memòria disponible") \ - DRI_CONF_ENUM(1,"Només memòria de targeta (si està disponible)") \ - DRI_CONF_ENUM(2,"Només memòria GART (AGP/PCIE) (si està disponible)") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(de,"Benutzte Arten von Texturspeicher") \ - DRI_CONF_ENUM(0,"Aller verfügbarer Speicher") \ - DRI_CONF_ENUM(1,"Nur Grafikspeicher (falls verfügbar)") \ - DRI_CONF_ENUM(2,"Nur GART-Speicher (AGP/PCIE) (falls verfügbar)") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(es,"Tipos de memoria de textura usados") \ - DRI_CONF_ENUM(0,"Toda la memoria disponible") \ - DRI_CONF_ENUM(1,"Solo memoria de tarjeta (si está disponible)") \ - DRI_CONF_ENUM(2,"Solo memoria GART (AGP/PCIE) (si está disponible)") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(nl,"Gebruikte soorten textuurgeheugen") \ - DRI_CONF_ENUM(0,"Al het beschikbaar geheugen") \ - DRI_CONF_ENUM(1,"Alleen geheugen op de kaart (als het aanwezig is)") \ - DRI_CONF_ENUM(2,"Alleen GART (AGP/PCIE) geheugen (als het aanwezig is)") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(fr,"Types de mémoire de texture") \ - DRI_CONF_ENUM(0,"Utiliser toute la mémoire disponible") \ - DRI_CONF_ENUM(1,"Utiliser uniquement la mémoire graphique (si disponible)") \ - DRI_CONF_ENUM(2,"Utiliser uniquement la mémoire GART (AGP/PCIE) (si disponible)") \ - DRI_CONF_DESC_END \ - DRI_CONF_DESC_BEGIN(sv,"Använda typer av texturminne") \ - DRI_CONF_ENUM(0,"Allt tillgängligt minne") \ - DRI_CONF_ENUM(1,"Endast kortminne (om tillgängligt)") \ - DRI_CONF_ENUM(2,"Endast GART-minne (AGP/PCIE) (om tillgängligt)") \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - #define DRI_CONF_MESA_GLTHREAD(def) \ DRI_CONF_OPT_BEGIN_B(mesa_glthread, def) \ DRI_CONF_DESC(en,"Enable offloading GL driver work to a separate thread") \ @@ -818,30 +460,15 @@ DRI_CONF_OPT_BEGIN_B(glx_disable_oml_sync_control, def) \ DRI_CONF_DESC(sv, "Disable the GLX_OML_sync_control extension") \ DRI_CONF_OPT_END - -/** - * \brief Software-fallback options. To allow using features (like - * GL_ARB_vertex_program) on GPUs that don't otherwise support the feature. - */ -#define DRI_CONF_SECTION_SOFTWARE \ -DRI_CONF_SECTION_BEGIN \ - DRI_CONF_DESC(en,"Features that are not hardware-accelerated") \ - DRI_CONF_DESC(ca,"Característiques no accelerades per maquinari") \ - DRI_CONF_DESC(de,"Funktionalität, die nicht hardwarebeschleunigt ist") \ - DRI_CONF_DESC(es,"Características no aceleradas por hardware") \ - DRI_CONF_DESC(nl,"Eigenschappen die niet hardwareversneld zijn") \ - DRI_CONF_DESC(fr,"Fonctionnalités ne bénéficiant pas d'une accélération matérielle") \ - DRI_CONF_DESC(sv,"Funktioner som inte är hårdvaruaccelererade") - -#define DRI_CONF_ARB_VERTEX_PROGRAM(def) \ -DRI_CONF_OPT_BEGIN_B(arb_vertex_program, def) \ - DRI_CONF_DESC(en,"Enable extension GL_ARB_vertex_program") \ - DRI_CONF_DESC(ca,"Habilita l'extensió GL_ARB_vertex_program") \ - DRI_CONF_DESC(de,"Erweiterung GL_ARB_vertex_program aktivieren") \ - DRI_CONF_DESC(es,"Habilitar la extensión GL_ARB_vertex_program") \ - DRI_CONF_DESC(nl,"Zet uitbreiding GL_ARB_vertex_program aan") \ - DRI_CONF_DESC(fr,"Activer l'extension GL_ARB_vertex_program") \ - DRI_CONF_DESC(sv,"Aktivera tillägget GL_ARB_vertex_program") \ +#define DRI_CONF_DISABLE_SGI_VIDEO_SYNC(def) \ +DRI_CONF_OPT_BEGIN_B(glx_disable_sgi_video_sync, def) \ + DRI_CONF_DESC(en, "Disable the GLX_SGI_video_sync extension") \ + DRI_CONF_DESC(ca, "Disable the GLX_SGI_video_sync extension") \ + DRI_CONF_DESC(de, "Disable the GLX_SGI_video_sync extension") \ + DRI_CONF_DESC(es, "Disable the GLX_SGI_video_sync extension") \ + DRI_CONF_DESC(nl, "Disable the GLX_SGI_video_sync extension") \ + DRI_CONF_DESC(fr, "Disable the GLX_SGI_video_sync extension") \ + DRI_CONF_DESC(sv, "Disable the GLX_SGI_video_sync extension") \ DRI_CONF_OPT_END @@ -881,6 +508,17 @@ DRI_CONF_OPT_BEGIN_B(glsl_zero_init, def) \ DRI_CONF_DESC(sv,"Force uninitialized variables to default to zero") \ DRI_CONF_OPT_END +#define DRI_CONF_ALLOW_RGB10_CONFIGS(def) \ +DRI_CONF_OPT_BEGIN_B(allow_rgb10_configs, def) \ +DRI_CONF_DESC(en,"Allow exposure of visuals and fbconfigs with rgb10a2 formats") \ +DRI_CONF_DESC(ca,"Allow exposure of visuals and fbconfigs with rgb10a2 formats") \ +DRI_CONF_DESC(de,"Allow exposure of visuals and fbconfigs with rgb10a2 formats") \ +DRI_CONF_DESC(es,"Allow exposure of visuals and fbconfigs with rgb10a2 formats") \ +DRI_CONF_DESC(nl,"Allow exposure of visuals and fbconfigs with rgb10a2 formats") \ +DRI_CONF_DESC(fr,"Allow exposure of visuals and fbconfigs with rgb10a2 formats") \ +DRI_CONF_DESC(sv,"Allow exposure of visuals and fbconfigs with rgb10a2 formats") \ +DRI_CONF_OPT_END + /** * \brief Initialization configuration options */ @@ -905,6 +543,17 @@ DRI_CONF_OPT_BEGIN(device_id, string, def) \ DRI_CONF_DESC(sv,"Define the graphic device to use if possible") \ DRI_CONF_OPT_END +#define DRI_CONF_DRI_DRIVER(def) \ +DRI_CONF_OPT_BEGIN(dri_driver, string, def) \ + DRI_CONF_DESC(en,"Override the DRI driver to load") \ + DRI_CONF_DESC(ca,"Override the DRI driver to load") \ + DRI_CONF_DESC(de,"Override the DRI driver to load") \ + DRI_CONF_DESC(es,"Override the DRI driver to load") \ + DRI_CONF_DESC(nl,"Override the DRI driver to load") \ + DRI_CONF_DESC(fr,"Override the DRI driver to load") \ + DRI_CONF_DESC(sv,"Override the DRI driver to load") \ +DRI_CONF_OPT_END + /** * \brief Gallium-Nine specific configuration options */ @@ -1026,3 +675,8 @@ DRI_CONF_OPT_END DRI_CONF_OPT_BEGIN_B(radeonsi_clear_db_cache_before_clear, def) \ DRI_CONF_DESC(en,"Clear DB cache before fast depth clear") \ DRI_CONF_OPT_END + +#define DRI_CONF_RADEONSI_ZERO_ALL_VRAM_ALLOCS(def) \ +DRI_CONF_OPT_BEGIN_B(radeonsi_zerovram, def) \ + DRI_CONF_DESC(en,"Zero all vram allocations") \ +DRI_CONF_OPT_END diff --git a/lib/mesa/src/util/xmlpool/sv.gmo b/lib/mesa/src/util/xmlpool/sv.gmo Binary files differnew file mode 100644 index 000000000..8393f427e --- /dev/null +++ b/lib/mesa/src/util/xmlpool/sv.gmo diff --git a/lib/mesa/src/util/xmlpool/sv.po b/lib/mesa/src/util/xmlpool/sv.po index d8d7353f4..36e5a9b65 100644 --- a/lib/mesa/src/util/xmlpool/sv.po +++ b/lib/mesa/src/util/xmlpool/sv.po @@ -21,14 +21,6 @@ msgstr "" msgid "Debugging" msgstr "Felsökning" -#: t_options.h:60 -msgid "Disable 3D acceleration" -msgstr "Inaktivera 3D-accelerering" - -#: t_options.h:65 -msgid "Show performance boxes" -msgstr "Visa prestandarutor" - #: t_options.h:70 msgid "Enable flushing batchbuffer after each draw call" msgstr "" @@ -53,10 +45,6 @@ msgstr "" msgid "Disable backslash-based line continuations in GLSL source" msgstr "" -#: t_options.h:100 -msgid "Disable GL_ARB_shader_bit_encoding" -msgstr "" - #: t_options.h:105 msgid "" "Force a default GLSL version for shaders that lack an explicit #version line" @@ -70,63 +58,6 @@ msgstr "" msgid "Image Quality" msgstr "Bildkvalitet" -#: t_options.h:133 -msgid "Texture color depth" -msgstr "Färgdjup för texturer" - -#: t_options.h:134 -msgid "Prefer frame buffer color depth" -msgstr "Föredra färgdjupet för framebuffer" - -#: t_options.h:135 -msgid "Prefer 32 bits per texel" -msgstr "Föredra 32 bitar per texel" - -#: t_options.h:136 -msgid "Prefer 16 bits per texel" -msgstr "Föredra 16 bitar per texel" - -#: t_options.h:137 -msgid "Force 16 bits per texel" -msgstr "Tvinga 16 bitar per texel" - -#: t_options.h:143 -msgid "Initial maximum value for anisotropic texture filtering" -msgstr "Initialt maximalt värde för anisotropisk texturfiltrering" - -#: t_options.h:148 -msgid "Forbid negative texture LOD bias" -msgstr "Förbjud negativ LOD-kompensation för texturer" - -#: t_options.h:153 -msgid "" -"Enable S3TC texture compression even if software support is not available" -msgstr "Aktivera S3TC-texturkomprimering även om programvarustöd saknas" - -#: t_options.h:160 -msgid "Initial color reduction method" -msgstr "Initial färgminskningsmetod" - -#: t_options.h:161 -msgid "Round colors" -msgstr "Avrunda färger" - -#: t_options.h:162 -msgid "Dither colors" -msgstr "Utjämna färger" - -#: t_options.h:170 -msgid "Color rounding method" -msgstr "Färgavrundningsmetod" - -#: t_options.h:171 -msgid "Round color components downward" -msgstr "Avrunda färdkomponenter nedåt" - -#: t_options.h:172 -msgid "Round to nearest color" -msgstr "Avrunda till närmsta färg" - #: t_options.h:181 msgid "Color dithering method" msgstr "Färgutjämningsmetod" @@ -143,10 +74,6 @@ msgstr "Horisontell felspridning, återställ fel vid radbörjan" msgid "Ordered 2D color dithering" msgstr "Ordnad 2D-färgutjämning" -#: t_options.h:190 -msgid "Floating point depth buffer" -msgstr "Buffert för flytande punktdjup" - #: t_options.h:195 msgid "A post-processing filter to cel-shade the output" msgstr "" @@ -179,44 +106,6 @@ msgstr "" msgid "Performance" msgstr "Prestanda" -#: t_options.h:238 -msgid "TCL mode (Transformation, Clipping, Lighting)" -msgstr "TCL-läge (Transformation, Clipping, Lighting)" - -#: t_options.h:239 -msgid "Use software TCL pipeline" -msgstr "Använd programvaru-TCL-rörledning" - -#: t_options.h:240 -msgid "Use hardware TCL as first TCL pipeline stage" -msgstr "Använd maskinvaru-TCL som första TCL-rörledningssteg" - -#: t_options.h:241 -msgid "Bypass the TCL pipeline" -msgstr "Kringgå TCL-rörledningen" - -#: t_options.h:242 -msgid "" -"Bypass the TCL pipeline with state-based machine code generated on-the-fly" -msgstr "" -"Kringgå TCL-rörledningen med tillståndsbaserad maskinkod som direktgenereras" - -#: t_options.h:251 -msgid "Method to limit rendering latency" -msgstr "Metod för att begränsa renderingslatens" - -#: t_options.h:252 -msgid "Busy waiting for the graphics hardware" -msgstr "Upptagen med att vänta på grafikhårdvaran" - -#: t_options.h:253 -msgid "Sleep for brief intervals while waiting for the graphics hardware" -msgstr "Sov i korta intervall under väntan på grafikhårdvaran" - -#: t_options.h:254 -msgid "Let the graphics hardware emit a software interrupt and sleep" -msgstr "Låt grafikhårdvaran sända ut ett programvaruavbrott och sov" - #: t_options.h:264 msgid "Synchronization with vertical refresh (swap intervals)" msgstr "Synkronisering med vertikal uppdatering (växlingsintervall)" @@ -241,44 +130,6 @@ msgstr "" "Synkronisera alltid med vertikal uppdatering, programmet väljer den minsta " "växlingsintervallen" -#: t_options.h:276 -msgid "Use HyperZ to boost performance" -msgstr "Använd HyperZ för att maximera prestandan" - -#: t_options.h:281 -msgid "Number of texture units used" -msgstr "Antal använda texturenheter" - -#: t_options.h:286 -msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" -msgstr "" -"Texturfiltreringskvalitet mot hastighet, även kallad \"brilinear\"-" -"texturfiltrering" - -#: t_options.h:294 -msgid "Used types of texture memory" -msgstr "Använda typer av texturminne" - -#: t_options.h:295 -msgid "All available memory" -msgstr "Allt tillgängligt minne" - -#: t_options.h:296 -msgid "Only card memory (if available)" -msgstr "Endast kortminne (om tillgängligt)" - -#: t_options.h:297 -msgid "Only GART (AGP/PCIE) memory (if available)" -msgstr "Endast GART-minne (AGP/PCIE) (om tillgängligt)" - -#: t_options.h:309 -msgid "Features that are not hardware-accelerated" -msgstr "Funktioner som inte är hårdvaruaccelererade" - -#: t_options.h:313 -msgid "Enable extension GL_ARB_vertex_program" -msgstr "Aktivera tillägget GL_ARB_vertex_program" - #: t_options.h:323 msgid "Miscellaneous" msgstr "" diff --git a/lib/mesa/src/util/xmlpool/t_options.h b/lib/mesa/src/util/xmlpool/t_options.h index bd553085c..e0a30f5fd 100644 --- a/lib/mesa/src/util/xmlpool/t_options.h +++ b/lib/mesa/src/util/xmlpool/t_options.h @@ -53,17 +53,7 @@ */ #define DRI_CONF_SECTION_DEBUG \ DRI_CONF_SECTION_BEGIN \ - DRI_CONF_DESC(en,gettext("Debugging")) - -#define DRI_CONF_NO_RAST(def) \ -DRI_CONF_OPT_BEGIN_B(no_rast, def) \ - DRI_CONF_DESC(en,gettext("Disable 3D acceleration")) \ -DRI_CONF_OPT_END - -#define DRI_CONF_PERFORMANCE_BOXES(def) \ -DRI_CONF_OPT_BEGIN_B(performance_boxes, def) \ - DRI_CONF_DESC(en,gettext("Show performance boxes")) \ -DRI_CONF_OPT_END + DRI_CONF_DESC(en,gettext("Debugging")) #define DRI_CONF_ALWAYS_FLUSH_BATCH(def) \ DRI_CONF_OPT_BEGIN_B(always_flush_batch, def) \ @@ -77,7 +67,7 @@ DRI_CONF_OPT_END #define DRI_CONF_DISABLE_THROTTLING(def) \ DRI_CONF_OPT_BEGIN_B(disable_throttling, def) \ - DRI_CONF_DESC(en,gettext("Disable throttling on first batch after flush")) \ + DRI_CONF_DESC(en,gettext("Disable throttling on first batch after flush")) \ DRI_CONF_OPT_END #define DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(def) \ @@ -100,11 +90,6 @@ DRI_CONF_OPT_BEGIN_B(disable_glsl_line_continuations, def) \ DRI_CONF_DESC(en,gettext("Disable backslash-based line continuations in GLSL source")) \ DRI_CONF_OPT_END -#define DRI_CONF_DISABLE_SHADER_BIT_ENCODING(def) \ -DRI_CONF_OPT_BEGIN_B(disable_shader_bit_encoding, def) \ - DRI_CONF_DESC(en,gettext("Disable GL_ARB_shader_bit_encoding")) \ -DRI_CONF_OPT_END - #define DRI_CONF_FORCE_GLSL_VERSION(def) \ DRI_CONF_OPT_BEGIN_V(force_glsl_version, int, def, "0:999") \ DRI_CONF_DESC(en,gettext("Force a default GLSL version for shaders that lack an explicit #version line")) \ @@ -115,6 +100,16 @@ DRI_CONF_OPT_BEGIN_B(allow_glsl_extension_directive_midshader, def) \ DRI_CONF_DESC(en,gettext("Allow GLSL #extension directives in the middle of shaders")) \ DRI_CONF_OPT_END +#define DRI_CONF_ALLOW_GLSL_BUILTIN_CONST_EXPRESSION(def) \ +DRI_CONF_OPT_BEGIN_B(allow_glsl_builtin_const_expression, def) \ + DRI_CONF_DESC(en,gettext("Allow builtins as part of constant expressions")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_ALLOW_GLSL_RELAXED_ES(def) \ +DRI_CONF_OPT_BEGIN_B(allow_glsl_relaxed_es, def) \ + DRI_CONF_DESC(en,gettext("Allow some relaxation of GLSL ES shader restrictions")) \ +DRI_CONF_OPT_END + #define DRI_CONF_ALLOW_GLSL_BUILTIN_VARIABLE_REDECLARATION(def) \ DRI_CONF_OPT_BEGIN_B(allow_glsl_builtin_variable_redeclaration, def) \ DRI_CONF_DESC(en,gettext("Allow GLSL built-in variables to be redeclared verbatim")) \ @@ -140,84 +135,28 @@ DRI_CONF_OPT_BEGIN_B(allow_glsl_cross_stage_interpolation_mismatch, def) \ DRI_CONF_DESC(en,gettext("Allow interpolation qualifier mismatch across shader stages")) \ DRI_CONF_OPT_END +#define DRI_CONF_ALLOW_GLSL_LAYOUT_QUALIFIER_ON_FUNCTION_PARAMETERS(def) \ +DRI_CONF_OPT_BEGIN_B(allow_glsl_layout_qualifier_on_function_parameters, def) \ + DRI_CONF_DESC(en,gettext("Allow layout qualifiers on function parameters.")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_FORCE_COMPAT_PROFILE(def) \ +DRI_CONF_OPT_BEGIN_B(force_compat_profile, def) \ + DRI_CONF_DESC(en,gettext("Force an OpenGL compatibility context")) \ +DRI_CONF_OPT_END + /** * \brief Image quality-related options */ #define DRI_CONF_SECTION_QUALITY \ DRI_CONF_SECTION_BEGIN \ - DRI_CONF_DESC(en,gettext("Image Quality")) - -#define DRI_CONF_EXCESS_MIPMAP(def) \ -DRI_CONF_OPT_BEGIN_B(excess_mipmap, def) \ - DRI_CONF_DESC(en,"Enable extra mipmap level") \ -DRI_CONF_OPT_END - -#define DRI_CONF_TEXTURE_DEPTH_FB 0 -#define DRI_CONF_TEXTURE_DEPTH_32 1 -#define DRI_CONF_TEXTURE_DEPTH_16 2 -#define DRI_CONF_TEXTURE_DEPTH_FORCE_16 3 -#define DRI_CONF_TEXTURE_DEPTH(def) \ -DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \ - DRI_CONF_DESC_BEGIN(en,gettext("Texture color depth")) \ - DRI_CONF_ENUM(0,gettext("Prefer frame buffer color depth")) \ - DRI_CONF_ENUM(1,gettext("Prefer 32 bits per texel")) \ - DRI_CONF_ENUM(2,gettext("Prefer 16 bits per texel")) \ - DRI_CONF_ENUM(3,gettext("Force 16 bits per texel")) \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_DEF_MAX_ANISOTROPY(def,range) \ -DRI_CONF_OPT_BEGIN_V(def_max_anisotropy,float,def,range) \ - DRI_CONF_DESC(en,gettext("Initial maximum value for anisotropic texture filtering")) \ -DRI_CONF_OPT_END - -#define DRI_CONF_NO_NEG_LOD_BIAS(def) \ -DRI_CONF_OPT_BEGIN_B(no_neg_lod_bias, def) \ - DRI_CONF_DESC(en,gettext("Forbid negative texture LOD bias")) \ -DRI_CONF_OPT_END + DRI_CONF_DESC(en,gettext("Image Quality")) #define DRI_CONF_PRECISE_TRIG(def) \ DRI_CONF_OPT_BEGIN_B(precise_trig, def) \ DRI_CONF_DESC(en,gettext("Prefer accuracy over performance in trig functions")) \ DRI_CONF_OPT_END -#define DRI_CONF_COLOR_REDUCTION_ROUND 0 -#define DRI_CONF_COLOR_REDUCTION_DITHER 1 -#define DRI_CONF_COLOR_REDUCTION(def) \ -DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \ - DRI_CONF_DESC_BEGIN(en,gettext("Initial color reduction method")) \ - DRI_CONF_ENUM(0,gettext("Round colors")) \ - DRI_CONF_ENUM(1,gettext("Dither colors")) \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_ROUND_TRUNC 0 -#define DRI_CONF_ROUND_ROUND 1 -#define DRI_CONF_ROUND_MODE(def) \ -DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \ - DRI_CONF_DESC_BEGIN(en,gettext("Color rounding method")) \ - DRI_CONF_ENUM(0,gettext("Round color components downward")) \ - DRI_CONF_ENUM(1,gettext("Round to nearest color")) \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_DITHER_XERRORDIFF 0 -#define DRI_CONF_DITHER_XERRORDIFFRESET 1 -#define DRI_CONF_DITHER_ORDERED 2 -#define DRI_CONF_DITHER_MODE(def) \ -DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \ - DRI_CONF_DESC_BEGIN(en,gettext("Color dithering method")) \ - DRI_CONF_ENUM(0,gettext("Horizontal error diffusion")) \ - DRI_CONF_ENUM(1,gettext("Horizontal error diffusion, reset error at line start")) \ - DRI_CONF_ENUM(2,gettext("Ordered 2D color dithering")) \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_FLOAT_DEPTH(def) \ -DRI_CONF_OPT_BEGIN_B(float_depth, def) \ - DRI_CONF_DESC(en,gettext("Floating point depth buffer")) \ -DRI_CONF_OPT_END - #define DRI_CONF_PP_CELSHADE(def) \ DRI_CONF_OPT_BEGIN_V(pp_celshade,enum,def,"0:1") \ DRI_CONF_DESC(en,gettext("A post-processing filter to cel-shade the output")) \ @@ -257,32 +196,6 @@ DRI_CONF_OPT_END DRI_CONF_SECTION_BEGIN \ DRI_CONF_DESC(en,gettext("Performance")) -#define DRI_CONF_TCL_SW 0 -#define DRI_CONF_TCL_PIPELINED 1 -#define DRI_CONF_TCL_VTXFMT 2 -#define DRI_CONF_TCL_CODEGEN 3 -#define DRI_CONF_TCL_MODE(def) \ -DRI_CONF_OPT_BEGIN_V(tcl_mode,enum,def,"0:3") \ - DRI_CONF_DESC_BEGIN(en,gettext("TCL mode (Transformation, Clipping, Lighting)")) \ - DRI_CONF_ENUM(0,gettext("Use software TCL pipeline")) \ - DRI_CONF_ENUM(1,gettext("Use hardware TCL as first TCL pipeline stage")) \ - DRI_CONF_ENUM(2,gettext("Bypass the TCL pipeline")) \ - DRI_CONF_ENUM(3,gettext("Bypass the TCL pipeline with state-based machine code generated on-the-fly")) \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - -#define DRI_CONF_FTHROTTLE_BUSY 0 -#define DRI_CONF_FTHROTTLE_USLEEPS 1 -#define DRI_CONF_FTHROTTLE_IRQS 2 -#define DRI_CONF_FTHROTTLE_MODE(def) \ -DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \ - DRI_CONF_DESC_BEGIN(en,gettext("Method to limit rendering latency")) \ - DRI_CONF_ENUM(0,gettext("Busy waiting for the graphics hardware")) \ - DRI_CONF_ENUM(1,gettext("Sleep for brief intervals while waiting for the graphics hardware")) \ - DRI_CONF_ENUM(2,gettext("Let the graphics hardware emit a software interrupt and sleep")) \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - #define DRI_CONF_VBLANK_NEVER 0 #define DRI_CONF_VBLANK_DEF_INTERVAL_0 1 #define DRI_CONF_VBLANK_DEF_INTERVAL_1 2 @@ -297,35 +210,6 @@ DRI_CONF_OPT_BEGIN_V(vblank_mode,enum,def,"0:3") \ DRI_CONF_DESC_END \ DRI_CONF_OPT_END -#define DRI_CONF_HYPERZ_DISABLED 0 -#define DRI_CONF_HYPERZ_ENABLED 1 -#define DRI_CONF_HYPERZ(def) \ -DRI_CONF_OPT_BEGIN_B(hyperz, def) \ - DRI_CONF_DESC(en,gettext("Use HyperZ to boost performance")) \ -DRI_CONF_OPT_END - -#define DRI_CONF_MAX_TEXTURE_UNITS(def,min,max) \ -DRI_CONF_OPT_BEGIN_V(texture_units,int,def, # min ":" # max ) \ - DRI_CONF_DESC(en,gettext("Number of texture units used")) \ -DRI_CONF_OPT_END - -#define DRI_CONF_TEXTURE_BLEND_QUALITY(def,range) \ -DRI_CONF_OPT_BEGIN_V(texture_blend_quality,float,def,range) \ - DRI_CONF_DESC(en,gettext("Texture filtering quality vs. speed, AKA “brilinear” texture filtering")) \ -DRI_CONF_OPT_END - -#define DRI_CONF_TEXTURE_HEAPS_ALL 0 -#define DRI_CONF_TEXTURE_HEAPS_CARD 1 -#define DRI_CONF_TEXTURE_HEAPS_GART 2 -#define DRI_CONF_TEXTURE_HEAPS(def) \ -DRI_CONF_OPT_BEGIN_V(texture_heaps,enum,def,"0:2") \ - DRI_CONF_DESC_BEGIN(en,gettext("Used types of texture memory")) \ - DRI_CONF_ENUM(0,gettext("All available memory")) \ - DRI_CONF_ENUM(1,gettext("Only card memory (if available)")) \ - DRI_CONF_ENUM(2,gettext("Only GART (AGP/PCIE) memory (if available)")) \ - DRI_CONF_DESC_END \ -DRI_CONF_OPT_END - #define DRI_CONF_MESA_GLTHREAD(def) \ DRI_CONF_OPT_BEGIN_B(mesa_glthread, def) \ DRI_CONF_DESC(en,gettext("Enable offloading GL driver work to a separate thread")) \ @@ -346,18 +230,9 @@ DRI_CONF_OPT_BEGIN_B(glx_disable_oml_sync_control, def) \ DRI_CONF_DESC(en, gettext("Disable the GLX_OML_sync_control extension")) \ DRI_CONF_OPT_END - -/** - * \brief Software-fallback options. To allow using features (like - * GL_ARB_vertex_program) on GPUs that don't otherwise support the feature. - */ -#define DRI_CONF_SECTION_SOFTWARE \ -DRI_CONF_SECTION_BEGIN \ - DRI_CONF_DESC(en,gettext("Features that are not hardware-accelerated")) - -#define DRI_CONF_ARB_VERTEX_PROGRAM(def) \ -DRI_CONF_OPT_BEGIN_B(arb_vertex_program, def) \ - DRI_CONF_DESC(en,gettext("Enable extension GL_ARB_vertex_program")) \ +#define DRI_CONF_DISABLE_SGI_VIDEO_SYNC(def) \ +DRI_CONF_OPT_BEGIN_B(glx_disable_sgi_video_sync, def) \ + DRI_CONF_DESC(en, gettext("Disable the GLX_SGI_video_sync extension")) \ DRI_CONF_OPT_END @@ -379,6 +254,11 @@ DRI_CONF_OPT_BEGIN_B(glsl_zero_init, def) \ DRI_CONF_DESC(en,gettext("Force uninitialized variables to default to zero")) \ DRI_CONF_OPT_END +#define DRI_CONF_ALLOW_RGB10_CONFIGS(def) \ +DRI_CONF_OPT_BEGIN_B(allow_rgb10_configs, def) \ +DRI_CONF_DESC(en,gettext("Allow exposure of visuals and fbconfigs with rgb10a2 formats")) \ +DRI_CONF_OPT_END + /** * \brief Initialization configuration options */ @@ -391,6 +271,11 @@ DRI_CONF_OPT_BEGIN(device_id, string, def) \ DRI_CONF_DESC(en,gettext("Define the graphic device to use if possible")) \ DRI_CONF_OPT_END +#define DRI_CONF_DRI_DRIVER(def) \ +DRI_CONF_OPT_BEGIN(dri_driver, string, def) \ + DRI_CONF_DESC(en,gettext("Override the DRI driver to load")) \ +DRI_CONF_OPT_END + /** * \brief Gallium-Nine specific configuration options */ @@ -452,3 +337,8 @@ DRI_CONF_OPT_END DRI_CONF_OPT_BEGIN_B(radeonsi_clear_db_cache_before_clear, def) \ DRI_CONF_DESC(en,"Clear DB cache before fast depth clear") \ DRI_CONF_OPT_END + +#define DRI_CONF_RADEONSI_ZERO_ALL_VRAM_ALLOCS(def) \ +DRI_CONF_OPT_BEGIN_B(radeonsi_zerovram, def) \ + DRI_CONF_DESC(en,"Zero all vram allocations") \ +DRI_CONF_OPT_END |