diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000000..da1d81e1b46
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,101 @@
+language: c
+
+sudo: false
+
+cache:
+ directories:
+ - $HOME/.ccache
+
+addons:
+ apt:
+ packages:
+ - libdrm-dev
+ - libudev-dev
+ - x11proto-xf86vidmode-dev
+ - libexpat1-dev
+ - libxcb-dri2-0-dev
+ - libx11-xcb-dev
+ - llvm-3.4-dev
+ - scons
+
+env:
+ global:
+ - XORG_RELEASES=http://xorg.freedesktop.org/releases/individual
+ - XCB_RELEASES=http://xcb.freedesktop.org/dist
+ - XORGMACROS_VERSION=util-macros-1.19.0
+ - GLPROTO_VERSION=glproto-1.4.17
+ - DRI2PROTO_VERSION=dri2proto-2.8
+ - DRI3PROTO_VERSION=dri3proto-1.0
+ - PRESENTPROTO_VERSION=presentproto-1.0
+ - LIBPCIACCESS_VERSION=libpciaccess-0.13.4
+ - LIBDRM_VERSION=libdrm-2.4.65
+ - XCBPROTO_VERSION=xcb-proto-1.11
+ - LIBXCB_VERSION=libxcb-1.11
+ - LIBXSHMFENCE_VERSION=libxshmfence-1.2
+ - PKG_CONFIG_PATH=$HOME/prefix/lib/pkgconfig
+ matrix:
+ - BUILD=make
+ - BUILD=scons
+
+install:
+ - export PATH="/usr/lib/ccache:$PATH"
+ - pip install --user mako
+
+ # Install dependencies where we require specific versions (or where
+ # disallowed by Travis CI's package whitelisting).
+
+ - wget $XORG_RELEASES/util/$XORGMACROS_VERSION.tar.bz2
+ - tar -jxvf $XORGMACROS_VERSION.tar.bz2
+ - (cd $XORGMACROS_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+ - wget $XORG_RELEASES/proto/$GLPROTO_VERSION.tar.bz2
+ - tar -jxvf $GLPROTO_VERSION.tar.bz2
+ - (cd $GLPROTO_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+ - wget $XORG_RELEASES/proto/$DRI2PROTO_VERSION.tar.bz2
+ - tar -jxvf $DRI2PROTO_VERSION.tar.bz2
+ - (cd $DRI2PROTO_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+ - wget $XORG_RELEASES/proto/$DRI3PROTO_VERSION.tar.bz2
+ - tar -jxvf $DRI3PROTO_VERSION.tar.bz2
+ - (cd $DRI3PROTO_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+ - wget $XORG_RELEASES/proto/$PRESENTPROTO_VERSION.tar.bz2
+ - tar -jxvf $PRESENTPROTO_VERSION.tar.bz2
+ - (cd $PRESENTPROTO_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+ - wget $XCB_RELEASES/$XCBPROTO_VERSION.tar.bz2
+ - tar -jxvf $XCBPROTO_VERSION.tar.bz2
+ - (cd $XCBPROTO_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+ - wget $XCB_RELEASES/$LIBXCB_VERSION.tar.bz2
+ - tar -jxvf $LIBXCB_VERSION.tar.bz2
+ - (cd $LIBXCB_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+ - wget $XORG_RELEASES/lib/$LIBPCIACCESS_VERSION.tar.bz2
+ - tar -jxvf $LIBPCIACCESS_VERSION.tar.bz2
+ - (cd $LIBPCIACCESS_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+ - wget http://dri.freedesktop.org/libdrm/$LIBDRM_VERSION.tar.bz2
+ - tar -jxvf $LIBDRM_VERSION.tar.bz2
+ - (cd $LIBDRM_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+ - wget $XORG_RELEASES/lib/$LIBXSHMFENCE_VERSION.tar.bz2
+ - tar -jxvf $LIBXSHMFENCE_VERSION.tar.bz2
+ - (cd $LIBXSHMFENCE_VERSION && ./configure --prefix=$HOME/prefix && make install)
+
+# Disabled LLVM (and therefore r300 and r600) because the build fails
+# with "undefined reference to `clock_gettime'" and "undefined
+# reference to `setupterm'" in llvmpipe.
+script:
+ - if test "x$BUILD" = xmake; then
+ ./autogen.sh --enable-debug
+ --disable-gallium-llvm
+ --with-egl-platforms=x11,drm
+ --with-dri-drivers=i915,i965,radeon,r200,swrast,nouveau
+ --with-gallium-drivers=svga,swrast,vc4,virgl
+ ;
+ make && make check;
+ elif test x$BUILD = xscons; then
+ scons;
+ fi
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000000..68cc368a3a1
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,66 @@
+# http://www.appveyor.com/docs/appveyor-yml
+#
+# To setup AppVeyor for your own personal repositories do the following:
+# - Sign up
+# - Add a new project
+# - Select Git and fill in the Git clone URL
+# - Setup a Git hook as explained in
+# https://github.com/appveyor/webhooks#installing-git-hook
+# - Check 'Settings > General > Skip branches without appveyor'
+# - Check 'Settings > General > Rolling builds'
+# - Setup the global or project notifications to your liking
+#
+# Note that kicking (or restarting) a build via the web UI will not work, as it
+# will fail to find appveyor.yml . The Git hook is the most practical way to
+# kick a build.
+#
+# See also:
+# - http://help.appveyor.com/discussions/problems/2209-node-grunt-build-specify-a-project-or-solution-file-the-directory-does-not-contain-a-project-or-solution-file
+# - http://help.appveyor.com/discussions/questions/1184-build-config-vs-appveyoryaml
+
+version: '{build}'
+
+branches:
+ except:
+ - /^travis.*$/
+
+clone_depth: 5
+
+cache:
+- win_flex_bison-2.4.5.zip
+- llvm-3.3.1-msvc2013-mtd.7z
+
+environment:
+ WINFLEXBISON_ARCHIVE: win_flex_bison-2.4.5.zip
+ LLVM_ARCHIVE: llvm-3.3.1-msvc2013-mtd.7z
+
+install:
+# Check pip
+- python --version
+- python -m pip --version
+# Install Mako
+- python -m pip install --egg Mako
+# Install SCons
+- python -m pip install --egg scons==2.4.1
+- scons --version
+# Install flex/bison
+- if not exist "%WINFLEXBISON_ARCHIVE%" appveyor DownloadFile "http://downloads.sourceforge.net/project/winflexbison/%WINFLEXBISON_ARCHIVE%"
+- 7z x -y -owinflexbison\ "%WINFLEXBISON_ARCHIVE%" > nul
+- set Path=%CD%\winflexbison;%Path%
+- win_flex --version
+- win_bison --version
+# Download and extract LLVM
+- if not exist "%LLVM_ARCHIVE%" appveyor DownloadFile "https://people.freedesktop.org/~jrfonseca/llvm/%LLVM_ARCHIVE%"
+- 7z x -y "%LLVM_ARCHIVE%" > nul
+- mkdir llvm\bin
+- set LLVM=%CD%\llvm
+
+build_script:
+- scons -j%NUMBER_OF_PROCESSORS% MSVC_VERSION=12.0 llvm=1
+
+
+# It's possible to setup notification here, as described in
+# http://www.appveyor.com/docs/notifications#appveyor-yml-configuration , but
+# doing so would cause the notification settings to be replicated across all
+# repos, which is most likely undesired. So it's better to rely on the
+# Appveyor global/project notification settings.
diff --git a/configure.ac b/configure.ac
index ebea7fcb61a..c26dbf2e126 100644
--- a/configure.ac
+++ b/configure.ac
@@ -198,6 +198,13 @@ if test "x$GCC" = xyes -a "x$acv_mesa_CLANG" = xno; then
fi
fi
+dnl We don't support building Mesa with Sun C compiler
+dnl https://bugs.freedesktop.org/show_bug.cgi?id=93189
+AC_CHECK_DECL([__SUNPRO_C], [SUNCC=yes], [SUNCC=no])
+if test "x$SUNCC" = xyes; then
+ AC_MSG_ERROR([Building with Sun C compiler is not supported, use GCC instead.])
+fi
+
dnl Check for compiler builtins
AX_GCC_BUILTIN([__builtin_bswap32])
AX_GCC_BUILTIN([__builtin_bswap64])
diff --git a/docs/GL3.txt b/docs/GL3.txt
index ad6b95e992b..7eda0028997 100644
--- a/docs/GL3.txt
+++ b/docs/GL3.txt
@@ -92,11 +92,11 @@ GL 3.3, GLSL 3.30 --- all DONE: i965, nv50, nvc0, r600, radeonsi, llvmpipe, soft
GL_ARB_vertex_type_2_10_10_10_rev DONE ()
-GL 4.0, GLSL 4.00 --- all DONE: nvc0, radeonsi
+GL 4.0, GLSL 4.00 --- all DONE: nvc0, r600, radeonsi
- GL_ARB_draw_buffers_blend DONE (i965, nv50, r600, llvmpipe, softpipe)
- GL_ARB_draw_indirect DONE (i965, r600, llvmpipe, softpipe)
- GL_ARB_gpu_shader5 DONE (i965, r600)
+ GL_ARB_draw_buffers_blend DONE (i965, nv50, llvmpipe, softpipe)
+ GL_ARB_draw_indirect DONE (i965, llvmpipe, softpipe)
+ GL_ARB_gpu_shader5 DONE (i965)
- 'precise' qualifier DONE
- Dynamically uniform sampler array indices DONE (softpipe)
- Dynamically uniform UBO array indices DONE ()
@@ -109,26 +109,26 @@ GL 4.0, GLSL 4.00 --- all DONE: nvc0, radeonsi
- Enhanced per-sample shading DONE ()
- Interpolation functions DONE ()
- New overload resolution rules DONE
- GL_ARB_gpu_shader_fp64 DONE (r600, llvmpipe, softpipe)
- GL_ARB_sample_shading DONE (i965, nv50, r600)
- GL_ARB_shader_subroutine DONE (i965, nv50, r600, llvmpipe, softpipe)
+ GL_ARB_gpu_shader_fp64 DONE (llvmpipe, softpipe)
+ GL_ARB_sample_shading DONE (i965, nv50)
+ GL_ARB_shader_subroutine DONE (i965, nv50, llvmpipe, softpipe)
GL_ARB_tessellation_shader DONE ()
- GL_ARB_texture_buffer_object_rgb32 DONE (i965, r600, llvmpipe, softpipe)
- GL_ARB_texture_cube_map_array DONE (i965, nv50, r600, llvmpipe, softpipe)
- GL_ARB_texture_gather DONE (i965, nv50, r600, llvmpipe, softpipe)
- GL_ARB_texture_query_lod DONE (i965, nv50, r600, softpipe)
- GL_ARB_transform_feedback2 DONE (i965, nv50, r600, llvmpipe, softpipe)
- GL_ARB_transform_feedback3 DONE (i965, nv50, r600, llvmpipe, softpipe)
+ GL_ARB_texture_buffer_object_rgb32 DONE (i965, llvmpipe, softpipe)
+ GL_ARB_texture_cube_map_array DONE (i965, nv50, llvmpipe, softpipe)
+ GL_ARB_texture_gather DONE (i965, nv50, llvmpipe, softpipe)
+ GL_ARB_texture_query_lod DONE (i965, nv50, softpipe)
+ GL_ARB_transform_feedback2 DONE (i965, nv50, llvmpipe, softpipe)
+ GL_ARB_transform_feedback3 DONE (i965, nv50, llvmpipe, softpipe)
-GL 4.1, GLSL 4.10 --- all DONE: nvc0, radeonsi
+GL 4.1, GLSL 4.10 --- all DONE: nvc0, r600, radeonsi
- GL_ARB_ES2_compatibility DONE (i965, nv50, r600, llvmpipe, softpipe)
+ GL_ARB_ES2_compatibility DONE (i965, nv50, llvmpipe, softpipe)
GL_ARB_get_program_binary DONE (0 binary formats)
GL_ARB_separate_shader_objects DONE (all drivers)
GL_ARB_shader_precision DONE (all drivers that support GLSL 4.10)
- GL_ARB_vertex_attrib_64bit DONE (r600, llvmpipe, softpipe)
- GL_ARB_viewport_array DONE (i965, nv50, r600, llvmpipe)
+ GL_ARB_vertex_attrib_64bit DONE (llvmpipe, softpipe)
+ GL_ARB_viewport_array DONE (i965, nv50, llvmpipe)
GL 4.2, GLSL 4.20:
@@ -152,13 +152,13 @@ GL 4.3, GLSL 4.30:
GL_ARB_arrays_of_arrays DONE (i965)
GL_ARB_ES3_compatibility DONE (all drivers that support GLSL 3.30)
GL_ARB_clear_buffer_object DONE (all drivers)
- GL_ARB_compute_shader in progress (jljusten)
- GL_ARB_copy_image DONE (i965, nv50, nvc0, radeonsi)
+ GL_ARB_compute_shader DONE (i965)
+ GL_ARB_copy_image DONE (i965, nv50, nvc0, r600, radeonsi)
GL_KHR_debug DONE (all drivers)
GL_ARB_explicit_uniform_location DONE (all drivers that support GLSL)
GL_ARB_fragment_layer_viewport DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe)
GL_ARB_framebuffer_no_attachments DONE (i965)
- GL_ARB_internalformat_query2 not started
+ GL_ARB_internalformat_query2 in progress (elima)
GL_ARB_invalidate_subdata DONE (all drivers)
GL_ARB_multi_draw_indirect DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe)
GL_ARB_program_interface_query DONE (all drivers)
@@ -210,7 +210,7 @@ GL 4.5, GLSL 4.50:
These are the extensions cherry-picked to make GLES 3.1
GLES3.1, GLSL ES 3.1
GL_ARB_arrays_of_arrays DONE (i965)
- GL_ARB_compute_shader in progress (jljusten)
+ GL_ARB_compute_shader DONE (i965)
GL_ARB_draw_indirect DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe)
GL_ARB_explicit_uniform_location DONE (all drivers that support GLSL)
GL_ARB_framebuffer_no_attachments DONE (i965)
@@ -244,7 +244,7 @@ GLES3.2, GLSL ES 3.2
GL_OES_copy_image not started (based on GL_ARB_copy_image, which is done for some drivers)
GL_OES_draw_buffers_indexed not started
GL_OES_draw_elements_base_vertex DONE (all drivers)
- GL_OES_geometry_shader not started (based on GL_ARB_geometry_shader4, which is done for all drivers)
+ GL_OES_geometry_shader started (Marta)
GL_OES_gpu_shader5 not started (based on parts of GL_ARB_gpu_shader5, which is done for some drivers)
GL_OES_primitive_bounding box not started
GL_OES_sample_shading not started (based on parts of GL_ARB_sample_shading, which is done for some drivers)
diff --git a/docs/envvars.html b/docs/envvars.html
index 1b2c03ef377..5bb7b1e65bb 100644
--- a/docs/envvars.html
+++ b/docs/envvars.html
@@ -238,6 +238,12 @@ for details.
+
VA-API state tracker environment variables
+
+VAAPI_MPEG4_ENABLED - enable MPEG4 for VA-API, disabled by default.
+
+
+
Other Gallium drivers have their own environment variables. These may change
frequently so the source code should be consulted for details.
diff --git a/docs/index.html b/docs/index.html
index 1f50d6b40d3..6b1221d1bbd 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -16,6 +16,17 @@
News
+December 9, 2015
+
+Mesa 11.0.7 is released.
+This is a bug-fix release.
+
+
+Mesa demos 8.3.0 is also released.
+See the announcement for more information about the release.
+You can download it from ftp.freedesktop.org/pub/mesa/demos/8.3.0/ .
+
+
November 21, 2015
Mesa 11.0.6 is released.
diff --git a/docs/install.html b/docs/install.html
index a90c2b27d58..c826d642001 100644
--- a/docs/install.html
+++ b/docs/install.html
@@ -39,7 +39,7 @@ Version 2.6.4 or later should work.
Python Mako module -
-Python Mako module is required. Version 0.7.3 or later should work.
+Python Mako module is required. Version 0.3.4 or later should work.
SCons is required for building on
diff --git a/docs/relnotes.html b/docs/relnotes.html
index 6a8ed324eb5..a8aaa5fd2e8 100644
--- a/docs/relnotes.html
+++ b/docs/relnotes.html
@@ -21,6 +21,7 @@ The release notes summarize what's new or changed in each Mesa release.
+11.0.7 release notes
11.0.6 release notes
11.0.5 release notes
11.0.4 release notes
diff --git a/docs/relnotes/11.0.5.html b/docs/relnotes/11.0.5.html
index 05fa0b98325..d825b05bbaa 100644
--- a/docs/relnotes/11.0.5.html
+++ b/docs/relnotes/11.0.5.html
@@ -45,8 +45,6 @@ because compatibility contexts are not supported.
-
-
Bug 91993 - Graphical glitch in Astromenace (open-source game).
Bug 92214 - Flightgear crashes during splashboot with R600 driver, LLVM 3.7.0 and mesa 11.0.2
diff --git a/docs/relnotes/11.0.7.html b/docs/relnotes/11.0.7.html
new file mode 100644
index 00000000000..704cbbec552
--- /dev/null
+++ b/docs/relnotes/11.0.7.html
@@ -0,0 +1,154 @@
+
+
+
+
+ Mesa Release Notes
+
+
+
+
+
+
+
+
+
+
Mesa 11.0.7 Release Notes / December 9, 2015
+
+
+Mesa 11.0.7 is a bug fix release which fixes bugs found since the 11.0.6 release.
+
+
+Mesa 11.0.7 implements the OpenGL 4.1 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 4.1. OpenGL
+4.1 is only available if requested at context creation
+because compatibility contexts are not supported.
+
+
+
+
SHA256 checksums
+
+07c27004ff68b288097d17b2faa7bdf15ec73c96b7e6c9835266e544adf0a62f mesa-11.0.7.tar.gz
+e7e90a332ede6c8fd08eff90786a3fd1605a4e62ebf3a9b514047838194538cb mesa-11.0.7.tar.xz
+
+
+
+
New features
+
None
+
+
Bug fixes
+
+
This list is likely incomplete.
+
+
+
+Bug 90348 - Spilling failure of b96 merged value
+
+Bug 92363 - [BSW/BDW] ogles1conform Gets test fails
+
+Bug 92438 - Segfault in pushbuf_kref when running the android emulator (qemu) on nv50
+
+Bug 93110 - [NVE4] textureSize() and textureQueryLevels() uses a texture bound during the previous draw call
+
+Bug 93126 - wrongly claim supporting GL_EXT_texture_rg
+
+
+
+
+
Changes
+
+
Chris Wilson (1):
+
+ meta: Compute correct buffer size with SkipRows/SkipPixels
+
+
+
Daniel Stone (1):
+
+ egl/wayland: Ignore rects from SwapBuffersWithDamage
+
+
+
Dave Airlie (4):
+
+ texgetimage: consolidate 1D array handling code.
+ r600: geometry shader gsvs itemsize workaround
+ r600: rv670 use at least 16es/gs threads
+ r600: workaround empty geom shader.
+
+
+
Emil Velikov (4):
+
+ docs: add sha256 checksums for 11.0.6
+ get-pick-list.sh: Require explicit "11.0" for nominating stable patches
+ mesa; add get-extra-pick-list.sh script into bin/
+ Update version to 11.0.7
+
+
+
François Tigeot (1):
+
+ xmlconfig: Add support for DragonFly
+
+
+
Ian Romanick (22):
+
+ mesa: Make bind_vertex_buffer avilable outside varray.c
+ mesa: Refactor update_array_format to make _mesa_update_array_format_public
+ mesa: Refactor enable_vertex_array_attrib to make _mesa_enable_vertex_array_attrib
+ i965: Pass brw_context instead of gl_context to brw_draw_rectlist
+ i965: Use DSA functions for VBOs in brw_meta_fast_clear
+ i965: Use internal functions for buffer object access
+ i965: Don't pollute the buffer object namespace in brw_meta_fast_clear
+ meta: Use DSA functions for PBO in create_texture_for_pbo
+ meta: Use _mesa_NamedBufferData and _mesa_NamedBufferSubData for users of _mesa_meta_setup_vertex_objects
+ i965: Use _mesa_NamedBufferSubData for users of _mesa_meta_setup_vertex_objects
+ meta: Don't leave the VBO bound after _mesa_meta_setup_vertex_objects
+ meta: Track VBO using gl_buffer_object instead of GL API object handle
+ meta: Use DSA functions for VBOs in _mesa_meta_setup_vertex_objects
+ meta: Use internal functions for buffer object and VAO access
+ meta: Don't pollute the buffer object namespace in _mesa_meta_setup_vertex_objects
+ meta: Partially convert _mesa_meta_DrawTex to DSA
+ meta: Track VBO using gl_buffer_object instead of GL API object handle in _mesa_meta_DrawTex
+ meta: Use internal functions for buffer object and VAO access in _mesa_meta_DrawTex
+ meta: Don't pollute the buffer object namespace in _mesa_meta_DrawTex
+ meta/TexSubImage: Don't pollute the buffer object namespace
+ meta/generate_mipmap: Don't leak the framebuffer object
+ glsl: Fix off-by-one error in array size check assertion
+
+
+
Ilia Mirkin (7):
+
+ nvc0/ir: actually emit AFETCH on kepler
+ nir: fix typo in idiv lowering, causing large-udiv-udiv failures
+ nouveau: use the buffer usage to determine placement when no binding
+ nv50,nvc0: properly handle buffer storage invalidation on dsa buffer
+ nv50/ir: fix (un)spilling of 3-wide results
+ mesa: support GL_RED/GL_RG in ES2 contexts when driver support exists
+ nvc0/ir: start offset at texBindBase for txq, like regular texturing
+
+
+
Jonathan Gray (1):
+
+ automake: fix some occurrences of hardcoded -ldl and -lpthread
+
+
+
Leo Liu (1):
+
+ radeon/vce: disable Stoney VCE for 11.0
+
+
+
Marta Lofstedt (1):
+
+ gles2: Update gl2ext.h to revision: 32120
+
+
+
Oded Gabbay (1):
+
+ llvmpipe: disable VSX in ppc due to LLVM PPC bug
+
+
+
+
+
+
diff --git a/docs/relnotes/11.1.0.html b/docs/relnotes/11.1.0.html
index 77df804d901..542f368d36c 100644
--- a/docs/relnotes/11.1.0.html
+++ b/docs/relnotes/11.1.0.html
@@ -54,6 +54,7 @@ Note: some of the new features are only available with certain drivers.
GL_ARB_clip_control on freedreno/a4xx
GL_ARB_copy_image on nv50, nvc0, radeonsi
GL_ARB_depth_clamp on freedreno/a4xx
+GL_ARB_fragment_layer_viewport on i965 (gen6+)
GL_ARB_gpu_shader_fp64 on r600 for Cypress/Cayman/Aruba chips
GL_ARB_gpu_shader5 on r600 for Evergreen and later chips
GL_ARB_seamless_cubemap_per_texture on freedreno/a4xx
diff --git a/docs/relnotes/11.2.0.html b/docs/relnotes/11.2.0.html
index 20f4543a562..12e0f07a860 100644
--- a/docs/relnotes/11.2.0.html
+++ b/docs/relnotes/11.2.0.html
@@ -45,6 +45,9 @@ Note: some of the new features are only available with certain drivers.
GL_ARB_base_instance on freedreno/a4xx
+GL_ARB_compute_shader on i965
+GL_ARB_copy_image on r600
+GL_ARB_tessellation_shader on r600 (evergreen/cayman only)
GL_ARB_texture_buffer_object_rgb32 on freedreno/a4xx
GL_ARB_texture_buffer_range on freedreno/a4xx
GL_ARB_texture_query_lod on freedreno/a4xx
@@ -52,6 +55,7 @@ Note: some of the new features are only available with certain drivers.
GL_ARB_texture_view on freedreno/a4xx
GL_ARB_vertex_type_10f_11f_11f_rev on freedreno/a4xx
GL_KHR_texture_compression_astc_ldr on freedreno/a4xx
+GL_AMD_performance_monitor on radeonsi (CIK+ only)
Bug fixes
diff --git a/include/GLES2/gl2ext.h b/include/GLES2/gl2ext.h
index 2b67c6e0f88..2d055961a1b 100644
--- a/include/GLES2/gl2ext.h
+++ b/include/GLES2/gl2ext.h
@@ -6,7 +6,7 @@ extern "C" {
#endif
/*
-** Copyright (c) 2013-2014 The Khronos Group Inc.
+** Copyright (c) 2013-2015 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
@@ -33,14 +33,14 @@ extern "C" {
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
-** Khronos $Revision: 28335 $ on $Date: 2014-09-26 18:55:45 -0700 (Fri, 26 Sep 2014) $
+** Khronos $Revision: 32120 $ on $Date: 2015-10-15 04:27:13 -0700 (Thu, 15 Oct 2015) $
*/
#ifndef GL_APIENTRYP
#define GL_APIENTRYP GL_APIENTRY*
#endif
-/* Generated on date 20140926 */
+/* Generated on date 20151015 */
/* Generated C header for:
* API: gles2
@@ -117,6 +117,7 @@ typedef void (GL_APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,
#define GL_PROGRAM_KHR 0x82E2
#define GL_VERTEX_ARRAY_KHR 0x8074
#define GL_QUERY_KHR 0x82E3
+#define GL_PROGRAM_PIPELINE_KHR 0x82E4
#define GL_SAMPLER_KHR 0x82E6
#define GL_MAX_LABEL_LENGTH_KHR 0x82E8
#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143
@@ -155,6 +156,11 @@ GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, void **params);
#endif
#endif /* GL_KHR_debug */
+#ifndef GL_KHR_no_error
+#define GL_KHR_no_error 1
+#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
+#endif /* GL_KHR_no_error */
+
#ifndef GL_KHR_robust_buffer_access_behavior
#define GL_KHR_robust_buffer_access_behavior 1
#endif /* GL_KHR_robust_buffer_access_behavior */
@@ -219,6 +225,10 @@ GL_APICALL void GL_APIENTRY glGetnUniformuivKHR (GLuint program, GLint location,
#define GL_KHR_texture_compression_astc_ldr 1
#endif /* GL_KHR_texture_compression_astc_ldr */
+#ifndef GL_KHR_texture_compression_astc_sliced_3d
+#define GL_KHR_texture_compression_astc_sliced_3d 1
+#endif /* GL_KHR_texture_compression_astc_sliced_3d */
+
#ifndef GL_OES_EGL_image
#define GL_OES_EGL_image 1
typedef void *GLeglImageOES;
@@ -238,6 +248,10 @@ GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum targe
#define GL_SAMPLER_EXTERNAL_OES 0x8D66
#endif /* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external_essl3
+#define GL_OES_EGL_image_external_essl3 1
+#endif /* GL_OES_EGL_image_external_essl3 */
+
#ifndef GL_OES_compressed_ETC1_RGB8_sub_texture
#define GL_OES_compressed_ETC1_RGB8_sub_texture 1
#endif /* GL_OES_compressed_ETC1_RGB8_sub_texture */
@@ -261,6 +275,14 @@ GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum targe
#define GL_PALETTE8_RGB5_A1_OES 0x8B99
#endif /* GL_OES_compressed_paletted_texture */
+#ifndef GL_OES_copy_image
+#define GL_OES_copy_image 1
+typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAOESPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyImageSubDataOES (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#endif
+#endif /* GL_OES_copy_image */
+
#ifndef GL_OES_depth24
#define GL_OES_depth24 1
#define GL_DEPTH_COMPONENT24_OES 0x81A6
@@ -275,6 +297,44 @@ GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum targe
#define GL_OES_depth_texture 1
#endif /* GL_OES_depth_texture */
+#ifndef GL_OES_draw_buffers_indexed
+#define GL_OES_draw_buffers_indexed 1
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+typedef void (GL_APIENTRYP PFNGLENABLEIOESPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEIOESPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIOESPROC) (GLuint buf, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIOESPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCIOESPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIOESPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKIOESPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIOESPROC) (GLenum target, GLuint index);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEnableiOES (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisableiOES (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glBlendEquationiOES (GLuint buf, GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparateiOES (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunciOES (GLuint buf, GLenum src, GLenum dst);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparateiOES (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void GL_APIENTRY glColorMaskiOES (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GL_APICALL GLboolean GL_APIENTRY glIsEnablediOES (GLenum target, GLuint index);
+#endif
+#endif /* GL_OES_draw_buffers_indexed */
+
+#ifndef GL_OES_draw_elements_base_vertex
+#define GL_OES_draw_elements_base_vertex 1
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexOES (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexOES (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
+#endif
+#endif /* GL_OES_draw_elements_base_vertex */
+
#ifndef GL_OES_element_index_uint
#define GL_OES_element_index_uint 1
#endif /* GL_OES_element_index_uint */
@@ -287,6 +347,51 @@ GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum targe
#define GL_OES_fragment_precision_high 1
#endif /* GL_OES_fragment_precision_high */
+#ifndef GL_OES_geometry_point_size
+#define GL_OES_geometry_point_size 1
+#endif /* GL_OES_geometry_point_size */
+
+#ifndef GL_OES_geometry_shader
+#define GL_OES_geometry_shader 1
+#define GL_GEOMETRY_SHADER_OES 0x8DD9
+#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004
+#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916
+#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917
+#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918
+#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F
+#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E
+#define GL_LINES_ADJACENCY_OES 0x000A
+#define GL_LINE_STRIP_ADJACENCY_OES 0x000B
+#define GL_TRIANGLES_ADJACENCY_OES 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0x000D
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7
+#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E
+#define GL_UNDEFINED_VERTEX_OES 0x8260
+#define GL_PRIMITIVES_GENERATED_OES 0x8C87
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312
+#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7
+#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREOESPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureOES (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+#endif /* GL_OES_geometry_shader */
+
#ifndef GL_OES_get_program_binary
#define GL_OES_get_program_binary 1
#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741
@@ -300,6 +405,10 @@ GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFor
#endif
#endif /* GL_OES_get_program_binary */
+#ifndef GL_OES_gpu_shader5
+#define GL_OES_gpu_shader5 1
+#endif /* GL_OES_gpu_shader5 */
+
#ifndef GL_OES_mapbuffer
#define GL_OES_mapbuffer 1
#define GL_WRITE_ONLY_OES 0x88B9
@@ -323,6 +432,15 @@ GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname,
#define GL_DEPTH24_STENCIL8_OES 0x88F0
#endif /* GL_OES_packed_depth_stencil */
+#ifndef GL_OES_primitive_bounding_box
+#define GL_OES_primitive_bounding_box 1
+#define GL_PRIMITIVE_BOUNDING_BOX_OES 0x92BE
+typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXOESPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxOES (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#endif
+#endif /* GL_OES_primitive_bounding_box */
+
#ifndef GL_OES_required_internalformat
#define GL_OES_required_internalformat 1
#define GL_ALPHA8_OES 0x803C
@@ -361,6 +479,10 @@ GL_APICALL void GL_APIENTRY glMinSampleShadingOES (GLfloat value);
#define GL_OES_shader_image_atomic 1
#endif /* GL_OES_shader_image_atomic */
+#ifndef GL_OES_shader_io_blocks
+#define GL_OES_shader_io_blocks 1
+#endif /* GL_OES_shader_io_blocks */
+
#ifndef GL_OES_shader_multisample_interpolation
#define GL_OES_shader_multisample_interpolation 1
#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B
@@ -388,6 +510,61 @@ GL_APICALL void GL_APIENTRY glMinSampleShadingOES (GLfloat value);
#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219
#endif /* GL_OES_surfaceless_context */
+#ifndef GL_OES_tessellation_point_size
+#define GL_OES_tessellation_point_size 1
+#endif /* GL_OES_tessellation_point_size */
+
+#ifndef GL_OES_tessellation_shader
+#define GL_OES_tessellation_shader 1
+#define GL_PATCHES_OES 0x000E
+#define GL_PATCH_VERTICES_OES 0x8E72
+#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75
+#define GL_TESS_GEN_MODE_OES 0x8E76
+#define GL_TESS_GEN_SPACING_OES 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78
+#define GL_TESS_GEN_POINT_MODE_OES 0x8E79
+#define GL_ISOLINES_OES 0x8E7A
+#define GL_QUADS_OES 0x0007
+#define GL_FRACTIONAL_ODD_OES 0x8E7B
+#define GL_FRACTIONAL_EVEN_OES 0x8E7C
+#define GL_MAX_PATCH_VERTICES_OES 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221
+#define GL_IS_PER_PATCH_OES 0x92E7
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308
+#define GL_TESS_CONTROL_SHADER_OES 0x8E88
+#define GL_TESS_EVALUATION_SHADER_OES 0x8E87
+#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010
+typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIOESPROC) (GLenum pname, GLint value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPatchParameteriOES (GLenum pname, GLint value);
+#endif
+#endif /* GL_OES_tessellation_shader */
+
#ifndef GL_OES_texture_3D
#define GL_OES_texture_3D 1
#define GL_TEXTURE_WRAP_R_OES 0x8072
@@ -412,6 +589,54 @@ GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum att
#endif
#endif /* GL_OES_texture_3D */
+#ifndef GL_OES_texture_border_clamp
+#define GL_OES_texture_border_clamp 1
+#define GL_TEXTURE_BORDER_COLOR_OES 0x1004
+#define GL_CLAMP_TO_BORDER_OES 0x812D
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexParameterIivOES (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIuivOES (GLenum target, GLenum pname, const GLuint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIivOES (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIuivOES (GLenum target, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterIivOES (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterIuivOES (GLuint sampler, GLenum pname, const GLuint *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIivOES (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivOES (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+#endif /* GL_OES_texture_border_clamp */
+
+#ifndef GL_OES_texture_buffer
+#define GL_OES_texture_buffer 1
+#define GL_TEXTURE_BUFFER_OES 0x8C2A
+#define GL_TEXTURE_BUFFER_BINDING_OES 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_OES 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_OES 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES 0x8C2D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES 0x919F
+#define GL_SAMPLER_BUFFER_OES 0x8DC2
+#define GL_INT_SAMPLER_BUFFER_OES 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_OES 0x8DD8
+#define GL_IMAGE_BUFFER_OES 0x9051
+#define GL_INT_IMAGE_BUFFER_OES 0x905C
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_OES 0x9067
+#define GL_TEXTURE_BUFFER_OFFSET_OES 0x919D
+#define GL_TEXTURE_BUFFER_SIZE_OES 0x919E
+typedef void (GL_APIENTRYP PFNGLTEXBUFFEROESPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEOESPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexBufferOES (GLenum target, GLenum internalformat, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTexBufferRangeOES (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#endif
+#endif /* GL_OES_texture_buffer */
+
#ifndef GL_OES_texture_compression_astc
#define GL_OES_texture_compression_astc 1
#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0
@@ -436,6 +661,19 @@ GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum att
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9
#endif /* GL_OES_texture_compression_astc */
+#ifndef GL_OES_texture_cube_map_array
+#define GL_OES_texture_cube_map_array 1
+#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES 0x900A
+#define GL_SAMPLER_CUBE_MAP_ARRAY_OES 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900F
+#define GL_IMAGE_CUBE_MAP_ARRAY_OES 0x9054
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x905F
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x906A
+#endif /* GL_OES_texture_cube_map_array */
+
#ifndef GL_OES_texture_float
#define GL_OES_texture_float 1
#endif /* GL_OES_texture_float */
@@ -476,6 +714,19 @@ GL_APICALL void GL_APIENTRY glTexStorage3DMultisampleOES (GLenum target, GLsizei
#endif
#endif /* GL_OES_texture_storage_multisample_2d_array */
+#ifndef GL_OES_texture_view
+#define GL_OES_texture_view 1
+#define GL_TEXTURE_VIEW_MIN_LEVEL_OES 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS_OES 0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER_OES 0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS_OES 0x82DE
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWOESPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTextureViewOES (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#endif
+#endif /* GL_OES_texture_view */
+
#ifndef GL_OES_vertex_array_object
#define GL_OES_vertex_array_object 1
#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5
@@ -774,12 +1025,71 @@ GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei
#define GL_SHADER_BINARY_DMP 0x9250
#endif /* GL_DMP_shader_binary */
+#ifndef GL_EXT_YUV_target
+#define GL_EXT_YUV_target 1
+#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7
+#endif /* GL_EXT_YUV_target */
+
+#ifndef GL_EXT_base_instance
+#define GL_EXT_base_instance 1
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedBaseInstanceEXT (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
+#endif
+#endif /* GL_EXT_base_instance */
+
+#ifndef GL_EXT_blend_func_extended
+#define GL_EXT_blend_func_extended 1
+#define GL_SRC1_COLOR_EXT 0x88F9
+#define GL_SRC1_ALPHA_EXT 0x8589
+#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB
+#define GL_SRC_ALPHA_SATURATE_EXT 0x0308
+#define GL_LOCATION_INDEX_EXT 0x930F
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC
+typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATAINDEXEXTPROC) (GLuint program, const GLchar *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBindFragDataLocationIndexedEXT (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+GL_APICALL void GL_APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name);
+GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocationIndexEXT (GLuint program, GLenum programInterface, const GLchar *name);
+GL_APICALL GLint GL_APIENTRY glGetFragDataIndexEXT (GLuint program, const GLchar *name);
+#endif
+#endif /* GL_EXT_blend_func_extended */
+
#ifndef GL_EXT_blend_minmax
#define GL_EXT_blend_minmax 1
#define GL_MIN_EXT 0x8007
#define GL_MAX_EXT 0x8008
#endif /* GL_EXT_blend_minmax */
+#ifndef GL_EXT_buffer_storage
+#define GL_EXT_buffer_storage 1
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_PERSISTENT_BIT_EXT 0x0040
+#define GL_MAP_COHERENT_BIT_EXT 0x0080
+#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100
+#define GL_CLIENT_STORAGE_BIT_EXT 0x0200
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000
+#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F
+#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220
+typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBufferStorageEXT (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
+#endif
+#endif /* GL_EXT_buffer_storage */
+
+#ifndef GL_EXT_color_buffer_float
+#define GL_EXT_color_buffer_float 1
+#endif /* GL_EXT_color_buffer_float */
+
#ifndef GL_EXT_color_buffer_half_float
#define GL_EXT_color_buffer_half_float 1
#define GL_RGBA16F_EXT 0x881A
@@ -917,8 +1227,6 @@ GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs);
#ifndef GL_EXT_draw_buffers_indexed
#define GL_EXT_draw_buffers_indexed 1
-#define GL_MIN 0x8007
-#define GL_MAX 0x8008
typedef void (GL_APIENTRYP PFNGLENABLEIEXTPROC) (GLenum target, GLuint index);
typedef void (GL_APIENTRYP PFNGLDISABLEIEXTPROC) (GLenum target, GLuint index);
typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIEXTPROC) (GLuint buf, GLenum mode);
@@ -939,6 +1247,20 @@ GL_APICALL GLboolean GL_APIENTRY glIsEnablediEXT (GLenum target, GLuint index);
#endif
#endif /* GL_EXT_draw_buffers_indexed */
+#ifndef GL_EXT_draw_elements_base_vertex
+#define GL_EXT_draw_elements_base_vertex 1
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
+#endif
+#endif /* GL_EXT_draw_elements_base_vertex */
+
#ifndef GL_EXT_draw_instanced
#define GL_EXT_draw_instanced 1
typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
@@ -949,6 +1271,10 @@ GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei cou
#endif
#endif /* GL_EXT_draw_instanced */
+#ifndef GL_EXT_float_blend
+#define GL_EXT_float_blend 1
+#endif /* GL_EXT_float_blend */
+
#ifndef GL_EXT_geometry_point_size
#define GL_EXT_geometry_point_size 1
#endif /* GL_EXT_geometry_point_size */
@@ -1033,6 +1359,22 @@ GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *
#endif
#endif /* GL_EXT_multi_draw_arrays */
+#ifndef GL_EXT_multi_draw_indirect
+#define GL_EXT_multi_draw_indirect 1
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMultiDrawArraysIndirectEXT (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsIndirectEXT (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+#endif
+#endif /* GL_EXT_multi_draw_indirect */
+
+#ifndef GL_EXT_multisampled_compatibility
+#define GL_EXT_multisampled_compatibility 1
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#endif /* GL_EXT_multisampled_compatibility */
+
#ifndef GL_EXT_multisampled_render_to_texture
#define GL_EXT_multisampled_render_to_texture 1
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
@@ -1070,6 +1412,10 @@ GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLi
#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A
#endif /* GL_EXT_occlusion_query_boolean */
+#ifndef GL_EXT_post_depth_coverage
+#define GL_EXT_post_depth_coverage 1
+#endif /* GL_EXT_post_depth_coverage */
+
#ifndef GL_EXT_primitive_bounding_box
#define GL_EXT_primitive_bounding_box 1
#define GL_PRIMITIVE_BOUNDING_BOX_EXT 0x92BE
@@ -1089,12 +1435,36 @@ GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxEXT (GLfloat minX, GLfloat min
#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG 0x93F1
#endif /* GL_EXT_pvrtc_sRGB */
+#ifndef GL_EXT_raster_multisample
+#define GL_EXT_raster_multisample 1
+#define GL_RASTER_MULTISAMPLE_EXT 0x9327
+#define GL_RASTER_SAMPLES_EXT 0x9328
+#define GL_MAX_RASTER_SAMPLES_EXT 0x9329
+#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A
+#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B
+#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C
+typedef void (GL_APIENTRYP PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRasterSamplesEXT (GLuint samples, GLboolean fixedsamplelocations);
+#endif
+#endif /* GL_EXT_raster_multisample */
+
#ifndef GL_EXT_read_format_bgra
#define GL_EXT_read_format_bgra 1
#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365
#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
#endif /* GL_EXT_read_format_bgra */
+#ifndef GL_EXT_render_snorm
+#define GL_EXT_render_snorm 1
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM_EXT 0x8F98
+#define GL_RG16_SNORM_EXT 0x8F99
+#define GL_RGBA16_SNORM_EXT 0x8F9B
+#endif /* GL_EXT_render_snorm */
+
#ifndef GL_EXT_robustness
#define GL_EXT_robustness 1
#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253
@@ -1265,6 +1635,27 @@ GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLin
#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62
#endif /* GL_EXT_shadow_samplers */
+#ifndef GL_EXT_sparse_texture
+#define GL_EXT_sparse_texture 1
+#define GL_TEXTURE_SPARSE_EXT 0x91A6
+#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7
+#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA
+#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8
+#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195
+#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196
+#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_3D 0x806F
+#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198
+#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199
+#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A
+#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9
+typedef void (GL_APIENTRYP PFNGLTEXPAGECOMMITMENTEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexPageCommitmentEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+#endif
+#endif /* GL_EXT_sparse_texture */
+
#ifndef GL_EXT_tessellation_point_size
#define GL_EXT_tessellation_point_size 1
#endif /* GL_EXT_tessellation_point_size */
@@ -1399,10 +1790,23 @@ GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalf
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
#endif /* GL_EXT_texture_filter_anisotropic */
+#ifndef GL_EXT_texture_filter_minmax
+#define GL_EXT_texture_filter_minmax 1
+#endif /* GL_EXT_texture_filter_minmax */
+
#ifndef GL_EXT_texture_format_BGRA8888
#define GL_EXT_texture_format_BGRA8888 1
#endif /* GL_EXT_texture_format_BGRA8888 */
+#ifndef GL_EXT_texture_norm16
+#define GL_EXT_texture_norm16 1
+#define GL_R16_EXT 0x822A
+#define GL_RG16_EXT 0x822C
+#define GL_RGBA16_EXT 0x805B
+#define GL_RGB16_EXT 0x8054
+#define GL_RGB16_SNORM_EXT 0x8F9A
+#endif /* GL_EXT_texture_norm16 */
+
#ifndef GL_EXT_texture_rg
#define GL_EXT_texture_rg 1
#define GL_RED_EXT 0x1903
@@ -1411,6 +1815,16 @@ GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalf
#define GL_RG8_EXT 0x822B
#endif /* GL_EXT_texture_rg */
+#ifndef GL_EXT_texture_sRGB_R8
+#define GL_EXT_texture_sRGB_R8 1
+#define GL_SR8_EXT 0x8FBD
+#endif /* GL_EXT_texture_sRGB_R8 */
+
+#ifndef GL_EXT_texture_sRGB_RG8
+#define GL_EXT_texture_sRGB_RG8 1
+#define GL_SRG8_EXT 0x8FBE
+#endif /* GL_EXT_texture_sRGB_RG8 */
+
#ifndef GL_EXT_texture_sRGB_decode
#define GL_EXT_texture_sRGB_decode 1
#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
@@ -1461,7 +1875,6 @@ GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target
#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC
#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD
#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE
-#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWEXTPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glTextureViewEXT (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
@@ -1524,6 +1937,21 @@ GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target,
#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
#endif /* GL_IMG_texture_compression_pvrtc2 */
+#ifndef GL_IMG_texture_filter_cubic
+#define GL_IMG_texture_filter_cubic 1
+#define GL_CUBIC_IMG 0x9139
+#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A
+#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B
+#endif /* GL_IMG_texture_filter_cubic */
+
+#ifndef GL_INTEL_framebuffer_CMAA
+#define GL_INTEL_framebuffer_CMAA 1
+typedef void (GL_APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glApplyFramebufferAttachmentCMAAINTEL (void);
+#endif
+#endif /* GL_INTEL_framebuffer_CMAA */
+
#ifndef GL_INTEL_performance_query
#define GL_INTEL_performance_query 1
#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000
@@ -1570,6 +1998,38 @@ GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint quer
#endif
#endif /* GL_INTEL_performance_query */
+#ifndef GL_NV_bindless_texture
+#define GL_NV_bindless_texture 1
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture);
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef GLuint64 (GL_APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access);
+typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef GLboolean (GL_APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureHandleNV (GLuint texture);
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler);
+GL_APICALL void GL_APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle);
+GL_APICALL void GL_APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle);
+GL_APICALL GLuint64 GL_APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+GL_APICALL void GL_APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access);
+GL_APICALL void GL_APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle);
+GL_APICALL void GL_APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+GL_APICALL GLboolean GL_APIENTRY glIsTextureHandleResidentNV (GLuint64 handle);
+GL_APICALL GLboolean GL_APIENTRY glIsImageHandleResidentNV (GLuint64 handle);
+#endif
+#endif /* GL_NV_bindless_texture */
+
#ifndef GL_NV_blend_equation_advanced
#define GL_NV_blend_equation_advanced 1
#define GL_BLEND_OVERLAP_NV 0x9281
@@ -1634,6 +2094,32 @@ GL_APICALL void GL_APIENTRY glBlendBarrierNV (void);
#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285
#endif /* GL_NV_blend_equation_advanced_coherent */
+#ifndef GL_NV_conditional_render
+#define GL_NV_conditional_render 1
+#define GL_QUERY_WAIT_NV 0x8E13
+#define GL_QUERY_NO_WAIT_NV 0x8E14
+#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+typedef void (GL_APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode);
+GL_APICALL void GL_APIENTRY glEndConditionalRenderNV (void);
+#endif
+#endif /* GL_NV_conditional_render */
+
+#ifndef GL_NV_conservative_raster
+#define GL_NV_conservative_raster 1
+#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346
+#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347
+#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348
+#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349
+typedef void (GL_APIENTRYP PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybits);
+#endif
+#endif /* GL_NV_conservative_raster */
+
#ifndef GL_NV_copy_buffer
#define GL_NV_copy_buffer 1
#define GL_COPY_READ_BUFFER_NV 0x8F36
@@ -1751,6 +2237,25 @@ GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
#endif
#endif /* GL_NV_fence */
+#ifndef GL_NV_fill_rectangle
+#define GL_NV_fill_rectangle 1
+#define GL_FILL_RECTANGLE_NV 0x933C
+#endif /* GL_NV_fill_rectangle */
+
+#ifndef GL_NV_fragment_coverage_to_color
+#define GL_NV_fragment_coverage_to_color 1
+#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD
+#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE
+typedef void (GL_APIENTRYP PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFragmentCoverageColorNV (GLuint color);
+#endif
+#endif /* GL_NV_fragment_coverage_to_color */
+
+#ifndef GL_NV_fragment_shader_interlock
+#define GL_NV_fragment_shader_interlock 1
+#endif /* GL_NV_fragment_shader_interlock */
+
#ifndef GL_NV_framebuffer_blit
#define GL_NV_framebuffer_blit 1
#define GL_READ_FRAMEBUFFER_NV 0x8CA8
@@ -1763,6 +2268,26 @@ GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint
#endif
#endif /* GL_NV_framebuffer_blit */
+#ifndef GL_NV_framebuffer_mixed_samples
+#define GL_NV_framebuffer_mixed_samples 1
+#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331
+#define GL_COLOR_SAMPLES_NV 0x8E20
+#define GL_DEPTH_SAMPLES_NV 0x932D
+#define GL_STENCIL_SAMPLES_NV 0x932E
+#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F
+#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330
+#define GL_COVERAGE_MODULATION_NV 0x9332
+#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glGetCoverageModulationTableNV (GLsizei bufsize, GLfloat *v);
+GL_APICALL void GL_APIENTRY glCoverageModulationNV (GLenum components);
+#endif
+#endif /* GL_NV_framebuffer_mixed_samples */
+
#ifndef GL_NV_framebuffer_multisample
#define GL_NV_framebuffer_multisample 1
#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB
@@ -1778,6 +2303,14 @@ GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV (GLenum target, G
#define GL_NV_generate_mipmap_sRGB 1
#endif /* GL_NV_generate_mipmap_sRGB */
+#ifndef GL_NV_geometry_shader_passthrough
+#define GL_NV_geometry_shader_passthrough 1
+#endif /* GL_NV_geometry_shader_passthrough */
+
+#ifndef GL_NV_image_formats
+#define GL_NV_image_formats 1
+#endif /* GL_NV_image_formats */
+
#ifndef GL_NV_instanced_arrays
#define GL_NV_instanced_arrays 1
#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE
@@ -1787,6 +2320,20 @@ GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint diviso
#endif
#endif /* GL_NV_instanced_arrays */
+#ifndef GL_NV_internalformat_sample_query
+#define GL_NV_internalformat_sample_query 1
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_MULTISAMPLES_NV 0x9371
+#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372
+#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373
+#define GL_CONFORMANT_NV 0x9374
+typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params);
+#endif
+#endif /* GL_NV_internalformat_sample_query */
+
#ifndef GL_NV_non_square_matrices
#define GL_NV_non_square_matrices 1
#define GL_FLOAT_MAT2x3_NV 0x8B65
@@ -1811,6 +2358,298 @@ GL_APICALL void GL_APIENTRY glUniformMatrix4x3fvNV (GLint location, GLsizei coun
#endif
#endif /* GL_NV_non_square_matrices */
+#ifndef GL_NV_path_rendering
+#define GL_NV_path_rendering 1
+#define GL_PATH_FORMAT_SVG_NV 0x9070
+#define GL_PATH_FORMAT_PS_NV 0x9071
+#define GL_STANDARD_FONT_NAME_NV 0x9072
+#define GL_SYSTEM_FONT_NAME_NV 0x9073
+#define GL_FILE_NAME_NV 0x9074
+#define GL_PATH_STROKE_WIDTH_NV 0x9075
+#define GL_PATH_END_CAPS_NV 0x9076
+#define GL_PATH_INITIAL_END_CAP_NV 0x9077
+#define GL_PATH_TERMINAL_END_CAP_NV 0x9078
+#define GL_PATH_JOIN_STYLE_NV 0x9079
+#define GL_PATH_MITER_LIMIT_NV 0x907A
+#define GL_PATH_DASH_CAPS_NV 0x907B
+#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C
+#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D
+#define GL_PATH_DASH_OFFSET_NV 0x907E
+#define GL_PATH_CLIENT_LENGTH_NV 0x907F
+#define GL_PATH_FILL_MODE_NV 0x9080
+#define GL_PATH_FILL_MASK_NV 0x9081
+#define GL_PATH_FILL_COVER_MODE_NV 0x9082
+#define GL_PATH_STROKE_COVER_MODE_NV 0x9083
+#define GL_PATH_STROKE_MASK_NV 0x9084
+#define GL_COUNT_UP_NV 0x9088
+#define GL_COUNT_DOWN_NV 0x9089
+#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A
+#define GL_CONVEX_HULL_NV 0x908B
+#define GL_BOUNDING_BOX_NV 0x908D
+#define GL_TRANSLATE_X_NV 0x908E
+#define GL_TRANSLATE_Y_NV 0x908F
+#define GL_TRANSLATE_2D_NV 0x9090
+#define GL_TRANSLATE_3D_NV 0x9091
+#define GL_AFFINE_2D_NV 0x9092
+#define GL_AFFINE_3D_NV 0x9094
+#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096
+#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098
+#define GL_UTF8_NV 0x909A
+#define GL_UTF16_NV 0x909B
+#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
+#define GL_PATH_COMMAND_COUNT_NV 0x909D
+#define GL_PATH_COORD_COUNT_NV 0x909E
+#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F
+#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0
+#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1
+#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2
+#define GL_SQUARE_NV 0x90A3
+#define GL_ROUND_NV 0x90A4
+#define GL_TRIANGULAR_NV 0x90A5
+#define GL_BEVEL_NV 0x90A6
+#define GL_MITER_REVERT_NV 0x90A7
+#define GL_MITER_TRUNCATE_NV 0x90A8
+#define GL_SKIP_MISSING_GLYPH_NV 0x90A9
+#define GL_USE_MISSING_GLYPH_NV 0x90AA
+#define GL_PATH_ERROR_POSITION_NV 0x90AB
+#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD
+#define GL_ADJACENT_PAIRS_NV 0x90AE
+#define GL_FIRST_TO_REST_NV 0x90AF
+#define GL_PATH_GEN_MODE_NV 0x90B0
+#define GL_PATH_GEN_COEFF_NV 0x90B1
+#define GL_PATH_GEN_COMPONENTS_NV 0x90B3
+#define GL_PATH_STENCIL_FUNC_NV 0x90B7
+#define GL_PATH_STENCIL_REF_NV 0x90B8
+#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9
+#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
+#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE
+#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF
+#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4
+#define GL_MOVE_TO_RESETS_NV 0x90B5
+#define GL_MOVE_TO_CONTINUES_NV 0x90B6
+#define GL_CLOSE_PATH_NV 0x00
+#define GL_MOVE_TO_NV 0x02
+#define GL_RELATIVE_MOVE_TO_NV 0x03
+#define GL_LINE_TO_NV 0x04
+#define GL_RELATIVE_LINE_TO_NV 0x05
+#define GL_HORIZONTAL_LINE_TO_NV 0x06
+#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07
+#define GL_VERTICAL_LINE_TO_NV 0x08
+#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09
+#define GL_QUADRATIC_CURVE_TO_NV 0x0A
+#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B
+#define GL_CUBIC_CURVE_TO_NV 0x0C
+#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D
+#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E
+#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
+#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10
+#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11
+#define GL_SMALL_CCW_ARC_TO_NV 0x12
+#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13
+#define GL_SMALL_CW_ARC_TO_NV 0x14
+#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15
+#define GL_LARGE_CCW_ARC_TO_NV 0x16
+#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17
+#define GL_LARGE_CW_ARC_TO_NV 0x18
+#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19
+#define GL_RESTART_PATH_NV 0xF0
+#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2
+#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4
+#define GL_RECT_NV 0xF6
+#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8
+#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA
+#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC
+#define GL_ARC_TO_NV 0xFE
+#define GL_RELATIVE_ARC_TO_NV 0xFF
+#define GL_BOLD_BIT_NV 0x01
+#define GL_ITALIC_BIT_NV 0x02
+#define GL_GLYPH_WIDTH_BIT_NV 0x01
+#define GL_GLYPH_HEIGHT_BIT_NV 0x02
+#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04
+#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08
+#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
+#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20
+#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40
+#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80
+#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100
+#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000
+#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000
+#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000
+#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000
+#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000
+#define GL_FONT_ASCENDER_BIT_NV 0x00200000
+#define GL_FONT_DESCENDER_BIT_NV 0x00400000
+#define GL_FONT_HEIGHT_BIT_NV 0x00800000
+#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000
+#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000
+#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000
+#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000
+#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000
+#define GL_ROUNDED_RECT_NV 0xE8
+#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9
+#define GL_ROUNDED_RECT2_NV 0xEA
+#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB
+#define GL_ROUNDED_RECT4_NV 0xEC
+#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED
+#define GL_ROUNDED_RECT8_NV 0xEE
+#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF
+#define GL_RELATIVE_RECT_NV 0xF7
+#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368
+#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369
+#define GL_FONT_UNAVAILABLE_NV 0x936A
+#define GL_FONT_UNINTELLIGIBLE_NV 0x936B
+#define GL_CONIC_CURVE_TO_NV 0x1A
+#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B
+#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000
+#define GL_STANDARD_FONT_FORMAT_NV 0x936C
+#define GL_PATH_PROJECTION_NV 0x1701
+#define GL_PATH_MODELVIEW_NV 0x1700
+#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3
+#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6
+#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36
+#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3
+#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4
+#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7
+#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38
+#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4
+#define GL_FRAGMENT_INPUT_NV 0x936D
+typedef GLuint (GL_APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range);
+typedef void (GL_APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range);
+typedef GLboolean (GL_APIENTRYP PFNGLISPATHNVPROC) (GLuint path);
+typedef void (GL_APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString);
+typedef void (GL_APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GL_APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GL_APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);
+typedef void (GL_APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath);
+typedef void (GL_APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
+typedef void (GL_APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value);
+typedef void (GL_APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray);
+typedef void (GL_APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units);
+typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func);
+typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value);
+typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands);
+typedef void (GL_APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords);
+typedef void (GL_APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray);
+typedef void (GL_APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
+typedef void (GL_APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);
+typedef void (GL_APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
+typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y);
+typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y);
+typedef GLfloat (GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments);
+typedef GLboolean (GL_APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]);
+typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef GLenum (GL_APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLuint GL_APIENTRY glGenPathsNV (GLsizei range);
+GL_APICALL void GL_APIENTRY glDeletePathsNV (GLuint path, GLsizei range);
+GL_APICALL GLboolean GL_APIENTRY glIsPathNV (GLuint path);
+GL_APICALL void GL_APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString);
+GL_APICALL void GL_APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL void GL_APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL void GL_APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);
+GL_APICALL void GL_APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath);
+GL_APICALL void GL_APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
+GL_APICALL void GL_APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value);
+GL_APICALL void GL_APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value);
+GL_APICALL void GL_APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray);
+GL_APICALL void GL_APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glPathCoverDepthFuncNV (GLenum func);
+GL_APICALL void GL_APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value);
+GL_APICALL void GL_APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value);
+GL_APICALL void GL_APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands);
+GL_APICALL void GL_APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords);
+GL_APICALL void GL_APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray);
+GL_APICALL void GL_APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
+GL_APICALL void GL_APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);
+GL_APICALL void GL_APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
+GL_APICALL GLboolean GL_APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y);
+GL_APICALL GLboolean GL_APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y);
+GL_APICALL GLfloat GL_APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments);
+GL_APICALL GLboolean GL_APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);
+GL_APICALL void GL_APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]);
+GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL GLenum GL_APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL void GL_APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
+GL_APICALL void GL_APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params);
+#endif
+#endif /* GL_NV_path_rendering */
+
+#ifndef GL_NV_path_rendering_shared_edge
+#define GL_NV_path_rendering_shared_edge 1
+#define GL_SHARED_EDGE_NV 0xC0
+#endif /* GL_NV_path_rendering_shared_edge */
+
+#ifndef GL_NV_polygon_mode
+#define GL_NV_polygon_mode 1
+#define GL_POLYGON_MODE_NV 0x0B40
+#define GL_POLYGON_OFFSET_POINT_NV 0x2A01
+#define GL_POLYGON_OFFSET_LINE_NV 0x2A02
+#define GL_POINT_NV 0x1B00
+#define GL_LINE_NV 0x1B01
+#define GL_FILL_NV 0x1B02
+typedef void (GL_APIENTRYP PFNGLPOLYGONMODENVPROC) (GLenum face, GLenum mode);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPolygonModeNV (GLenum face, GLenum mode);
+#endif
+#endif /* GL_NV_polygon_mode */
+
#ifndef GL_NV_read_buffer
#define GL_NV_read_buffer 1
#define GL_READ_BUFFER_NV 0x0C02
@@ -1850,6 +2689,34 @@ GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode);
#define GL_ETC1_SRGB8_NV 0x88EE
#endif /* GL_NV_sRGB_formats */
+#ifndef GL_NV_sample_locations
+#define GL_NV_sample_locations 1
+#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340
+#define GL_SAMPLE_LOCATION_NV 0x8E50
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341
+#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342
+#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLRESOLVEDEPTHVALUESNVPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferSampleLocationsfvNV (GLenum target, GLuint start, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glNamedFramebufferSampleLocationsfvNV (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void);
+#endif
+#endif /* GL_NV_sample_locations */
+
+#ifndef GL_NV_sample_mask_override_coverage
+#define GL_NV_sample_mask_override_coverage 1
+#endif /* GL_NV_sample_mask_override_coverage */
+
+#ifndef GL_NV_shader_noperspective_interpolation
+#define GL_NV_shader_noperspective_interpolation 1
+#endif /* GL_NV_shader_noperspective_interpolation */
+
#ifndef GL_NV_shadow_samplers_array
#define GL_NV_shadow_samplers_array 1
#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4
@@ -1874,6 +2741,67 @@ GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode);
#define GL_NV_texture_npot_2D_mipmap 1
#endif /* GL_NV_texture_npot_2D_mipmap */
+#ifndef GL_NV_viewport_array
+#define GL_NV_viewport_array 1
+#define GL_MAX_VIEWPORTS_NV 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F
+typedef void (GL_APIENTRYP PFNGLVIEWPORTARRAYVNVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDNVPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDVNVPROC) (GLuint index, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEARRAYFVNVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEINDEXEDFNVPROC) (GLuint index, GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLGETFLOATI_VNVPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLENABLEINVPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEINVPROC) (GLenum target, GLuint index);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDINVPROC) (GLenum target, GLuint index);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glViewportArrayvNV (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glViewportIndexedfNV (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+GL_APICALL void GL_APIENTRY glViewportIndexedfvNV (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glScissorArrayvNV (GLuint first, GLsizei count, const GLint *v);
+GL_APICALL void GL_APIENTRY glScissorIndexedNV (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glScissorIndexedvNV (GLuint index, const GLint *v);
+GL_APICALL void GL_APIENTRY glDepthRangeArrayfvNV (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glDepthRangeIndexedfNV (GLuint index, GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glGetFloati_vNV (GLenum target, GLuint index, GLfloat *data);
+GL_APICALL void GL_APIENTRY glEnableiNV (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisableiNV (GLenum target, GLuint index);
+GL_APICALL GLboolean GL_APIENTRY glIsEnablediNV (GLenum target, GLuint index);
+#endif
+#endif /* GL_NV_viewport_array */
+
+#ifndef GL_NV_viewport_array2
+#define GL_NV_viewport_array2 1
+#endif /* GL_NV_viewport_array2 */
+
+#ifndef GL_OVR_multiview
+#define GL_OVR_multiview 1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632
+#define GL_MAX_VIEWS_OVR 0x9631
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
+#endif
+#endif /* GL_OVR_multiview */
+
+#ifndef GL_OVR_multiview2
+#define GL_OVR_multiview2 1
+#endif /* GL_OVR_multiview2 */
+
+#ifndef GL_OVR_multiview_multisampled_render_to_texture
+#define GL_OVR_multiview_multisampled_render_to_texture 1
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureMultisampleMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews);
+#endif
+#endif /* GL_OVR_multiview_multisampled_render_to_texture */
+
#ifndef GL_QCOM_alpha_test
#define GL_QCOM_alpha_test 1
#define GL_ALPHA_TEST_QCOM 0x0BC0
diff --git a/include/c99_compat.h b/include/c99_compat.h
index 4fc91bc1357..4be5b7e1259 100644
--- a/include/c99_compat.h
+++ b/include/c99_compat.h
@@ -81,8 +81,6 @@
/* Intel compiler supports inline keyword */
# elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
# define inline __inline
-# elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
- /* C99 supports inline keyword */
# elif (__STDC_VERSION__ >= 199901L)
/* C99 supports inline keyword */
# else
@@ -100,8 +98,6 @@
#ifndef restrict
# if (__STDC_VERSION__ >= 199901L)
/* C99 */
-# elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
- /* C99 */
# elif defined(__GNUC__)
# define restrict __restrict__
# elif defined(_MSC_VER)
@@ -118,8 +114,6 @@
#ifndef __func__
# if (__STDC_VERSION__ >= 199901L)
/* C99 */
-# elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
- /* C99 */
# elif defined(__GNUC__)
# define __func__ __FUNCTION__
# elif defined(_MSC_VER)
diff --git a/scons/llvm.py b/scons/llvm.py
index c59b8cb9317..1fc8a3fd13e 100644
--- a/scons/llvm.py
+++ b/scons/llvm.py
@@ -106,7 +106,19 @@ def generate(env):
])
env.Prepend(LIBPATH = [os.path.join(llvm_dir, 'lib')])
# LIBS should match the output of `llvm-config --libs engine mcjit bitwriter x86asmprinter`
- if llvm_version >= distutils.version.LooseVersion('3.6'):
+ if llvm_version >= distutils.version.LooseVersion('3.7'):
+ env.Prepend(LIBS = [
+ 'LLVMBitWriter', 'LLVMX86Disassembler', 'LLVMX86AsmParser',
+ 'LLVMX86CodeGen', 'LLVMSelectionDAG', 'LLVMAsmPrinter',
+ 'LLVMCodeGen', 'LLVMScalarOpts', 'LLVMProfileData',
+ 'LLVMInstCombine', 'LLVMInstrumentation', 'LLVMTransformUtils', 'LLVMipa',
+ 'LLVMAnalysis', 'LLVMX86Desc', 'LLVMMCDisassembler',
+ 'LLVMX86Info', 'LLVMX86AsmPrinter', 'LLVMX86Utils',
+ 'LLVMMCJIT', 'LLVMTarget', 'LLVMExecutionEngine',
+ 'LLVMRuntimeDyld', 'LLVMObject', 'LLVMMCParser',
+ 'LLVMBitReader', 'LLVMMC', 'LLVMCore', 'LLVMSupport'
+ ])
+ elif llvm_version >= distutils.version.LooseVersion('3.6'):
env.Prepend(LIBS = [
'LLVMBitWriter', 'LLVMX86Disassembler', 'LLVMX86AsmParser',
'LLVMX86CodeGen', 'LLVMSelectionDAG', 'LLVMAsmPrinter',
diff --git a/src/gallium/auxiliary/Makefile.am b/src/gallium/auxiliary/Makefile.am
index ee296ceda33..7b026b51c33 100644
--- a/src/gallium/auxiliary/Makefile.am
+++ b/src/gallium/auxiliary/Makefile.am
@@ -9,7 +9,7 @@ AM_CFLAGS = \
-I$(top_srcdir)/src/gallium/auxiliary/util \
$(GALLIUM_CFLAGS) \
$(VISIBILITY_CFLAGS) \
- $(MSVC2008_COMPAT_CXXFLAGS)
+ $(MSVC2008_COMPAT_CFLAGS)
AM_CXXFLAGS = \
$(VISIBILITY_CXXFLAGS) \
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c
index d36f1fbd717..b240c938dcc 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.c
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.c
@@ -247,7 +247,7 @@ struct cso_cache *cso_cache_create(void)
{
struct cso_cache *sc = MALLOC_STRUCT(cso_cache);
int i;
- if (sc == NULL)
+ if (!sc)
return NULL;
sc->max_size = 4096;
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 00686d2af41..6b29b20c53e 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -244,7 +244,7 @@ static void cso_init_vbuf(struct cso_context *cso)
struct cso_context *cso_create_context( struct pipe_context *pipe )
{
struct cso_context *ctx = CALLOC_STRUCT(cso_context);
- if (ctx == NULL)
+ if (!ctx)
goto out;
ctx->cache = cso_cache_create();
@@ -1075,7 +1075,7 @@ cso_single_sampler(struct cso_context *ctx, unsigned shader_stage,
{
void *handle = NULL;
- if (templ != NULL) {
+ if (templ) {
unsigned key_size = sizeof(struct pipe_sampler_state);
unsigned hash_key = cso_construct_key((void*)templ, key_size);
struct cso_hash_iter iter =
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index ee009c1fb71..16a261c14cf 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -72,7 +72,7 @@ draw_create_context(struct pipe_context *pipe, void *context,
boolean try_llvm)
{
struct draw_context *draw = CALLOC_STRUCT( draw_context );
- if (draw == NULL)
+ if (!draw)
goto err_out;
/* we need correct cpu caps for disabling denorms in draw_vbo() */
diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index c827a68ea0a..6b33341ce6c 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -734,7 +734,7 @@ draw_create_geometry_shader(struct draw_context *draw,
if (use_llvm) {
llvm_gs = CALLOC_STRUCT(llvm_geometry_shader);
- if (llvm_gs == NULL)
+ if (!llvm_gs)
return NULL;
gs = &llvm_gs->base;
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 8435991fb6b..ee974243b3e 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -551,7 +551,7 @@ draw_llvm_create_variant(struct draw_llvm *llvm,
variant = MALLOC(sizeof *variant +
shader->variant_key_size -
sizeof variant->key);
- if (variant == NULL)
+ if (!variant)
return NULL;
variant->llvm = llvm;
@@ -2224,7 +2224,7 @@ draw_gs_llvm_create_variant(struct draw_llvm *llvm,
variant = MALLOC(sizeof *variant +
shader->variant_key_size -
sizeof variant->key);
- if (variant == NULL)
+ if (!variant)
return NULL;
variant->llvm = llvm;
diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c
index 32cad59d604..cb316956162 100644
--- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
+++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
@@ -283,7 +283,7 @@ draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_stat
struct draw_llvm_sampler_soa *sampler;
sampler = CALLOC_STRUCT(draw_llvm_sampler_soa);
- if(!sampler)
+ if (!sampler)
return NULL;
sampler->base.destroy = draw_llvm_sampler_soa_destroy;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 85d24b7a6a1..877db5979b1 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -429,7 +429,7 @@ aaline_create_texture(struct aaline_stage *aaline)
PIPE_TRANSFER_WRITE,
&box, &transfer);
- if (data == NULL)
+ if (!data)
return FALSE;
for (i = 0; i < size; i++) {
@@ -774,7 +774,7 @@ static struct aaline_stage *
draw_aaline_stage(struct draw_context *draw)
{
struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage);
- if (aaline == NULL)
+ if (!aaline)
return NULL;
aaline->stage.draw = draw;
@@ -793,8 +793,7 @@ draw_aaline_stage(struct draw_context *draw)
return aaline;
fail:
- if (aaline)
- aaline->stage.destroy(&aaline->stage);
+ aaline->stage.destroy(&aaline->stage);
return NULL;
}
@@ -824,12 +823,12 @@ aaline_create_fs_state(struct pipe_context *pipe,
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
struct aaline_fragment_shader *aafs = NULL;
- if (aaline == NULL)
+ if (!aaline)
return NULL;
aafs = CALLOC_STRUCT(aaline_fragment_shader);
- if (aafs == NULL)
+ if (!aafs)
return NULL;
aafs->state.tokens = tgsi_dup_tokens(fs->tokens);
@@ -847,7 +846,7 @@ aaline_bind_fs_state(struct pipe_context *pipe, void *fs)
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
- if (aaline == NULL) {
+ if (!aaline) {
return;
}
@@ -864,11 +863,11 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
- if (aafs == NULL) {
+ if (!aafs) {
return;
}
- if (aaline != NULL) {
+ if (aaline) {
/* pass-through */
aaline->driver_delete_fs_state(pipe, aafs->driver_fs);
@@ -889,7 +888,7 @@ aaline_bind_sampler_states(struct pipe_context *pipe, unsigned shader,
assert(start == 0);
- if (aaline == NULL) {
+ if (!aaline) {
return;
}
@@ -912,7 +911,7 @@ aaline_set_sampler_views(struct pipe_context *pipe, unsigned shader,
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
uint i;
- if (aaline == NULL) {
+ if (!aaline) {
return;
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
index 063e36828d7..33ef8ec1702 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
@@ -662,7 +662,7 @@ static struct aapoint_stage *
draw_aapoint_stage(struct draw_context *draw)
{
struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage);
- if (aapoint == NULL)
+ if (!aapoint)
goto fail;
aapoint->stage.draw = draw;
@@ -707,7 +707,7 @@ aapoint_create_fs_state(struct pipe_context *pipe,
{
struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader);
- if (aafs == NULL)
+ if (!aafs)
return NULL;
aafs->state.tokens = tgsi_dup_tokens(fs->tokens);
@@ -767,7 +767,7 @@ draw_install_aapoint_stage(struct draw_context *draw,
* Create / install AA point drawing / prim stage
*/
aapoint = draw_aapoint_stage( draw );
- if (aapoint == NULL)
+ if (!aapoint)
return FALSE;
/* save original driver functions */
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index c22758bc702..35e54f4a8be 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -58,19 +58,24 @@
struct clip_stage {
struct draw_stage stage; /**< base class */
- /* List of the attributes to be flatshaded. */
- uint num_flat_attribs;
- uint flat_attribs[PIPE_MAX_SHADER_OUTPUTS];
+ unsigned pos_attr;
- /* Mask of attributes in noperspective mode */
- boolean noperspective_attribs[PIPE_MAX_SHADER_OUTPUTS];
+ /* List of the attributes to be constant interpolated. */
+ uint num_const_attribs;
+ uint8_t const_attribs[PIPE_MAX_SHADER_OUTPUTS];
+ /* List of the attributes to be linear interpolated. */
+ uint num_linear_attribs;
+ uint8_t linear_attribs[PIPE_MAX_SHADER_OUTPUTS];
+ /* List of the attributes to be perspective interpolated. */
+ uint num_perspect_attribs;
+ uint8_t perspect_attribs[PIPE_MAX_SHADER_OUTPUTS];
float (*plane)[4];
};
/** Cast wrapper */
-static inline struct clip_stage *clip_stage( struct draw_stage *stage )
+static inline struct clip_stage *clip_stage(struct draw_stage *stage)
{
return (struct clip_stage *)stage;
}
@@ -96,10 +101,10 @@ draw_viewport_index(struct draw_context *draw,
/* All attributes are float[4], so this is easy:
*/
-static void interp_attr( float dst[4],
- float t,
- const float in[4],
- const float out[4] )
+static void interp_attr(float dst[4],
+ float t,
+ const float in[4],
+ const float out[4])
{
dst[0] = LINTERP( t, out[0], in[0] );
dst[1] = LINTERP( t, out[1], in[1] );
@@ -111,30 +116,28 @@ static void interp_attr( float dst[4],
/**
* Copy flat shaded attributes src vertex to dst vertex.
*/
-static void copy_flat( struct draw_stage *stage,
- struct vertex_header *dst,
- const struct vertex_header *src )
+static void copy_flat(struct draw_stage *stage,
+ struct vertex_header *dst,
+ const struct vertex_header *src)
{
const struct clip_stage *clipper = clip_stage(stage);
uint i;
- for (i = 0; i < clipper->num_flat_attribs; i++) {
- const uint attr = clipper->flat_attribs[i];
+ for (i = 0; i < clipper->num_const_attribs; i++) {
+ const uint attr = clipper->const_attribs[i];
COPY_4FV(dst->data[attr], src->data[attr]);
}
}
/* Interpolate between two vertices to produce a third.
*/
-static void interp( const struct clip_stage *clip,
- struct vertex_header *dst,
- float t,
- const struct vertex_header *out,
- const struct vertex_header *in,
- unsigned viewport_index )
+static void interp(const struct clip_stage *clip,
+ struct vertex_header *dst,
+ float t,
+ const struct vertex_header *out,
+ const struct vertex_header *in,
+ unsigned viewport_index)
{
- const unsigned nr_attrs = draw_num_shader_outputs(clip->stage.draw);
- const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
- const unsigned clip_attr = draw_current_shader_clipvertex_output(clip->stage.draw);
+ const unsigned pos_attr = clip->pos_attr;
unsigned j;
float t_nopersp;
@@ -168,6 +171,13 @@ static void interp( const struct clip_stage *clip,
dst->data[pos_attr][3] = oow;
}
+
+ /* interp perspective attribs */
+ for (j = 0; j < clip->num_perspect_attribs; j++) {
+ const unsigned attr = clip->perspect_attribs[j];
+ interp_attr(dst->data[attr], t, in->data[attr], out->data[attr]);
+ }
+
/**
* Compute the t in screen-space instead of 3d space to use
* for noperspective interpolation.
@@ -177,7 +187,7 @@ static void interp( const struct clip_stage *clip,
* pick whatever value (the interpolated point won't be in front
* anyway), so just use the 3d t.
*/
- {
+ if (clip->num_linear_attribs) {
int k;
t_nopersp = t;
/* find either in.x != out.x or in.y != out.y */
@@ -191,24 +201,17 @@ static void interp( const struct clip_stage *clip,
break;
}
}
- }
-
- /* Other attributes
- */
- for (j = 0; j < nr_attrs; j++) {
- if (j != pos_attr && j != clip_attr) {
- if (clip->noperspective_attribs[j])
- interp_attr(dst->data[j], t_nopersp, in->data[j], out->data[j]);
- else
- interp_attr(dst->data[j], t, in->data[j], out->data[j]);
+ for (j = 0; j < clip->num_linear_attribs; j++) {
+ const unsigned attr = clip->linear_attribs[j];
+ interp_attr(dst->data[attr], t_nopersp, in->data[attr], out->data[attr]);
}
}
}
/**
- * Checks whether the specifed triangle is empty and if it is returns
+ * Checks whether the specified triangle is empty and if it is returns
* true, otherwise returns false.
- * Triangle is considered null/empty if it's area is qual to zero.
+ * Triangle is considered null/empty if its area is equal to zero.
*/
static inline boolean
is_tri_null(struct draw_context *draw, const struct prim_header *header)
@@ -233,11 +236,11 @@ is_tri_null(struct draw_context *draw, const struct prim_header *header)
* Emit a post-clip polygon to the next pipeline stage. The polygon
* will be convex and the provoking vertex will always be vertex[0].
*/
-static void emit_poly( struct draw_stage *stage,
- struct vertex_header **inlist,
- const boolean *edgeflags,
- unsigned n,
- const struct prim_header *origPrim)
+static void emit_poly(struct draw_stage *stage,
+ struct vertex_header **inlist,
+ const boolean *edgeflags,
+ unsigned n,
+ const struct prim_header *origPrim)
{
struct prim_header header;
unsigned i;
@@ -358,15 +361,16 @@ static inline float getclipdist(const struct clip_stage *clipper,
/* Clip a triangle against the viewport and user clip planes.
*/
static void
-do_clip_tri( struct draw_stage *stage,
- struct prim_header *header,
- unsigned clipmask )
+do_clip_tri(struct draw_stage *stage,
+ struct prim_header *header,
+ unsigned clipmask)
{
struct clip_stage *clipper = clip_stage( stage );
struct vertex_header *a[MAX_CLIPPED_VERTICES];
struct vertex_header *b[MAX_CLIPPED_VERTICES];
struct vertex_header **inlist = a;
struct vertex_header **outlist = b;
+ struct vertex_header *prov_vertex;
unsigned tmpnr = 0;
unsigned n = 3;
unsigned i;
@@ -380,7 +384,20 @@ do_clip_tri( struct draw_stage *stage,
inlist[1] = header->v[1];
inlist[2] = header->v[2];
- viewport_index = draw_viewport_index(clipper->stage.draw, inlist[0]);
+ /*
+ * For d3d10, we need to take this from the leading (first) vertex.
+ * For GL, we could do anything (as long as we advertize
+ * GL_UNDEFINED_VERTEX for the VIEWPORT_INDEX_PROVOKING_VERTEX query),
+ * but it needs to be consistent with what other parts (i.e. driver)
+ * will do, and that seems easier with GL_PROVOKING_VERTEX logic.
+ */
+ if (stage->draw->rasterizer->flatshade_first) {
+ prov_vertex = inlist[0];
+ }
+ else {
+ prov_vertex = inlist[2];
+ }
+ viewport_index = draw_viewport_index(clipper->stage.draw, prov_vertex);
if (DEBUG_CLIP) {
const float *v0 = header->v[0]->clip;
@@ -425,7 +442,7 @@ do_clip_tri( struct draw_stage *stage,
inEdges[n] = inEdges[0];
for (i = 1; i <= n; i++) {
- struct vertex_header *vert = inlist[i];
+ struct vertex_header *vert = inlist[i];
boolean *edge = &inEdges[i];
float dp = getclipdist(clipper, vert, plane_idx);
@@ -433,16 +450,16 @@ do_clip_tri( struct draw_stage *stage,
if (util_is_inf_or_nan(dp))
return; //discard nan
- if (dp_prev >= 0.0f) {
+ if (dp_prev >= 0.0f) {
assert(outcount < MAX_CLIPPED_VERTICES);
if (outcount >= MAX_CLIPPED_VERTICES)
return;
outEdges[outcount] = *edge_prev;
- outlist[outcount++] = vert_prev;
- }
+ outlist[outcount++] = vert_prev;
+ }
- if (DIFFERENT_SIGNS(dp, dp_prev)) {
- struct vertex_header *new_vert;
+ if (DIFFERENT_SIGNS(dp, dp_prev)) {
+ struct vertex_header *new_vert;
boolean *new_edge;
assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
@@ -455,19 +472,19 @@ do_clip_tri( struct draw_stage *stage,
return;
new_edge = &outEdges[outcount];
- outlist[outcount++] = new_vert;
+ outlist[outcount++] = new_vert;
- if (dp < 0.0f) {
- /* Going out of bounds. Avoid division by zero as we
- * know dp != dp_prev from DIFFERENT_SIGNS, above.
- */
- float t = dp / (dp - dp_prev);
- interp( clipper, new_vert, t, vert, vert_prev, viewport_index );
-
- /* Whether or not to set edge flag for the new vert depends
+ if (dp < 0.0f) {
+ /* Going out of bounds. Avoid division by zero as we
+ * know dp != dp_prev from DIFFERENT_SIGNS, above.
+ */
+ float t = dp / (dp - dp_prev);
+ interp( clipper, new_vert, t, vert, vert_prev, viewport_index );
+
+ /* Whether or not to set edge flag for the new vert depends
* on whether it's a user-defined clipping plane. We're
* copying NVIDIA's behaviour here.
- */
+ */
if (is_user_clip_plane) {
/* we want to see an edge along the clip plane */
*new_edge = TRUE;
@@ -478,31 +495,31 @@ do_clip_tri( struct draw_stage *stage,
*new_edge = *edge_prev;
new_vert->edgeflag = FALSE;
}
- }
+ }
else {
- /* Coming back in.
- */
- float t = dp_prev / (dp_prev - dp);
- interp( clipper, new_vert, t, vert_prev, vert, viewport_index );
+ /* Coming back in.
+ */
+ float t = dp_prev / (dp_prev - dp);
+ interp( clipper, new_vert, t, vert_prev, vert, viewport_index );
- /* Copy starting vert's edgeflag:
- */
- new_vert->edgeflag = vert_prev->edgeflag;
+ /* Copy starting vert's edgeflag:
+ */
+ new_vert->edgeflag = vert_prev->edgeflag;
*new_edge = *edge_prev;
- }
- }
+ }
+ }
- vert_prev = vert;
+ vert_prev = vert;
edge_prev = edge;
- dp_prev = dp;
+ dp_prev = dp;
}
/* swap in/out lists */
{
- struct vertex_header **tmp = inlist;
- inlist = outlist;
- outlist = tmp;
- n = outcount;
+ struct vertex_header **tmp = inlist;
+ inlist = outlist;
+ outlist = tmp;
+ n = outcount;
}
{
boolean *tmp = inEdges;
@@ -512,10 +529,10 @@ do_clip_tri( struct draw_stage *stage,
}
- /* If flat-shading, copy provoking vertex color to polygon vertex[0]
+ /* If constant interpolated, copy provoking vertex attrib to polygon vertex[0]
*/
if (n >= 3) {
- if (clipper->num_flat_attribs) {
+ if (clipper->num_const_attribs) {
if (stage->draw->rasterizer->flatshade_first) {
if (inlist[0] != header->v[0]) {
assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
@@ -535,7 +552,7 @@ do_clip_tri( struct draw_stage *stage,
}
}
}
-
+
/* Emit the polygon as triangles to the setup stage:
*/
emit_poly( stage, inlist, inEdges, n, header );
@@ -546,17 +563,26 @@ do_clip_tri( struct draw_stage *stage,
/* Clip a line against the viewport and user clip planes.
*/
static void
-do_clip_line( struct draw_stage *stage,
- struct prim_header *header,
- unsigned clipmask )
+do_clip_line(struct draw_stage *stage,
+ struct prim_header *header,
+ unsigned clipmask)
{
const struct clip_stage *clipper = clip_stage( stage );
struct vertex_header *v0 = header->v[0];
struct vertex_header *v1 = header->v[1];
+ struct vertex_header *prov_vertex;
float t0 = 0.0F;
float t1 = 0.0F;
struct prim_header newprim;
- int viewport_index = draw_viewport_index(clipper->stage.draw, v0);
+ int viewport_index;
+
+ if (stage->draw->rasterizer->flatshade_first) {
+ prov_vertex = v0;
+ }
+ else {
+ prov_vertex = v1;
+ }
+ viewport_index = draw_viewport_index(clipper->stage.draw, prov_vertex);
while (clipmask) {
const unsigned plane_idx = ffs(clipmask)-1;
@@ -567,17 +593,17 @@ do_clip_line( struct draw_stage *stage,
return; //discard nan
if (dp1 < 0.0F) {
- float t = dp1 / (dp1 - dp0);
+ float t = dp1 / (dp1 - dp0);
t1 = MAX2(t1, t);
}
if (dp0 < 0.0F) {
- float t = dp0 / (dp0 - dp1);
+ float t = dp0 / (dp0 - dp1);
t0 = MAX2(t0, t);
}
if (t0 + t1 >= 1.0F)
- return; /* discard */
+ return; /* discard */
clipmask &= ~(1 << plane_idx); /* turn off this plane's bit */
}
@@ -615,8 +641,7 @@ do_clip_line( struct draw_stage *stage,
static void
-clip_point( struct draw_stage *stage,
- struct prim_header *header )
+clip_point(struct draw_stage *stage, struct prim_header *header)
{
if (header->v[0]->clipmask == 0)
stage->next->point( stage->next, header );
@@ -630,8 +655,7 @@ clip_point( struct draw_stage *stage,
* the guard band and not just outside the vp.)
*/
static void
-clip_point_guard_xy( struct draw_stage *stage,
- struct prim_header *header )
+clip_point_guard_xy(struct draw_stage *stage, struct prim_header *header)
{
unsigned clipmask = header->v[0]->clipmask;
if ((clipmask & 0xffffffff) == 0)
@@ -658,8 +682,7 @@ clip_point_guard_xy( struct draw_stage *stage,
static void
-clip_first_point( struct draw_stage *stage,
- struct prim_header *header )
+clip_first_point(struct draw_stage *stage, struct prim_header *header)
{
stage->point = stage->draw->guard_band_points_xy ? clip_point_guard_xy : clip_point;
stage->point(stage, header);
@@ -667,8 +690,7 @@ clip_first_point( struct draw_stage *stage,
static void
-clip_line( struct draw_stage *stage,
- struct prim_header *header )
+clip_line(struct draw_stage *stage, struct prim_header *header)
{
unsigned clipmask = (header->v[0]->clipmask |
header->v[1]->clipmask);
@@ -686,8 +708,7 @@ clip_line( struct draw_stage *stage,
static void
-clip_tri( struct draw_stage *stage,
- struct prim_header *header )
+clip_tri(struct draw_stage *stage, struct prim_header *header)
{
unsigned clipmask = (header->v[0]->clipmask |
header->v[1]->clipmask |
@@ -715,12 +736,24 @@ find_interp(const struct draw_fragment_shader *fs, int *indexed_interp,
if (semantic_name == TGSI_SEMANTIC_COLOR ||
semantic_name == TGSI_SEMANTIC_BCOLOR) {
interp = indexed_interp[semantic_index];
+ } else if (semantic_name == TGSI_SEMANTIC_POSITION ||
+ semantic_name == TGSI_SEMANTIC_CLIPVERTEX) {
+ /* these inputs are handled specially always */
+ return -1;
} else {
/* Otherwise, search in the FS inputs, with a decent default
* if we don't find it.
+ * This probably only matters for layer, vpindex, culldist, maybe
+ * front_face.
*/
uint j;
- interp = TGSI_INTERPOLATE_PERSPECTIVE;
+ if (semantic_name == TGSI_SEMANTIC_LAYER ||
+ semantic_name == TGSI_SEMANTIC_VIEWPORT_INDEX) {
+ interp = TGSI_INTERPOLATE_CONSTANT;
+ }
+ else {
+ interp = TGSI_INTERPOLATE_PERSPECTIVE;
+ }
if (fs) {
for (j = 0; j < fs->info.num_inputs; j++) {
if (semantic_name == fs->info.input_semantic_name[j] &&
@@ -738,13 +771,16 @@ find_interp(const struct draw_fragment_shader *fs, int *indexed_interp,
* primitive that really requires clipping.
*/
static void
-clip_init_state( struct draw_stage *stage )
+clip_init_state(struct draw_stage *stage)
{
struct clip_stage *clipper = clip_stage( stage );
const struct draw_context *draw = stage->draw;
const struct draw_fragment_shader *fs = draw->fs.fragment_shader;
const struct tgsi_shader_info *info = draw_get_shader_info(draw);
uint i, j;
+ int indexed_interp[2];
+
+ clipper->pos_attr = draw_current_shader_position_output(draw);
/* We need to know for each attribute what kind of interpolation is
* done on it (flat, smooth or noperspective). But the information
@@ -765,7 +801,6 @@ clip_init_state( struct draw_stage *stage )
/* First pick up the interpolation mode for
* gl_Color/gl_SecondaryColor, with the correct default.
*/
- int indexed_interp[2];
indexed_interp[0] = indexed_interp[1] = draw->rasterizer->flatshade ?
TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE;
@@ -778,29 +813,33 @@ clip_init_state( struct draw_stage *stage )
}
}
- /* Then resolve the interpolation mode for every output attribute.
- *
- * Given how the rest of the code, the most efficient way is to
- * have a vector of flat-mode attributes, and a mask for
- * noperspective attributes.
- */
+ /* Then resolve the interpolation mode for every output attribute. */
- clipper->num_flat_attribs = 0;
- memset(clipper->noperspective_attribs, 0, sizeof(clipper->noperspective_attribs));
+ clipper->num_const_attribs = 0;
+ clipper->num_linear_attribs = 0;
+ clipper->num_perspect_attribs = 0;
for (i = 0; i < info->num_outputs; i++) {
/* Find the interpolation mode for a specific attribute */
int interp = find_interp(fs, indexed_interp,
info->output_semantic_name[i],
info->output_semantic_index[i]);
- /* If it's flat, add it to the flat vector. Otherwise update
- * the noperspective mask.
- */
-
- if (interp == TGSI_INTERPOLATE_CONSTANT) {
- clipper->flat_attribs[clipper->num_flat_attribs] = i;
- clipper->num_flat_attribs++;
- } else
- clipper->noperspective_attribs[i] = interp == TGSI_INTERPOLATE_LINEAR;
+ switch (interp) {
+ case TGSI_INTERPOLATE_CONSTANT:
+ clipper->const_attribs[clipper->num_const_attribs] = i;
+ clipper->num_const_attribs++;
+ break;
+ case TGSI_INTERPOLATE_LINEAR:
+ clipper->linear_attribs[clipper->num_linear_attribs] = i;
+ clipper->num_linear_attribs++;
+ break;
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ clipper->perspect_attribs[clipper->num_perspect_attribs] = i;
+ clipper->num_perspect_attribs++;
+ break;
+ default:
+ assert(interp == -1);
+ break;
+ }
}
/* Search the extra vertex attributes */
for (j = 0; j < draw->extra_shader_outputs.num; j++) {
@@ -808,39 +847,47 @@ clip_init_state( struct draw_stage *stage )
int interp = find_interp(fs, indexed_interp,
draw->extra_shader_outputs.semantic_name[j],
draw->extra_shader_outputs.semantic_index[j]);
- /* If it's flat, add it to the flat vector. Otherwise update
- * the noperspective mask.
- */
- if (interp == TGSI_INTERPOLATE_CONSTANT) {
- clipper->flat_attribs[clipper->num_flat_attribs] = i + j;
- clipper->num_flat_attribs++;
- } else
- clipper->noperspective_attribs[i + j] = interp == TGSI_INTERPOLATE_LINEAR;
+ switch (interp) {
+ case TGSI_INTERPOLATE_CONSTANT:
+ clipper->const_attribs[clipper->num_const_attribs] = i + j;
+ clipper->num_const_attribs++;
+ break;
+ case TGSI_INTERPOLATE_LINEAR:
+ clipper->linear_attribs[clipper->num_linear_attribs] = i + j;
+ clipper->num_linear_attribs++;
+ break;
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ clipper->perspect_attribs[clipper->num_perspect_attribs] = i + j;
+ clipper->num_perspect_attribs++;
+ break;
+ default:
+ assert(interp == -1);
+ break;
+ }
}
-
+
stage->tri = clip_tri;
stage->line = clip_line;
}
-static void clip_first_tri( struct draw_stage *stage,
- struct prim_header *header )
+static void clip_first_tri(struct draw_stage *stage,
+ struct prim_header *header)
{
clip_init_state( stage );
stage->tri( stage, header );
}
-static void clip_first_line( struct draw_stage *stage,
- struct prim_header *header )
+static void clip_first_line(struct draw_stage *stage,
+ struct prim_header *header)
{
clip_init_state( stage );
stage->line( stage, header );
}
-static void clip_flush( struct draw_stage *stage,
- unsigned flags )
+static void clip_flush(struct draw_stage *stage, unsigned flags)
{
stage->tri = clip_first_tri;
stage->line = clip_first_line;
@@ -848,13 +895,13 @@ static void clip_flush( struct draw_stage *stage,
}
-static void clip_reset_stipple_counter( struct draw_stage *stage )
+static void clip_reset_stipple_counter(struct draw_stage *stage)
{
stage->next->reset_stipple_counter( stage->next );
}
-static void clip_destroy( struct draw_stage *stage )
+static void clip_destroy(struct draw_stage *stage)
{
draw_free_temp_verts( stage );
FREE( stage );
@@ -865,10 +912,10 @@ static void clip_destroy( struct draw_stage *stage )
* Allocate a new clipper stage.
* \return pointer to new stage object
*/
-struct draw_stage *draw_clip_stage( struct draw_context *draw )
+struct draw_stage *draw_clip_stage(struct draw_context *draw)
{
struct clip_stage *clipper = CALLOC_STRUCT(clip_stage);
- if (clipper == NULL)
+ if (!clipper)
goto fail;
clipper->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c
index fc8293bd128..240f55190f5 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_cull.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c
@@ -251,7 +251,7 @@ static void cull_destroy( struct draw_stage *stage )
struct draw_stage *draw_cull_stage( struct draw_context *draw )
{
struct cull_stage *cull = CALLOC_STRUCT(cull_stage);
- if (cull == NULL)
+ if (!cull)
goto fail;
cull->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
index 0ea740861d6..cd285e6f97c 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
@@ -309,7 +309,7 @@ static void flatshade_destroy( struct draw_stage *stage )
struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
{
struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage);
- if (flatshade == NULL)
+ if (!flatshade)
goto fail;
flatshade->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c
index 5e0d8ce793d..f58e32b98a4 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_offset.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c
@@ -231,7 +231,7 @@ static void offset_destroy( struct draw_stage *stage )
struct draw_stage *draw_offset_stage( struct draw_context *draw )
{
struct offset_stage *offset = CALLOC_STRUCT(offset_stage);
- if (offset == NULL)
+ if (!offset)
goto fail;
offset->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index a51e91fe931..b58d7530783 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -577,7 +577,7 @@ static struct pstip_stage *
draw_pstip_stage(struct draw_context *draw, struct pipe_context *pipe)
{
struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage);
- if (pstip == NULL)
+ if (!pstip)
goto fail;
pstip->pipe = pipe;
@@ -742,7 +742,7 @@ draw_install_pstipple_stage(struct draw_context *draw,
* Create / install pgon stipple drawing / prim stage
*/
pstip = draw_pstip_stage( draw, pipe );
- if (pstip == NULL)
+ if (!pstip)
goto fail;
draw->pipeline.pstipple = &pstip->stage;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
index 381aa41530b..dcf05aac1d9 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
@@ -235,7 +235,7 @@ stipple_destroy( struct draw_stage *stage )
struct draw_stage *draw_stipple_stage( struct draw_context *draw )
{
struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage);
- if (stipple == NULL)
+ if (!stipple)
goto fail;
stipple->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c
index 7f958d9b985..52d87c6b291 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c
@@ -165,7 +165,7 @@ static void twoside_destroy( struct draw_stage *stage )
struct draw_stage *draw_twoside_stage( struct draw_context *draw )
{
struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage);
- if (twoside == NULL)
+ if (!twoside)
goto fail;
twoside->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
index 8e6435cdbb4..2517d610e71 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
@@ -255,7 +255,7 @@ draw_unfilled_prepare_outputs( struct draw_context *draw,
struct draw_stage *draw_unfilled_stage( struct draw_context *draw )
{
struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage);
- if (unfilled == NULL)
+ if (!unfilled)
goto fail;
unfilled->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_util.c b/src/gallium/auxiliary/draw/draw_pipe_util.c
index cb8c732afe8..53a42a6a0e4 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_util.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_util.c
@@ -78,7 +78,7 @@ boolean draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr )
unsigned i;
ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr );
- if (store == NULL)
+ if (!store)
return FALSE;
stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr );
diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c
index e69d84a37cd..01d07593d5c 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_validate.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c
@@ -326,7 +326,7 @@ static void validate_destroy( struct draw_stage *stage )
struct draw_stage *draw_validate_stage( struct draw_context *draw )
{
struct draw_stage *stage = CALLOC_STRUCT(draw_stage);
- if (stage == NULL)
+ if (!stage)
return NULL;
stage->draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
index 5cc866d7eee..f36706cee01 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
@@ -426,7 +426,7 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw,
struct vbuf_render *render )
{
struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage);
- if (vbuf == NULL)
+ if (!vbuf)
goto fail;
vbuf->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
index 38ac11a9adf..ae4a00eb630 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
@@ -202,7 +202,7 @@ static void wideline_destroy( struct draw_stage *stage )
struct draw_stage *draw_wide_line_stage( struct draw_context *draw )
{
struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage);
- if (wide == NULL)
+ if (!wide)
goto fail;
wide->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index 348b0e93bbc..adb6120d834 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -315,7 +315,7 @@ static void widepoint_destroy( struct draw_stage *stage )
struct draw_stage *draw_wide_point_stage( struct draw_context *draw )
{
struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage);
- if (wide == NULL)
+ if (!wide)
goto fail;
wide->stage.draw = draw;
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 3236e523a94..0204b439dee 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -109,7 +109,7 @@ draw_pt_arrays(struct draw_context *draw,
frontend = draw->pt.frontend;
- if (frontend ) {
+ if (frontend) {
if (draw->pt.prim != prim || draw->pt.opt != opt) {
/* In certain conditions switching primitives requires us to flush
* and validate the different stages. One example is when smooth
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index b6966a52ea4..c7b224a88f7 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -376,7 +376,7 @@ static void fetch_emit_destroy( struct draw_pt_middle_end *middle )
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw )
{
struct fetch_emit_middle_end *fetch_emit = CALLOC_STRUCT( fetch_emit_middle_end );
- if (fetch_emit == NULL)
+ if (!fetch_emit)
return NULL;
fetch_emit->cache = translate_cache_create();
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index 1501942eb44..438c9a6b9c4 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -200,7 +200,7 @@ draw_vs_lookup_variant( struct draw_vertex_shader *vs,
/* Else have to create a new one:
*/
variant = vs->create_variant( vs, key );
- if (variant == NULL)
+ if (!variant)
return NULL;
/* Add it to our list, could be smarter:
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 17b54b6fe74..abd64f5acd2 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -225,7 +225,7 @@ draw_create_vs_exec(struct draw_context *draw,
{
struct exec_vertex_shader *vs = CALLOC_STRUCT( exec_vertex_shader );
- if (vs == NULL)
+ if (!vs)
return NULL;
/* we make a private copy of the tokens */
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
index ac3999efc68..c92e4317216 100644
--- a/src/gallium/auxiliary/draw/draw_vs_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c
@@ -86,7 +86,7 @@ draw_create_vs_llvm(struct draw_context *draw,
{
struct llvm_vertex_shader *vs = CALLOC_STRUCT( llvm_vertex_shader );
- if (vs == NULL)
+ if (!vs)
return NULL;
/* we make a private copy of the tokens */
diff --git a/src/gallium/auxiliary/draw/draw_vs_variant.c b/src/gallium/auxiliary/draw/draw_vs_variant.c
index ce3a608c1d1..af36a86674d 100644
--- a/src/gallium/auxiliary/draw/draw_vs_variant.c
+++ b/src/gallium/auxiliary/draw/draw_vs_variant.c
@@ -302,7 +302,7 @@ draw_vs_create_variant_generic( struct draw_vertex_shader *vs,
struct translate_key fetch, emit;
struct draw_vs_variant_generic *vsvg = CALLOC_STRUCT( draw_vs_variant_generic );
- if (vsvg == NULL)
+ if (!vsvg)
return NULL;
vsvg->base.key = *key;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 50ae192325b..01c6ba96e3f 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -194,7 +194,7 @@ lp_build_min_simple(struct lp_build_context *bld,
}
}
- if(intrinsic) {
+ if (intrinsic) {
/* We need to handle nan's for floating point numbers. If one of the
* inputs is nan the other should be returned (required by both D3D10+
* and OpenCL).
@@ -376,7 +376,7 @@ lp_build_max_simple(struct lp_build_context *bld,
}
}
- if(intrinsic) {
+ if (intrinsic) {
if (util_cpu_caps.has_sse && type.floating &&
nan_behavior != GALLIVM_NAN_BEHAVIOR_UNDEFINED &&
nan_behavior != GALLIVM_NAN_RETURN_OTHER_SECOND_NONNAN &&
@@ -518,7 +518,7 @@ lp_build_add(struct lp_build_context *bld,
}
}
- if(intrinsic)
+ if (intrinsic)
return lp_build_intrinsic_binary(builder, intrinsic, lp_build_vec_type(bld->gallivm, bld->type), a, b);
}
@@ -810,7 +810,7 @@ lp_build_sub(struct lp_build_context *bld,
}
}
- if(intrinsic)
+ if (intrinsic)
return lp_build_intrinsic_binary(builder, intrinsic, lp_build_vec_type(bld->gallivm, bld->type), a, b);
}
@@ -3287,7 +3287,7 @@ lp_build_log2_approx(struct lp_build_context *bld,
logexp = LLVMBuildSIToFP(builder, logexp, vec_type, "");
}
- if(p_log2) {
+ if (p_log2) {
/* mant = 1 + (float) mantissa(x) */
mant = LLVMBuildAnd(builder, i, mantmask, "");
mant = LLVMBuildOr(builder, mant, one, "");
@@ -3335,15 +3335,15 @@ lp_build_log2_approx(struct lp_build_context *bld,
}
}
- if(p_exp) {
+ if (p_exp) {
exp = LLVMBuildBitCast(builder, exp, vec_type, "");
*p_exp = exp;
}
- if(p_floor_log2)
+ if (p_floor_log2)
*p_floor_log2 = logexp;
- if(p_log2)
+ if (p_log2)
*p_log2 = res;
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c
index 9cd7c5553cf..58fdcc94437 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c
@@ -373,7 +373,7 @@ lp_build_const_aos(struct gallivm_state *gallivm,
lp_build_elem_type(gallivm, type);
- if(swizzle == NULL)
+ if (!swizzle)
swizzle = default_swizzle;
elems[swizzle[0]] = lp_build_const_elem(gallivm, type, r);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 28c7a86316e..09c1b379172 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -1548,13 +1548,21 @@ emit_fetch_gs_input(
swizzle_index);
assert(res);
-
- if (stype == TGSI_TYPE_UNSIGNED) {
+ if (stype == TGSI_TYPE_DOUBLE) {
+ LLVMValueRef swizzle_index = lp_build_const_int32(gallivm, swizzle + 1);
+ LLVMValueRef res2;
+ res2 = bld->gs_iface->fetch_input(bld->gs_iface, bld_base,
+ reg->Dimension.Indirect,
+ vertex_index,
+ reg->Register.Indirect,
+ attrib_index,
+ swizzle_index);
+ assert(res2);
+ res = emit_fetch_double(bld_base, stype, res, res2);
+ } else if (stype == TGSI_TYPE_UNSIGNED) {
res = LLVMBuildBitCast(builder, res, bld_base->uint_bld.vec_type, "");
} else if (stype == TGSI_TYPE_SIGNED) {
res = LLVMBuildBitCast(builder, res, bld_base->int_bld.vec_type, "");
- } else if (stype == TGSI_TYPE_DOUBLE) {
- res = LLVMBuildBitCast(builder, res, bld_base->dbl_bld.vec_type, "");
}
return res;
@@ -1701,15 +1709,15 @@ emit_fetch_deriv(
LLVMValueRef *ddx,
LLVMValueRef *ddy)
{
- if(res)
+ if (res)
*res = src;
/* TODO: use interpolation coeffs for inputs */
- if(ddx)
+ if (ddx)
*ddx = lp_build_ddx(&bld->bld_base.base, src);
- if(ddy)
+ if (ddy)
*ddy = lp_build_ddy(&bld->bld_base.base, src);
}
diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
index efceb85e38d..c5c33327702 100644
--- a/src/gallium/auxiliary/hud/hud_context.c
+++ b/src/gallium/auxiliary/hud/hud_context.c
@@ -1127,12 +1127,20 @@ print_help(struct pipe_screen *screen)
}
if (screen->get_driver_query_info){
+ boolean skipping = false;
struct pipe_driver_query_info info;
num_queries = screen->get_driver_query_info(screen, 0, NULL);
for (i = 0; i < num_queries; i++){
screen->get_driver_query_info(screen, i, &info);
- printf(" %s\n", info.name);
+ if (info.flags & PIPE_DRIVER_QUERY_FLAG_DONT_LIST) {
+ if (!skipping)
+ puts(" ...");
+ skipping = true;
+ } else {
+ printf(" %s\n", info.name);
+ skipping = false;
+ }
}
}
diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c
index 86c2ffadbc8..5def6d3f32a 100644
--- a/src/gallium/auxiliary/nir/tgsi_to_nir.c
+++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c
@@ -22,6 +22,10 @@
* IN THE SOFTWARE.
*/
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
+#endif
+
#include "util/ralloc.h"
#include "glsl/nir/nir.h"
#include "glsl/nir/nir_control_flow.h"
@@ -464,7 +468,7 @@ ttn_emit_immediate(struct ttn_compile *c)
nir_builder_instr_insert(b, &load_const->instr);
}
-static nir_src
+static nir_ssa_def *
ttn_src_for_indirect(struct ttn_compile *c, struct tgsi_ind_register *indirect);
/* generate either a constant or indirect deref chain for accessing an
@@ -483,7 +487,7 @@ ttn_array_deref(struct ttn_compile *c, nir_intrinsic_instr *instr,
if (indirect) {
arr->deref_array_type = nir_deref_array_type_indirect;
- arr->indirect = ttn_src_for_indirect(c, indirect);
+ arr->indirect = nir_src_for_ssa(ttn_src_for_indirect(c, indirect));
} else {
arr->deref_array_type = nir_deref_array_type_direct;
}
@@ -582,19 +586,14 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
switch (file) {
case TGSI_FILE_INPUT:
- op = indirect ? nir_intrinsic_load_input_indirect :
- nir_intrinsic_load_input;
+ op = nir_intrinsic_load_input;
assert(!dim);
break;
case TGSI_FILE_CONSTANT:
if (dim) {
- op = indirect ? nir_intrinsic_load_ubo_indirect :
- nir_intrinsic_load_ubo;
- /* convert index from vec4 to byte: */
- index *= 16;
+ op = nir_intrinsic_load_ubo;
} else {
- op = indirect ? nir_intrinsic_load_uniform_indirect :
- nir_intrinsic_load_uniform;
+ op = nir_intrinsic_load_uniform;
}
break;
default:
@@ -605,7 +604,6 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
load = nir_intrinsic_instr_create(b->shader, op);
load->num_components = 4;
- load->const_index[0] = index;
if (dim) {
if (dimind) {
load->src[srcn] =
@@ -618,17 +616,26 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
}
srcn++;
}
- if (indirect) {
- load->src[srcn] = ttn_src_for_indirect(c, indirect);
- if (dim) {
- assert(load->src[srcn].is_ssa);
- /* we also need to covert vec4 to byte here too: */
- load->src[srcn] =
- nir_src_for_ssa(nir_ishl(b, load->src[srcn].ssa,
- nir_imm_int(b, 4)));
+
+ nir_ssa_def *offset;
+ if (dim) {
+ /* UBO loads don't have a const_index[0] base offset. */
+ offset = nir_imm_int(b, index);
+ if (indirect) {
+ offset = nir_iadd(b, offset, ttn_src_for_indirect(c, indirect));
+ }
+ /* UBO offsets are in bytes, but TGSI gives them to us in vec4's */
+ offset = nir_ishl(b, offset, nir_imm_int(b, 4));
+ } else {
+ load->const_index[0] = index;
+ if (indirect) {
+ offset = ttn_src_for_indirect(c, indirect);
+ } else {
+ offset = nir_imm_int(b, 0);
}
- srcn++;
}
+ load->src[srcn++] = nir_src_for_ssa(offset);
+
nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
nir_builder_instr_insert(b, &load->instr);
@@ -644,7 +651,7 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
return src;
}
-static nir_src
+static nir_ssa_def *
ttn_src_for_indirect(struct ttn_compile *c, struct tgsi_ind_register *indirect)
{
nir_builder *b = &c->build;
@@ -656,7 +663,7 @@ ttn_src_for_indirect(struct ttn_compile *c, struct tgsi_ind_register *indirect)
indirect->File,
indirect->Index,
NULL, NULL, NULL);
- return nir_src_for_ssa(nir_imov_alu(b, src, 1));
+ return nir_imov_alu(b, src, 1);
}
static nir_alu_dest
@@ -725,7 +732,7 @@ ttn_get_dest(struct ttn_compile *c, struct tgsi_full_dst_register *tgsi_fdst)
if (tgsi_dst->Indirect && (tgsi_dst->File != TGSI_FILE_TEMPORARY)) {
nir_src *indirect = ralloc(c->build.shader, nir_src);
- *indirect = ttn_src_for_indirect(c, &tgsi_fdst->Indirect);
+ *indirect = nir_src_for_ssa(ttn_src_for_indirect(c, &tgsi_fdst->Indirect));
dest.dest.reg.indirect = indirect;
}
@@ -1923,9 +1930,10 @@ ttn_add_output_stores(struct ttn_compile *c)
nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_output);
unsigned loc = var->data.driver_location + i;
store->num_components = 4;
- store->const_index[0] = loc;
store->src[0].reg.reg = c->output_regs[loc].reg;
store->src[0].reg.base_offset = c->output_regs[loc].offset;
+ store->const_index[0] = loc;
+ store->src[1] = nir_src_for_ssa(nir_imm_int(b, 0));
nir_builder_instr_insert(b, &store->instr);
}
}
diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c b/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c
index 5539a730b4c..c8e1f134c99 100644
--- a/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c
+++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c
@@ -33,9 +33,10 @@
#include "sw/kms-dri/kms_dri_sw_winsys.h"
#include "sw/null/null_sw_winsys.h"
#include "sw/wrapper/wrapper_sw_winsys.h"
-#include "target-helpers/inline_sw_helper.h"
+#include "target-helpers/sw_helper_public.h"
#include "state_tracker/drisw_api.h"
#include "state_tracker/sw_driver.h"
+#include "state_tracker/sw_winsys.h"
struct pipe_loader_sw_device {
struct pipe_loader_device base;
@@ -136,7 +137,7 @@ pipe_loader_sw_probe_dri(struct pipe_loader_device **devs, struct drisw_loader_f
if (!pipe_loader_sw_probe_init_common(sdev))
goto fail;
- for (i = 0; sdev->dd->winsys; i++) {
+ for (i = 0; sdev->dd->winsys[i].name; i++) {
if (strcmp(sdev->dd->winsys[i].name, "dri") == 0) {
sdev->ws = sdev->dd->winsys[i].create_winsys(drisw_lf);
break;
@@ -168,7 +169,7 @@ pipe_loader_sw_probe_kms(struct pipe_loader_device **devs, int fd)
if (!pipe_loader_sw_probe_init_common(sdev))
goto fail;
- for (i = 0; sdev->dd->winsys; i++) {
+ for (i = 0; sdev->dd->winsys[i].name; i++) {
if (strcmp(sdev->dd->winsys[i].name, "kms_dri") == 0) {
sdev->ws = sdev->dd->winsys[i].create_winsys(fd);
break;
@@ -199,7 +200,7 @@ pipe_loader_sw_probe_null(struct pipe_loader_device **devs)
if (!pipe_loader_sw_probe_init_common(sdev))
goto fail;
- for (i = 0; sdev->dd->winsys; i++) {
+ for (i = 0; sdev->dd->winsys[i].name; i++) {
if (strcmp(sdev->dd->winsys[i].name, "null") == 0) {
sdev->ws = sdev->dd->winsys[i].create_winsys();
break;
@@ -222,7 +223,7 @@ pipe_loader_sw_probe(struct pipe_loader_device **devs, int ndev)
{
int i = 1;
- if (i < ndev) {
+ if (i <= ndev) {
if (!pipe_loader_sw_probe_null(devs)) {
i--;
}
@@ -244,7 +245,7 @@ pipe_loader_sw_probe_wrapped(struct pipe_loader_device **dev,
if (!pipe_loader_sw_probe_init_common(sdev))
goto fail;
- for (i = 0; sdev->dd->winsys; i++) {
+ for (i = 0; sdev->dd->winsys[i].name; i++) {
if (strcmp(sdev->dd->winsys[i].name, "wrapped") == 0) {
sdev->ws = sdev->dd->winsys[i].create_winsys(screen);
break;
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
index ba48d461d5c..803c1d39192 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
@@ -163,7 +163,7 @@ pb_map(struct pb_buffer *buf,
unsigned flags, void *flush_ctx)
{
assert(buf);
- if(!buf)
+ if (!buf)
return NULL;
assert(pipe_is_referenced(&buf->reference));
return buf->vtbl->map(buf, flags, flush_ctx);
@@ -174,7 +174,7 @@ static inline void
pb_unmap(struct pb_buffer *buf)
{
assert(buf);
- if(!buf)
+ if (!buf)
return;
assert(pipe_is_referenced(&buf->reference));
buf->vtbl->unmap(buf);
@@ -187,7 +187,7 @@ pb_get_base_buffer( struct pb_buffer *buf,
pb_size *offset )
{
assert(buf);
- if(!buf) {
+ if (!buf) {
base_buf = NULL;
offset = 0;
return;
@@ -204,7 +204,7 @@ static inline enum pipe_error
pb_validate(struct pb_buffer *buf, struct pb_validate *vl, unsigned flags)
{
assert(buf);
- if(!buf)
+ if (!buf)
return PIPE_ERROR;
assert(buf->vtbl->validate);
return buf->vtbl->validate(buf, vl, flags);
@@ -215,7 +215,7 @@ static inline void
pb_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence)
{
assert(buf);
- if(!buf)
+ if (!buf)
return;
assert(buf->vtbl->fence);
buf->vtbl->fence(buf, fence);
@@ -226,7 +226,7 @@ static inline void
pb_destroy(struct pb_buffer *buf)
{
assert(buf);
- if(!buf)
+ if (!buf)
return;
assert(!pipe_is_referenced(&buf->reference));
buf->vtbl->destroy(buf);
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
index 08935b4dec7..2678268e923 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
@@ -626,7 +626,7 @@ fenced_buffer_copy_storage_to_gpu_locked(struct fenced_buffer *fenced_buf)
assert(fenced_buf->buffer);
map = pb_map(fenced_buf->buffer, PB_USAGE_CPU_WRITE, NULL);
- if(!map)
+ if (!map)
return PIPE_ERROR;
memcpy(map, fenced_buf->data, fenced_buf->size);
@@ -646,7 +646,7 @@ fenced_buffer_copy_storage_to_cpu_locked(struct fenced_buffer *fenced_buf)
assert(fenced_buf->buffer);
map = pb_map(fenced_buf->buffer, PB_USAGE_CPU_READ, NULL);
- if(!map)
+ if (!map)
return PIPE_ERROR;
memcpy(fenced_buf->data, map, fenced_buf->size);
@@ -720,7 +720,7 @@ fenced_buffer_map(struct pb_buffer *buf,
map = fenced_buf->data;
}
- if(map) {
+ if (map) {
++fenced_buf->mapcount;
fenced_buf->flags |= flags & PB_USAGE_CPU_READ_WRITE;
}
@@ -764,7 +764,7 @@ fenced_buffer_validate(struct pb_buffer *buf,
pipe_mutex_lock(fenced_mgr->mutex);
- if(!vl) {
+ if (!vl) {
/* invalidate */
fenced_buf->vl = NULL;
fenced_buf->validation_flags = 0;
@@ -927,7 +927,7 @@ fenced_bufmgr_create_buffer(struct pb_manager *mgr,
}
fenced_buf = CALLOC_STRUCT(fenced_buffer);
- if(!fenced_buf)
+ if (!fenced_buf)
goto no_buffer;
pipe_reference_init(&fenced_buf->base.reference, 1);
@@ -1042,7 +1042,7 @@ fenced_bufmgr_create(struct pb_manager *provider,
{
struct fenced_manager *fenced_mgr;
- if(!provider)
+ if (!provider)
return NULL;
fenced_mgr = CALLOC_STRUCT(fenced_manager);
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c
index b97771457d6..ea2f2fa107c 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c
@@ -132,7 +132,7 @@ pb_malloc_buffer_create(pb_size size,
/* TODO: do a single allocation */
buf = CALLOC_STRUCT(malloc_buffer);
- if(!buf)
+ if (!buf)
return NULL;
pipe_reference_init(&buf->base.reference, 1);
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c
index 47cbaeb20ac..f71bacc8820 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c
@@ -67,7 +67,7 @@ pb_alt_manager_create_buffer(struct pb_manager *_mgr,
struct pb_buffer *buf;
buf = mgr->provider1->create_buffer(mgr->provider1, size, desc);
- if(buf)
+ if (buf)
return buf;
buf = mgr->provider2->create_buffer(mgr->provider2, size, desc);
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
index cc8ae84bb1b..1c8c25d6f76 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
@@ -354,7 +354,7 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr,
}
}
- if(buf) {
+ if (buf) {
mgr->cache_size -= buf->base.size;
LIST_DEL(&buf->head);
--mgr->numDelayed;
@@ -367,7 +367,7 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr,
pipe_mutex_unlock(mgr->mutex);
buf = CALLOC_STRUCT(pb_cache_buffer);
- if(!buf)
+ if (!buf)
return NULL;
buf->buffer = mgr->provider->create_buffer(mgr->provider, size, desc);
@@ -454,7 +454,7 @@ pb_cache_manager_create(struct pb_manager *provider,
{
struct pb_cache_manager *mgr;
- if(!provider)
+ if (!provider)
return NULL;
mgr = CALLOC_STRUCT(pb_cache_manager);
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
index 7ad70f293a6..3d3a7aba7fb 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
@@ -160,7 +160,7 @@ pb_debug_buffer_fill(struct pb_debug_buffer *buf)
map = pb_map(buf->buffer, PB_USAGE_CPU_WRITE, NULL);
assert(map);
- if(map) {
+ if (map) {
fill_random_pattern(map, buf->underflow_size);
fill_random_pattern(map + buf->underflow_size + buf->base.size,
buf->overflow_size);
@@ -183,7 +183,7 @@ pb_debug_buffer_check(struct pb_debug_buffer *buf)
PB_USAGE_CPU_READ |
PB_USAGE_UNSYNCHRONIZED, NULL);
assert(map);
- if(map) {
+ if (map) {
boolean underflow, overflow;
pb_size min_ofs, max_ofs;
@@ -256,15 +256,13 @@ pb_debug_buffer_map(struct pb_buffer *_buf,
pb_debug_buffer_check(buf);
map = pb_map(buf->buffer, flags, flush_ctx);
- if(!map)
+ if (!map)
return NULL;
- if(map) {
- pipe_mutex_lock(buf->mutex);
- ++buf->map_count;
- debug_backtrace_capture(buf->map_backtrace, 1, PB_DEBUG_MAP_BACKTRACE);
- pipe_mutex_unlock(buf->mutex);
- }
+ pipe_mutex_lock(buf->mutex);
+ ++buf->map_count;
+ debug_backtrace_capture(buf->map_backtrace, 1, PB_DEBUG_MAP_BACKTRACE);
+ pipe_mutex_unlock(buf->mutex);
return (uint8_t *)map + buf->underflow_size;
}
@@ -375,7 +373,7 @@ pb_debug_manager_create_buffer(struct pb_manager *_mgr,
assert(desc->alignment);
buf = CALLOC_STRUCT(pb_debug_buffer);
- if(!buf)
+ if (!buf)
return NULL;
real_size = mgr->underflow_size + size + mgr->overflow_size;
@@ -462,7 +460,7 @@ pb_debug_manager_create(struct pb_manager *provider,
{
struct pb_debug_manager *mgr;
- if(!provider)
+ if (!provider)
return NULL;
mgr = CALLOC_STRUCT(pb_debug_manager);
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c
index 72099ba5850..14de61b163f 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c
@@ -252,7 +252,7 @@ mm_bufmgr_create_from_buffer(struct pb_buffer *buffer,
{
struct mm_pb_manager *mm;
- if(!buffer)
+ if (!buffer)
return NULL;
mm = CALLOC_STRUCT(mm_pb_manager);
@@ -300,7 +300,7 @@ mm_bufmgr_create(struct pb_manager *provider,
struct pb_manager *mgr;
struct pb_desc desc;
- if(!provider)
+ if (!provider)
return NULL;
memset(&desc, 0, sizeof(desc));
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c
index c20e2dca02d..4885d68c398 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c
@@ -151,7 +151,7 @@ pb_ondemand_buffer_instantiate(struct pb_ondemand_buffer *buf)
return PIPE_ERROR_OUT_OF_MEMORY;
map = pb_map(buf->buffer, PB_USAGE_CPU_READ, NULL);
- if(!map) {
+ if (!map) {
pb_reference(&buf->buffer, NULL);
return PIPE_ERROR;
}
@@ -241,7 +241,7 @@ pb_ondemand_manager_create_buffer(struct pb_manager *_mgr,
struct pb_ondemand_buffer *buf;
buf = CALLOC_STRUCT(pb_ondemand_buffer);
- if(!buf)
+ if (!buf)
return NULL;
pipe_reference_init(&buf->base.reference, 1);
@@ -288,11 +288,11 @@ pb_ondemand_manager_create(struct pb_manager *provider)
{
struct pb_ondemand_manager *mgr;
- if(!provider)
+ if (!provider)
return NULL;
mgr = CALLOC_STRUCT(pb_ondemand_manager);
- if(!mgr)
+ if (!mgr)
return NULL;
mgr->base.destroy = pb_ondemand_manager_destroy;
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c
index 56a5e82ece0..98877b46352 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c
@@ -261,7 +261,7 @@ pool_bufmgr_create(struct pb_manager *provider,
struct pool_buffer *pool_buf;
pb_size i;
- if(!provider)
+ if (!provider)
return NULL;
pool = CALLOC_STRUCT(pool_pb_manager);
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c
index aadeaa087f4..fdbcf9e5c44 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c
@@ -542,7 +542,7 @@ pb_slab_range_manager_create(struct pb_manager *provider,
pb_size bufSize;
unsigned i;
- if(!provider)
+ if (!provider)
return NULL;
mgr = CALLOC_STRUCT(pb_slab_range_manager);
diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c
index 657ac23ef25..8489842effd 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_validate.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c
@@ -66,7 +66,7 @@ pb_validate_add_buffer(struct pb_validate *vl,
unsigned flags)
{
assert(buf);
- if(!buf)
+ if (!buf)
return PIPE_ERROR;
assert(flags & PB_USAGE_GPU_READ_WRITE);
@@ -94,7 +94,7 @@ pb_validate_add_buffer(struct pb_validate *vl,
new_entries = (struct pb_validate_entry *)REALLOC(vl->entries,
vl->size*sizeof(struct pb_validate_entry),
new_size*sizeof(struct pb_validate_entry));
- if(!new_entries)
+ if (!new_entries)
return PIPE_ERROR_OUT_OF_MEMORY;
memset(new_entries + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_validate_entry));
@@ -177,7 +177,7 @@ pb_validate_create()
struct pb_validate *vl;
vl = CALLOC_STRUCT(pb_validate);
- if(!vl)
+ if (!vl)
return NULL;
vl->size = PB_VALIDATE_INITIAL_SIZE;
diff --git a/src/gallium/auxiliary/postprocess/pp_init.c b/src/gallium/auxiliary/postprocess/pp_init.c
index bdf66e6d63a..b9eff78bf4f 100644
--- a/src/gallium/auxiliary/postprocess/pp_init.c
+++ b/src/gallium/auxiliary/postprocess/pp_init.c
@@ -58,7 +58,7 @@ pp_init(struct pipe_context *pipe, const unsigned int *enabled,
ppq = CALLOC(1, sizeof(struct pp_queue_t));
- if (ppq == NULL) {
+ if (!ppq) {
pp_debug("Unable to allocate memory for ppq.\n");
goto error;
}
diff --git a/src/gallium/auxiliary/postprocess/pp_mlaa.c b/src/gallium/auxiliary/postprocess/pp_mlaa.c
index 024a24895c8..a3f58b52f48 100644
--- a/src/gallium/auxiliary/postprocess/pp_mlaa.c
+++ b/src/gallium/auxiliary/postprocess/pp_mlaa.c
@@ -238,7 +238,7 @@ pp_jimenezmlaa_init_run(struct pp_queue_t *ppq, unsigned int n,
tmp_text = CALLOC(sizeof(blend2fs_1) + sizeof(blend2fs_2) +
IMM_SPACE, sizeof(char));
- if (tmp_text == NULL) {
+ if (!tmp_text) {
pp_debug("Failed to allocate shader space\n");
return FALSE;
}
diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c
index caa2062f4cf..c6c7b88eea3 100644
--- a/src/gallium/auxiliary/postprocess/pp_run.c
+++ b/src/gallium/auxiliary/postprocess/pp_run.c
@@ -262,7 +262,7 @@ pp_tgsi_to_state(struct pipe_context *pipe, const char *text, bool isvs,
*/
tokens = tgsi_alloc_tokens(PP_MAX_TOKENS);
- if (tokens == NULL) {
+ if (!tokens) {
pp_debug("Failed to allocate temporary token storage.\n");
return NULL;
}
diff --git a/src/gallium/auxiliary/target-helpers/sw_helper.h b/src/gallium/auxiliary/target-helpers/sw_helper.h
new file mode 100644
index 00000000000..ae5f3de92ba
--- /dev/null
+++ b/src/gallium/auxiliary/target-helpers/sw_helper.h
@@ -0,0 +1,73 @@
+
+#ifndef SW_HELPER_H
+#define SW_HELPER_H
+
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+#include "target-helpers/sw_helper_public.h"
+#include "state_tracker/sw_winsys.h"
+
+
+/* Helper function to choose and instantiate one of the software rasterizers:
+ * llvmpipe, softpipe.
+ */
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+#ifdef GALLIUM_VIRGL
+#include "virgl/virgl_public.h"
+#include "virgl/vtest/virgl_vtest_public.h"
+#endif
+
+static inline struct pipe_screen *
+sw_screen_create_named(struct sw_winsys *winsys, const char *driver)
+{
+ struct pipe_screen *screen = NULL;
+
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+ screen = llvmpipe_create_screen(winsys);
+#endif
+
+#if defined(GALLIUM_VIRGL)
+ if (screen == NULL && strcmp(driver, "virpipe") == 0) {
+ struct virgl_winsys *vws;
+ vws = virgl_vtest_winsys_wrap(winsys);
+ screen = virgl_create_screen(vws);
+ }
+#endif
+
+#if defined(GALLIUM_SOFTPIPE)
+ if (screen == NULL)
+ screen = softpipe_create_screen(winsys);
+#endif
+
+ return screen;
+}
+
+
+struct pipe_screen *
+sw_screen_create(struct sw_winsys *winsys)
+{
+ const char *default_driver;
+ const char *driver;
+
+#if defined(GALLIUM_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+ return sw_screen_create_named(winsys, driver);
+}
+
+#endif
diff --git a/src/gallium/auxiliary/target-helpers/sw_helper_public.h b/src/gallium/auxiliary/target-helpers/sw_helper_public.h
new file mode 100644
index 00000000000..12b301b6ab4
--- /dev/null
+++ b/src/gallium/auxiliary/target-helpers/sw_helper_public.h
@@ -0,0 +1,10 @@
+#ifndef _SW_HELPER_PUBLIC_H
+#define _SW_HELPER_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+sw_screen_create(struct sw_winsys *winsys);
+
+#endif /* _SW_HELPER_PUBLIC_H */
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index d14372feb30..88ecb2a31cb 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -321,7 +321,7 @@ iter_instruction(
}
info = tgsi_get_opcode_info( inst->Instruction.Opcode );
- if (info == NULL) {
+ if (!info) {
report_error( ctx, "(%u): Invalid instruction opcode", inst->Instruction.Opcode );
return TRUE;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index f2f518130fb..4aaf8dfe6d8 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -1018,7 +1018,7 @@ static void validate( unsigned opcode,
#ifdef DEBUG
const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );
assert(info);
- if(info) {
+ if (info) {
assert(nr_dst == info->num_dst);
assert(nr_src == info->num_src);
}
@@ -1083,7 +1083,7 @@ ureg_emit_label(struct ureg_program *ureg,
{
union tgsi_any_token *out, *insn;
- if(!label_token)
+ if (!label_token)
return;
out = get_tokens( ureg, DOMAIN_INSN, 1 );
@@ -1843,7 +1843,7 @@ ureg_create_with_screen(unsigned processor, struct pipe_screen *screen)
{
int i;
struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );
- if (ureg == NULL)
+ if (!ureg)
goto no_ureg;
ureg->processor = processor;
diff --git a/src/gallium/auxiliary/translate/translate_cache.c b/src/gallium/auxiliary/translate/translate_cache.c
index 2bed02a454b..8aad7cdfb2b 100644
--- a/src/gallium/auxiliary/translate/translate_cache.c
+++ b/src/gallium/auxiliary/translate/translate_cache.c
@@ -40,7 +40,7 @@ struct translate_cache {
struct translate_cache * translate_cache_create( void )
{
struct translate_cache *cache = MALLOC_STRUCT(translate_cache);
- if (cache == NULL) {
+ if (!cache) {
return NULL;
}
diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c
index 45eb63231e3..3b460e11c34 100644
--- a/src/gallium/auxiliary/translate/translate_generic.c
+++ b/src/gallium/auxiliary/translate/translate_generic.c
@@ -772,7 +772,7 @@ struct translate *translate_generic_create( const struct translate_key *key )
struct translate_generic *tg = CALLOC_STRUCT(translate_generic);
unsigned i;
- if (tg == NULL)
+ if (!tg)
return NULL;
assert(key->nr_elements <= TRANSLATE_MAX_ATTRIBS);
diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c
index c7b6c36fcfa..b3c3b305962 100644
--- a/src/gallium/auxiliary/translate/translate_sse.c
+++ b/src/gallium/auxiliary/translate/translate_sse.c
@@ -1486,7 +1486,7 @@ translate_sse2_create(const struct translate_key *key)
goto fail;
p = os_malloc_aligned(sizeof(struct translate_sse), 16);
- if (p == NULL)
+ if (!p)
goto fail;
memset(p, 0, sizeof(*p));
diff --git a/src/gallium/auxiliary/util/u_bitmask.c b/src/gallium/auxiliary/util/u_bitmask.c
index b19be29a5a4..c22f5068923 100644
--- a/src/gallium/auxiliary/util/u_bitmask.c
+++ b/src/gallium/auxiliary/util/u_bitmask.c
@@ -66,7 +66,7 @@ util_bitmask_create(void)
struct util_bitmask *bm;
bm = MALLOC_STRUCT(util_bitmask);
- if(!bm)
+ if (!bm)
return NULL;
bm->words = (util_bitmask_word *)CALLOC(UTIL_BITMASK_INITIAL_WORDS, sizeof(util_bitmask_word));
@@ -114,7 +114,7 @@ util_bitmask_resize(struct util_bitmask *bm,
new_words = (util_bitmask_word *)REALLOC((void *)bm->words,
bm->size / UTIL_BITMASK_BITS_PER_BYTE,
new_size / UTIL_BITMASK_BITS_PER_BYTE);
- if(!new_words)
+ if (!new_words)
return FALSE;
memset(new_words + bm->size/UTIL_BITMASK_BITS_PER_WORD,
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index fccc92c06c4..05b4567130e 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -1825,6 +1825,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_framebuffer_state fb_state;
+ unsigned num_layers;
assert(dstsurf->texture);
if (!dstsurf->texture)
@@ -1852,10 +1853,19 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0);
- blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
- blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
- UTIL_BLITTER_ATTRIB_COLOR, color);
+
+ num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
+ if (num_layers > 1 && ctx->has_layered) {
+ blitter_set_common_draw_rect_state(ctx, FALSE, TRUE);
+ blitter_set_clear_color(ctx, color);
+ blitter_draw(ctx, dstx, dsty, dstx+width, dsty+height, 0, num_layers);
+ }
+ else {
+ blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
+ blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
+ UTIL_BLITTER_ATTRIB_COLOR, color);
+ }
blitter_restore_vertex_states(ctx);
blitter_restore_fragment_states(ctx);
@@ -1877,6 +1887,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_framebuffer_state fb_state;
struct pipe_stencil_ref sr = { { 0 } };
+ unsigned num_layers;
assert(dstsurf->texture);
if (!dstsurf->texture)
@@ -1920,11 +1931,19 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0);
- blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
- blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height,
- (float) depth,
- UTIL_BLITTER_ATTRIB_NONE, NULL);
+
+ num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
+ if (num_layers > 1 && ctx->has_layered) {
+ blitter_set_common_draw_rect_state(ctx, FALSE, TRUE);
+ blitter_draw(ctx, dstx, dsty, dstx+width, dsty+height, (float) depth, num_layers);
+ }
+ else {
+ blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
+ blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height,
+ (float) depth,
+ UTIL_BLITTER_ATTRIB_NONE, NULL);
+ }
blitter_restore_vertex_states(ctx);
blitter_restore_fragment_states(ctx);
diff --git a/src/gallium/auxiliary/util/u_cache.c b/src/gallium/auxiliary/util/u_cache.c
index da0856981eb..acc82bac0ff 100644
--- a/src/gallium/auxiliary/util/u_cache.c
+++ b/src/gallium/auxiliary/util/u_cache.c
@@ -95,7 +95,7 @@ util_cache_create(uint32_t (*hash)(const void *key),
struct util_cache *cache;
cache = CALLOC_STRUCT(util_cache);
- if(!cache)
+ if (!cache)
return NULL;
cache->hash = hash;
diff --git a/src/gallium/auxiliary/util/u_cpu_detect.c b/src/gallium/auxiliary/util/u_cpu_detect.c
index d1f9e978682..c719d3a77f0 100644
--- a/src/gallium/auxiliary/util/u_cpu_detect.c
+++ b/src/gallium/auxiliary/util/u_cpu_detect.c
@@ -182,7 +182,7 @@ static int has_cpuid(void)
static inline void
cpuid(uint32_t ax, uint32_t *p)
{
-#if (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO)) && defined(PIPE_ARCH_X86)
+#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
__asm __volatile (
"xchgl %%ebx, %1\n\t"
"cpuid\n\t"
@@ -193,7 +193,7 @@ cpuid(uint32_t ax, uint32_t *p)
"=d" (p[3])
: "0" (ax)
);
-#elif (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO)) && defined(PIPE_ARCH_X86_64)
+#elif defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86_64)
__asm __volatile (
"cpuid\n\t"
: "=a" (p[0]),
@@ -219,7 +219,7 @@ cpuid(uint32_t ax, uint32_t *p)
static inline void
cpuid_count(uint32_t ax, uint32_t cx, uint32_t *p)
{
-#if (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO)) && defined(PIPE_ARCH_X86)
+#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
__asm __volatile (
"xchgl %%ebx, %1\n\t"
"cpuid\n\t"
@@ -230,7 +230,7 @@ cpuid_count(uint32_t ax, uint32_t cx, uint32_t *p)
"=d" (p[3])
: "0" (ax), "2" (cx)
);
-#elif (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO)) && defined(PIPE_ARCH_X86_64)
+#elif defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86_64)
__asm __volatile (
"cpuid\n\t"
: "=a" (p[0]),
@@ -281,7 +281,7 @@ PIPE_ALIGN_STACK static inline boolean sse2_has_daz(void)
} PIPE_ALIGN_VAR(16) fxarea;
fxarea.mxcsr_mask = 0;
-#if (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO))
+#if defined(PIPE_CC_GCC)
__asm __volatile ("fxsave %0" : "+m" (fxarea));
#elif (defined(PIPE_CC_MSVC) && _MSC_VER >= 1700) || defined(PIPE_CC_ICL)
/* 1700 = Visual Studio 2012 */
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index 702953673ba..cb162d89a58 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -153,7 +153,7 @@ debug_get_option(const char *name, const char *dfault)
const char *result;
result = os_get_option(name);
- if(!result)
+ if (!result)
result = dfault;
if (debug_get_option_should_print())
@@ -557,7 +557,7 @@ void debug_dump_surface(struct pipe_context *pipe,
surface->u.tex.first_layer,
PIPE_TRANSFER_READ,
0, 0, surface->width, surface->height, &transfer);
- if(!data)
+ if (!data)
return;
debug_dump_image(prefix,
@@ -654,7 +654,7 @@ debug_dump_transfer_bmp(struct pipe_context *pipe,
transfer->box.height *
transfer->box.depth *
4*sizeof(float));
- if(!rgba)
+ if (!rgba)
goto error1;
pipe_get_tile_rgba(transfer, ptr, 0, 0,
@@ -680,7 +680,7 @@ debug_dump_float_rgba_bmp(const char *filename,
struct bmp_info_header bmih;
unsigned x, y;
- if(!rgba)
+ if (!rgba)
goto error1;
bmfh.bfType = 0x4d42;
@@ -702,7 +702,7 @@ debug_dump_float_rgba_bmp(const char *filename,
bmih.biClrImportant = 0;
stream = fopen(filename, "wb");
- if(!stream)
+ if (!stream)
goto error1;
fwrite(&bmfh, 14, 1, stream);
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index aaf223c6f68..5307072fa3a 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -268,9 +268,11 @@ void _debug_assert_fail(const char *expr,
*/
#define pipe_debug_message(cb, type, fmt, ...) do { \
static unsigned id = 0; \
- _pipe_debug_message(cb, &id, \
- PIPE_DEBUG_TYPE_ ## type, \
- fmt, __VA_ARGS__); \
+ if ((cb) && (cb)->debug_message) { \
+ _pipe_debug_message(cb, &id, \
+ PIPE_DEBUG_TYPE_ ## type, \
+ fmt, ##__VA_ARGS__); \
+ } \
} while (0)
struct pipe_debug_callback;
diff --git a/src/gallium/auxiliary/util/u_debug_memory.c b/src/gallium/auxiliary/util/u_debug_memory.c
index 3e7ecfa79f3..f1cc8eb1b7c 100644
--- a/src/gallium/auxiliary/util/u_debug_memory.c
+++ b/src/gallium/auxiliary/util/u_debug_memory.c
@@ -128,7 +128,7 @@ debug_malloc(const char *file, unsigned line, const char *function,
struct debug_memory_footer *ftr;
hdr = os_malloc(sizeof(*hdr) + size + sizeof(*ftr));
- if(!hdr) {
+ if (!hdr) {
debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n",
file, line, function,
(long unsigned)size);
@@ -167,7 +167,7 @@ debug_free(const char *file, unsigned line, const char *function,
struct debug_memory_header *hdr;
struct debug_memory_footer *ftr;
- if(!ptr)
+ if (!ptr)
return;
hdr = header_from_data(ptr);
@@ -213,7 +213,7 @@ debug_calloc(const char *file, unsigned line, const char *function,
size_t count, size_t size )
{
void *ptr = debug_malloc( file, line, function, count * size );
- if( ptr )
+ if (ptr)
memset( ptr, 0, count * size );
return ptr;
}
@@ -226,7 +226,7 @@ debug_realloc(const char *file, unsigned line, const char *function,
struct debug_memory_footer *old_ftr, *new_ftr;
void *new_ptr;
- if(!old_ptr)
+ if (!old_ptr)
return debug_malloc( file, line, function, new_size );
if(!new_size) {
@@ -253,7 +253,7 @@ debug_realloc(const char *file, unsigned line, const char *function,
/* alloc new */
new_hdr = os_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr));
- if(!new_hdr) {
+ if (!new_hdr) {
debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n",
file, line, function,
(long unsigned)new_size);
diff --git a/src/gallium/auxiliary/util/u_debug_refcnt.c b/src/gallium/auxiliary/util/u_debug_refcnt.c
index a51b4c55f83..2c3dc986a90 100644
--- a/src/gallium/auxiliary/util/u_debug_refcnt.c
+++ b/src/gallium/auxiliary/util/u_debug_refcnt.c
@@ -79,7 +79,7 @@ static boolean debug_serial(void* p, unsigned* pserial)
#endif
pipe_mutex_lock(serials_mutex);
- if(!serials_hash)
+ if (!serials_hash)
serials_hash = util_hash_table_create(hash_ptr, compare_ptr);
serial = (unsigned)(uintptr_t)util_hash_table_get(serials_hash, p);
if(!serial)
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 03784bf2ccf..fa442aff38f 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -107,7 +107,7 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
float *v = NULL;
v = MALLOC(vertexBytes);
- if (v == NULL)
+ if (!v)
goto out;
/*
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
index 441d16236b5..a73a1de2f0b 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -320,7 +320,7 @@ util_dump_resource(FILE *stream, const struct pipe_resource *state)
void
util_dump_rasterizer_state(FILE *stream, const struct pipe_rasterizer_state *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -374,7 +374,7 @@ util_dump_rasterizer_state(FILE *stream, const struct pipe_rasterizer_state *sta
void
util_dump_poly_stipple(FILE *stream, const struct pipe_poly_stipple *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -392,7 +392,7 @@ util_dump_poly_stipple(FILE *stream, const struct pipe_poly_stipple *state)
void
util_dump_viewport_state(FILE *stream, const struct pipe_viewport_state *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -409,7 +409,7 @@ util_dump_viewport_state(FILE *stream, const struct pipe_viewport_state *state)
void
util_dump_scissor_state(FILE *stream, const struct pipe_scissor_state *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -430,7 +430,7 @@ util_dump_clip_state(FILE *stream, const struct pipe_clip_state *state)
{
unsigned i;
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -456,7 +456,7 @@ util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state)
{
unsigned i;
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -500,7 +500,7 @@ util_dump_depth_stencil_alpha_state(FILE *stream, const struct pipe_depth_stenci
{
unsigned i;
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -579,7 +579,7 @@ util_dump_blend_state(FILE *stream, const struct pipe_blend_state *state)
{
unsigned valid_entries = 1;
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -611,7 +611,7 @@ util_dump_blend_state(FILE *stream, const struct pipe_blend_state *state)
void
util_dump_blend_color(FILE *stream, const struct pipe_blend_color *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -626,7 +626,7 @@ util_dump_blend_color(FILE *stream, const struct pipe_blend_color *state)
void
util_dump_stencil_ref(FILE *stream, const struct pipe_stencil_ref *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -656,7 +656,7 @@ util_dump_framebuffer_state(FILE *stream, const struct pipe_framebuffer_state *s
void
util_dump_sampler_state(FILE *stream, const struct pipe_sampler_state *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -686,7 +686,7 @@ util_dump_sampler_state(FILE *stream, const struct pipe_sampler_state *state)
void
util_dump_surface(FILE *stream, const struct pipe_surface *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -770,7 +770,7 @@ util_dump_sampler_view(FILE *stream, const struct pipe_sampler_view *state)
void
util_dump_transfer(FILE *stream, const struct pipe_transfer *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -832,7 +832,7 @@ util_dump_index_buffer(FILE *stream, const struct pipe_index_buffer *state)
void
util_dump_vertex_buffer(FILE *stream, const struct pipe_vertex_buffer *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -851,7 +851,7 @@ util_dump_vertex_buffer(FILE *stream, const struct pipe_vertex_buffer *state)
void
util_dump_vertex_element(FILE *stream, const struct pipe_vertex_element *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -889,7 +889,7 @@ util_dump_stream_output_target(FILE *stream,
void
util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
{
- if(!state) {
+ if (!state) {
util_dump_null(stream);
return;
}
@@ -924,7 +924,7 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
void util_dump_box(FILE *stream, const struct pipe_box *box)
{
- if(!box) {
+ if (!box) {
util_dump_null(stream);
return;
}
diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c
index 42c4e44b644..c6eeeef0f3a 100644
--- a/src/gallium/auxiliary/util/u_handle_table.c
+++ b/src/gallium/auxiliary/util/u_handle_table.c
@@ -64,7 +64,7 @@ handle_table_create(void)
struct handle_table *ht;
ht = MALLOC_STRUCT(handle_table);
- if(!ht)
+ if (!ht)
return NULL;
ht->objects = (void **)CALLOC(HANDLE_TABLE_INITIAL_SIZE, sizeof(void *));
@@ -114,7 +114,7 @@ handle_table_resize(struct handle_table *ht,
new_objects = (void **)REALLOC((void *)ht->objects,
ht->size*sizeof(void *),
new_size*sizeof(void *));
- if(!new_objects)
+ if (!new_objects)
return 0;
memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
@@ -139,7 +139,7 @@ handle_table_clear(struct handle_table *ht,
*/
object = ht->objects[index];
- if(object) {
+ if (object) {
ht->objects[index] = NULL;
if(ht->destroy)
@@ -199,7 +199,7 @@ handle_table_set(struct handle_table *ht,
return 0;
assert(object);
- if(!object)
+ if (!object)
return 0;
index = handle - 1;
@@ -247,7 +247,7 @@ handle_table_remove(struct handle_table *ht,
index = handle - 1;
object = ht->objects[index];
- if(!object)
+ if (!object)
return;
handle_table_clear(ht, index);
diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c
index a505fbc4d83..9e2b6b7de8b 100644
--- a/src/gallium/auxiliary/util/u_hash_table.c
+++ b/src/gallium/auxiliary/util/u_hash_table.c
@@ -82,7 +82,7 @@ util_hash_table_create(unsigned (*hash)(void *key),
struct util_hash_table *ht;
ht = MALLOC_STRUCT(util_hash_table);
- if(!ht)
+ if (!ht)
return NULL;
ht->cso = cso_hash_create();
@@ -154,14 +154,14 @@ util_hash_table_set(struct util_hash_table *ht,
key_hash = ht->hash(key);
item = util_hash_table_find_item(ht, key, key_hash);
- if(item) {
+ if (item) {
/* TODO: key/value destruction? */
item->value = value;
return PIPE_OK;
}
item = MALLOC_STRUCT(util_hash_table_item);
- if(!item)
+ if (!item)
return PIPE_ERROR_OUT_OF_MEMORY;
item->key = key;
@@ -191,7 +191,7 @@ util_hash_table_get(struct util_hash_table *ht,
key_hash = ht->hash(key);
item = util_hash_table_find_item(ht, key, key_hash);
- if(!item)
+ if (!item)
return NULL;
return item->value;
diff --git a/src/gallium/auxiliary/util/u_helpers.c b/src/gallium/auxiliary/util/u_helpers.c
index 09619c1c9e9..09020b061a3 100644
--- a/src/gallium/auxiliary/util/u_helpers.c
+++ b/src/gallium/auxiliary/util/u_helpers.c
@@ -81,7 +81,13 @@ void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst,
const struct pipe_vertex_buffer *src,
unsigned start_slot, unsigned count)
{
- uint32_t enabled_buffers = (1ull << *dst_count) - 1;
+ unsigned i;
+ uint32_t enabled_buffers = 0;
+
+ for (i = 0; i < *dst_count; i++) {
+ if (dst[i].buffer || dst[i].user_buffer)
+ enabled_buffers |= (1ull << i);
+ }
util_set_vertex_buffers_mask(dst, &enabled_buffers, src, start_slot,
count);
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 384e267b593..57a3b0b6082 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -289,7 +289,7 @@ pipe_buffer_map_range(struct pipe_context *pipe,
u_box_1d(offset, length, &box);
map = pipe->transfer_map(pipe, buffer, 0, access, &box, transfer);
- if (map == NULL) {
+ if (!map) {
return NULL;
}
diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c
index 2069b56f464..bd4c4e1b106 100644
--- a/src/gallium/auxiliary/util/u_mm.c
+++ b/src/gallium/auxiliary/util/u_mm.c
@@ -34,7 +34,7 @@ void
u_mmDumpMemInfo(const struct mem_block *heap)
{
debug_printf("Memory heap %p:\n", (void *) heap);
- if (heap == 0) {
+ if (heap == NULL) {
debug_printf(" heap == 0\n");
}
else {
diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h
index 366801545ed..a09c315cc0a 100644
--- a/src/gallium/auxiliary/util/u_prim.h
+++ b/src/gallium/auxiliary/util/u_prim.h
@@ -145,6 +145,9 @@ u_prims_for_vertices(unsigned prim, unsigned num)
{
const struct u_prim_vertex_count *info = u_prim_vertex_count(prim);
+ assert(info);
+ assert(info->incr != 0);
+
if (num < info->min)
return 0;
diff --git a/src/gallium/auxiliary/util/u_ringbuffer.c b/src/gallium/auxiliary/util/u_ringbuffer.c
index 5816b781660..19830a904e6 100644
--- a/src/gallium/auxiliary/util/u_ringbuffer.c
+++ b/src/gallium/auxiliary/util/u_ringbuffer.c
@@ -24,7 +24,7 @@ struct util_ringbuffer
struct util_ringbuffer *util_ringbuffer_create( unsigned dwords )
{
struct util_ringbuffer *ring = CALLOC_STRUCT(util_ringbuffer);
- if (ring == NULL)
+ if (!ring)
return NULL;
assert(util_is_power_of_two(dwords));
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index 6eed33769dd..7ffb2712472 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -80,7 +80,7 @@ util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe,
uint i;
ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
- if (ureg == NULL)
+ if (!ureg)
return NULL;
if (window_space)
@@ -228,7 +228,7 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
interp_mode == TGSI_INTERPOLATE_PERSPECTIVE);
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
+ if (!ureg)
return NULL;
sampler = ureg_DECL_sampler( ureg, 0 );
@@ -298,7 +298,7 @@ util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
struct ureg_src imm;
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
+ if (!ureg)
return NULL;
sampler = ureg_DECL_sampler( ureg, 0 );
@@ -350,7 +350,7 @@ util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe,
struct ureg_src imm;
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
+ if (!ureg)
return NULL;
depth_sampler = ureg_DECL_sampler( ureg, 0 );
@@ -414,7 +414,7 @@ util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe,
struct ureg_src imm;
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
+ if (!ureg)
return NULL;
stencil_sampler = ureg_DECL_sampler( ureg, 0 );
@@ -494,7 +494,7 @@ void *
util_make_empty_fragment_shader(struct pipe_context *pipe)
{
struct ureg_program *ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
- if (ureg == NULL)
+ if (!ureg)
return NULL;
ureg_END(ureg);
@@ -518,7 +518,7 @@ util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
+ if (!ureg)
return NULL;
src = ureg_DECL_fs_input( ureg, input_semantic, 0,
@@ -848,7 +848,7 @@ util_make_geometry_passthrough_shader(struct pipe_context *pipe,
unsigned i;
ureg = ureg_create(TGSI_PROCESSOR_GEOMETRY);
- if (ureg == NULL)
+ if (!ureg)
return NULL;
ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, PIPE_PRIM_POINTS);
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index 70ed911b7f1..6aa44f9602a 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -397,7 +397,7 @@ util_clear_render_target(struct pipe_context *pipe,
}
}
else {
- util_pack_color(color->f, dst->format, &uc);
+ util_pack_color(color->f, format, &uc);
}
util_fill_box(dst_map, dst->format,
diff --git a/src/gallium/auxiliary/util/u_surfaces.c b/src/gallium/auxiliary/util/u_surfaces.c
index c2f2b74c939..78b2506e47b 100644
--- a/src/gallium/auxiliary/util/u_surfaces.c
+++ b/src/gallium/auxiliary/util/u_surfaces.c
@@ -59,7 +59,7 @@ util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size,
}
ps = (struct pipe_surface *)CALLOC(1, surface_struct_size);
- if(!ps)
+ if (!ps)
{
*res = NULL;
return FALSE;
@@ -114,7 +114,7 @@ util_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (
for(i = 0; i <= pt->last_level; ++i)
{
struct pipe_surface *ps = us->u.array[i];
- if(ps)
+ if (ps)
destroy_surface(ps);
}
FREE(us->u.array);
diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
index 4cb524d5cb1..adae84bbfab 100644
--- a/src/gallium/auxiliary/util/u_transfer.c
+++ b/src/gallium/auxiliary/util/u_transfer.c
@@ -37,7 +37,7 @@ void u_default_transfer_inline_write( struct pipe_context *pipe,
level,
usage,
box, &transfer);
- if (map == NULL)
+ if (!map)
return;
if (resource->target == PIPE_BUFFER) {
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index 59207a1969b..b672fad6bf0 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -270,7 +270,7 @@ void u_upload_buffer(struct u_upload_mgr *upload,
PIPE_TRANSFER_READ,
&transfer);
- if (map == NULL) {
+ if (!map) {
pipe_resource_reference(outbuf, NULL);
return;
}
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
index 9d0e4a1eae0..f5bb3a0106f 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
@@ -542,7 +542,7 @@ vl_mpeg12_get_decode_buffer(struct vl_mpeg12_decoder *dec, struct pipe_video_buf
return buffer;
buffer = CALLOC_STRUCT(vl_mpeg12_buffer);
- if (buffer == NULL)
+ if (!buffer)
return NULL;
if (!vl_vb_init(&buffer->vertex_stream, dec->context,
diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c
index 6cd2557a892..e8cd24dec81 100644
--- a/src/gallium/auxiliary/vl/vl_video_buffer.c
+++ b/src/gallium/auxiliary/vl/vl_video_buffer.c
@@ -115,7 +115,7 @@ vl_video_buffer_formats(struct pipe_screen *screen, enum pipe_format format)
return const_resource_formats_VUYA;
case PIPE_FORMAT_R8G8B8X8_UNORM:
- return const_resource_formats_VUYX;
+ return const_resource_formats_YUVX;
case PIPE_FORMAT_B8G8R8X8_UNORM:
return const_resource_formats_VUYX;
diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri.c b/src/gallium/auxiliary/vl/vl_winsys_dri.c
index ae0d4cdee1b..758f50d7c23 100644
--- a/src/gallium/auxiliary/vl/vl_winsys_dri.c
+++ b/src/gallium/auxiliary/vl/vl_winsys_dri.c
@@ -392,7 +392,7 @@ vl_dri2_screen_create(Display *display, int screen)
goto free_connect;
if (drmGetMagic(fd, &magic))
- goto free_connect;
+ goto close_fd;
authenticate_cookie = xcb_dri2_authenticate_unchecked(scrn->conn,
get_xcb_screen(s, screen)->root,
@@ -402,7 +402,7 @@ vl_dri2_screen_create(Display *display, int screen)
if (authenticate == NULL || !authenticate->authenticated)
goto free_authenticate;
- if (pipe_loader_drm_probe_fd(&scrn->base.dev, dup(fd)))
+ if (pipe_loader_drm_probe_fd(&scrn->base.dev, fd))
scrn->base.pscreen = pipe_loader_create_screen(scrn->base.dev);
if (!scrn->base.pscreen)
@@ -428,8 +428,11 @@ vl_dri2_screen_create(Display *display, int screen)
release_pipe:
if (scrn->base.dev)
pipe_loader_release(&scrn->base.dev, 1);
+ fd = -1;
free_authenticate:
free(authenticate);
+close_fd:
+ close(fd);
free_connect:
free(connect);
free_query:
diff --git a/src/gallium/auxiliary/vl/vl_winsys_drm.c b/src/gallium/auxiliary/vl/vl_winsys_drm.c
index f993e2c7727..6d9d947588c 100644
--- a/src/gallium/auxiliary/vl/vl_winsys_drm.c
+++ b/src/gallium/auxiliary/vl/vl_winsys_drm.c
@@ -41,12 +41,16 @@ struct vl_screen *
vl_drm_screen_create(int fd)
{
struct vl_screen *vscreen;
+ int new_fd = -1;
vscreen = CALLOC_STRUCT(vl_screen);
if (!vscreen)
return NULL;
- if (pipe_loader_drm_probe_fd(&vscreen->dev, dup(fd)))
+ if (fd < 0 || (new_fd = dup(fd)) < 0)
+ goto error;
+
+ if (pipe_loader_drm_probe_fd(&vscreen->dev, new_fd))
vscreen->pscreen = pipe_loader_create_screen(vscreen->dev);
if (!vscreen->pscreen)
@@ -63,6 +67,8 @@ vl_drm_screen_create(int fd)
error:
if (vscreen->dev)
pipe_loader_release(&vscreen->dev, 1);
+ else
+ close(new_fd);
FREE(vscreen);
return NULL;
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_texture.c b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c
index 90013e260ce..6e4b5a5e72c 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_texture.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c
@@ -106,6 +106,9 @@ fd2_sampler_states_bind(struct pipe_context *pctx,
unsigned shader, unsigned start,
unsigned nr, void **hwcso)
{
+ if (!hwcso)
+ nr = 0;
+
if (shader == PIPE_SHADER_FRAGMENT) {
struct fd_context *ctx = fd_context(pctx);
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
index 4ed04b38dea..736151651b2 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
@@ -264,7 +264,7 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit,
A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT(MAX2(vp->constlen + 1, 0)));
OUT_RING(ring, A3XX_SP_VS_PARAM_REG_POSREGID(pos_regid) |
A3XX_SP_VS_PARAM_REG_PSIZEREGID(psize_regid) |
- A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(align(fp->total_in, 4) / 4));
+ A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(fp->varying_in));
for (i = 0, j = -1; (i < 8) && (j < (int)fp->inputs_count); i++) {
uint32_t reg = 0;
@@ -387,23 +387,27 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit,
/* figure out VARYING_INTERP / FLAT_SHAD register values: */
for (j = -1; (j = ir3_next_varying(fp, j)) < (int)fp->inputs_count; ) {
+ /* NOTE: varyings are packed, so if compmask is 0xb
+ * then first, third, and fourth component occupy
+ * three consecutive varying slots:
+ */
+ unsigned compmask = fp->inputs[j].compmask;
/* TODO might be cleaner to just +8 in SP_VS_VPC_DST_REG
* instead.. rather than -8 everywhere else..
*/
uint32_t inloc = fp->inputs[j].inloc - 8;
- /* currently assuming varyings aligned to 4 (not
- * packed):
- */
- debug_assert((inloc % 4) == 0);
-
if ((fp->inputs[j].interpolate == INTERP_QUALIFIER_FLAT) ||
(fp->inputs[j].rasterflat && emit->rasterflat)) {
uint32_t loc = inloc;
- for (i = 0; i < 4; i++, loc++) {
- vinterp[loc / 16] |= FLAT << ((loc % 16) * 2);
- flatshade[loc / 32] |= 1 << (loc % 32);
+
+ for (i = 0; i < 4; i++) {
+ if (compmask & (1 << i)) {
+ vinterp[loc / 16] |= FLAT << ((loc % 16) * 2);
+ flatshade[loc / 32] |= 1 << (loc % 32);
+ loc++;
+ }
}
}
@@ -416,10 +420,31 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit,
* interpolation bits for .zw such that they become .01
*/
if (emit->sprite_coord_enable & texmask) {
- vpsrepl[inloc / 16] |= (emit->sprite_coord_mode ? 0x0d : 0x09)
- << ((inloc % 16) * 2);
- vinterp[(inloc + 2) / 16] |= 2 << (((inloc + 2) % 16) * 2);
- vinterp[(inloc + 3) / 16] |= 3 << (((inloc + 3) % 16) * 2);
+ /* mask is two 2-bit fields, where:
+ * '01' -> S
+ * '10' -> T
+ * '11' -> 1 - T (flip mode)
+ */
+ unsigned mask = emit->sprite_coord_mode ? 0b1101 : 0b1001;
+ uint32_t loc = inloc;
+ if (compmask & 0x1) {
+ vpsrepl[loc / 16] |= ((mask >> 0) & 0x3) << ((loc % 16) * 2);
+ loc++;
+ }
+ if (compmask & 0x2) {
+ vpsrepl[loc / 16] |= ((mask >> 2) & 0x3) << ((loc % 16) * 2);
+ loc++;
+ }
+ if (compmask & 0x4) {
+ /* .z <- 0.0f */
+ vinterp[loc / 16] |= 0b10 << ((loc % 16) * 2);
+ loc++;
+ }
+ if (compmask & 0x8) {
+ /* .w <- 1.0f */
+ vinterp[loc / 16] |= 0b11 << ((loc % 16) * 2);
+ loc++;
+ }
}
}
}
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
index 99ae99ea0c1..9d54d41e1ad 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
@@ -149,6 +149,9 @@ fd3_sampler_states_bind(struct pipe_context *pctx,
uint16_t saturate_s = 0, saturate_t = 0, saturate_r = 0;
unsigned i;
+ if (!hwcso)
+ nr = 0;
+
for (i = 0; i < nr; i++) {
if (hwcso[i]) {
struct fd3_sampler_stateobj *sampler =
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_program.c b/src/gallium/drivers/freedreno/a4xx/fd4_program.c
index 3df13543148..0e861b90b12 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_program.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_program.c
@@ -326,7 +326,7 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
A4XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING(s[VS].v->total_in));
OUT_RING(ring, A4XX_SP_VS_PARAM_REG_POSREGID(pos_regid) |
A4XX_SP_VS_PARAM_REG_PSIZEREGID(psize_regid) |
- A4XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(align(s[FS].v->total_in, 4) / 4));
+ A4XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(s[FS].v->varying_in));
for (i = 0, j = -1; (i < 16) && (j < (int)s[FS].v->inputs_count); i++) {
uint32_t reg = 0;
@@ -479,24 +479,27 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
*/
/* figure out VARYING_INTERP / VARYING_PS_REPL register values: */
for (j = -1; (j = ir3_next_varying(s[FS].v, j)) < (int)s[FS].v->inputs_count; ) {
+ /* NOTE: varyings are packed, so if compmask is 0xb
+ * then first, third, and fourth component occupy
+ * three consecutive varying slots:
+ */
+ unsigned compmask = s[FS].v->inputs[j].compmask;
/* TODO might be cleaner to just +8 in SP_VS_VPC_DST_REG
* instead.. rather than -8 everywhere else..
*/
uint32_t inloc = s[FS].v->inputs[j].inloc - 8;
- /* currently assuming varyings aligned to 4 (not
- * packed):
- */
- debug_assert((inloc % 4) == 0);
-
if ((s[FS].v->inputs[j].interpolate == INTERP_QUALIFIER_FLAT) ||
(s[FS].v->inputs[j].rasterflat && emit->rasterflat)) {
uint32_t loc = inloc;
- for (i = 0; i < 4; i++, loc++) {
- vinterp[loc / 16] |= 1 << ((loc % 16) * 2);
- //flatshade[loc / 32] |= 1 << (loc % 32);
+ for (i = 0; i < 4; i++) {
+ if (compmask & (1 << i)) {
+ vinterp[loc / 16] |= 1 << ((loc % 16) * 2);
+ //flatshade[loc / 32] |= 1 << (loc % 32);
+ loc++;
+ }
}
}
@@ -509,10 +512,31 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
* interpolation bits for .zw such that they become .01
*/
if (emit->sprite_coord_enable & texmask) {
- vpsrepl[inloc / 16] |= (emit->sprite_coord_mode ? 0x0d : 0x09)
- << ((inloc % 16) * 2);
- vinterp[(inloc + 2) / 16] |= 2 << (((inloc + 2) % 16) * 2);
- vinterp[(inloc + 3) / 16] |= 3 << (((inloc + 3) % 16) * 2);
+ /* mask is two 2-bit fields, where:
+ * '01' -> S
+ * '10' -> T
+ * '11' -> 1 - T (flip mode)
+ */
+ unsigned mask = emit->sprite_coord_mode ? 0b1101 : 0b1001;
+ uint32_t loc = inloc;
+ if (compmask & 0x1) {
+ vpsrepl[loc / 16] |= ((mask >> 0) & 0x3) << ((loc % 16) * 2);
+ loc++;
+ }
+ if (compmask & 0x2) {
+ vpsrepl[loc / 16] |= ((mask >> 2) & 0x3) << ((loc % 16) * 2);
+ loc++;
+ }
+ if (compmask & 0x4) {
+ /* .z <- 0.0f */
+ vinterp[loc / 16] |= 0b10 << ((loc % 16) * 2);
+ loc++;
+ }
+ if (compmask & 0x8) {
+ /* .w <- 1.0f */
+ vinterp[loc / 16] |= 0b11 << ((loc % 16) * 2);
+ loc++;
+ }
}
}
}
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
index 0eba75577b0..38348580e21 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
@@ -150,6 +150,9 @@ fd4_sampler_states_bind(struct pipe_context *pctx,
uint16_t saturate_s = 0, saturate_t = 0, saturate_r = 0;
unsigned i;
+ if (!hwcso)
+ nr = 0;
+
for (i = 0; i < nr; i++) {
if (hwcso[i]) {
struct fd4_sampler_stateobj *sampler =
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 63ca9e30620..bcdd518c8bf 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -337,10 +337,8 @@ fd_resource_transfer_map(struct pipe_context *pctx,
}
buf = fd_bo_map(rsc->bo);
- if (!buf) {
- fd_resource_transfer_unmap(pctx, ptrans);
- return NULL;
- }
+ if (!buf)
+ goto fail;
offset = slice->offset +
box->y / util_format_get_blockheight(format) * ptrans->stride +
diff --git a/src/gallium/drivers/freedreno/freedreno_surface.c b/src/gallium/drivers/freedreno/freedreno_surface.c
index 70c44eb79c3..90433934345 100644
--- a/src/gallium/drivers/freedreno/freedreno_surface.c
+++ b/src/gallium/drivers/freedreno/freedreno_surface.c
@@ -41,27 +41,28 @@ fd_create_surface(struct pipe_context *pctx,
// struct fd_resource* tex = fd_resource(ptex);
struct fd_surface* surface = CALLOC_STRUCT(fd_surface);
+ if (!surface)
+ return NULL;
+
debug_assert(ptex->target != PIPE_BUFFER);
debug_assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
- if (surface) {
- struct pipe_surface *psurf = &surface->base;
- unsigned level = surf_tmpl->u.tex.level;
+ struct pipe_surface *psurf = &surface->base;
+ unsigned level = surf_tmpl->u.tex.level;
- pipe_reference_init(&psurf->reference, 1);
- pipe_resource_reference(&psurf->texture, ptex);
+ pipe_reference_init(&psurf->reference, 1);
+ pipe_resource_reference(&psurf->texture, ptex);
- psurf->context = pctx;
- psurf->format = surf_tmpl->format;
- psurf->width = u_minify(ptex->width0, level);
- psurf->height = u_minify(ptex->height0, level);
- psurf->u.tex.level = level;
- psurf->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
- psurf->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
+ psurf->context = pctx;
+ psurf->format = surf_tmpl->format;
+ psurf->width = u_minify(ptex->width0, level);
+ psurf->height = u_minify(ptex->height0, level);
+ psurf->u.tex.level = level;
+ psurf->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+ psurf->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
- // TODO
- DBG("TODO: %ux%u", psurf->width, psurf->height);
- }
+ // TODO
+ DBG("TODO: %ux%u", psurf->width, psurf->height);
return &surface->base;
}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h
index 12f2ebe18db..62d14a0ae37 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3.h
@@ -177,6 +177,7 @@ struct ir3_instruction {
* before register assignment is done:
*/
IR3_INSTR_MARK = 0x1000,
+ IR3_INSTR_UNUSED= 0x2000,
} flags;
int repeat;
#ifdef DEBUG
@@ -243,11 +244,7 @@ struct ir3_instruction {
* result of moving a const to a reg would have a low cost, so to
* it could make sense to duplicate the instruction at various
* points where the result is needed to reduce register footprint.
- *
- * DEPTH_UNUSED used to mark unused instructions after depth
- * calculation pass.
*/
-#define DEPTH_UNUSED ~0
unsigned depth;
/* When we get to the RA stage, we no longer need depth, but
* we do need instruction's position/name:
@@ -258,6 +255,10 @@ struct ir3_instruction {
};
};
+ /* used for per-pass extra instruction data.
+ */
+ void *data;
+
/* Used during CP and RA stages. For fanin and shader inputs/
* outputs where we need a sequence of consecutive registers,
* keep track of each src instructions left (ie 'n-1') and right
@@ -404,7 +405,7 @@ struct ir3_block {
/* used for per-pass extra block data. Mainly used right
* now in RA step to track livein/liveout.
*/
- void *bd;
+ void *data;
#ifdef DEBUG
uint32_t serialno;
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
index 156bb0be247..eea5c5e28db 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
@@ -96,9 +96,6 @@ struct ir3_compile {
*/
struct hash_table *block_ht;
- /* for calculating input/output positions/linkages: */
- unsigned next_inloc;
-
/* a4xx (at least patchlevel 0) cannot seem to flat-interpolate
* so we need to use ldlv.u32 to load the varying directly:
*/
@@ -166,7 +163,7 @@ static struct nir_shader *to_nir(struct ir3_compile *ctx,
struct nir_shader *s = tgsi_to_nir(tokens, &options);
- if (fd_mesa_debug & FD_DBG_OPTMSGS) {
+ if (fd_mesa_debug & FD_DBG_DISASM) {
debug_printf("----------------------\n");
nir_print_shader(s, stdout);
debug_printf("----------------------\n");
@@ -204,7 +201,7 @@ static struct nir_shader *to_nir(struct ir3_compile *ctx,
nir_remove_dead_variables(s);
nir_validate_shader(s);
- if (fd_mesa_debug & FD_DBG_OPTMSGS) {
+ if (fd_mesa_debug & FD_DBG_DISASM) {
debug_printf("----------------------\n");
nir_print_shader(s, stdout);
debug_printf("----------------------\n");
@@ -235,13 +232,10 @@ compile_init(struct ir3_compiler *compiler,
ctx->compiler = compiler;
ctx->ir = so->ir;
ctx->so = so;
- ctx->next_inloc = 8;
ctx->def_ht = _mesa_hash_table_create(ctx,
_mesa_hash_pointer, _mesa_key_pointer_equal);
ctx->var_ht = _mesa_hash_table_create(ctx,
_mesa_hash_pointer, _mesa_key_pointer_equal);
- ctx->addr_ht = _mesa_hash_table_create(ctx,
- _mesa_hash_pointer, _mesa_key_pointer_equal);
ctx->block_ht = _mesa_hash_table_create(ctx,
_mesa_hash_pointer, _mesa_key_pointer_equal);
@@ -333,12 +327,12 @@ struct ir3_nir_block_data {
static struct ir3_nir_block_data *
get_block_data(struct ir3_compile *ctx, struct ir3_block *block)
{
- if (!block->bd) {
+ if (!block->data) {
struct ir3_nir_block_data *bd = ralloc_size(ctx, sizeof(*bd) +
((ctx->num_arrays + 1) * sizeof(bd->arrs[0])));
- block->bd = bd;
+ block->data = bd;
}
- return block->bd;
+ return block->data;
}
static void
@@ -401,7 +395,7 @@ get_var(struct ir3_compile *ctx, nir_variable *var)
pred_block && (pred_block->predecessors->entries < 2) && !defn;
pred_block = nir_block_pred(pred_block)) {
struct ir3_block *pblock = get_block(ctx, pred_block);
- struct ir3_nir_block_data *pbd = pblock->bd;
+ struct ir3_nir_block_data *pbd = pblock->data;
if (!pbd)
continue;
defn = pbd->arrs[arr->aid];
@@ -456,7 +450,7 @@ add_array_phi_srcs(struct ir3_compile *ctx, nir_block *nblock,
BITSET_SET(visited, nblock->index);
block = get_block(ctx, nblock);
- bd = block->bd;
+ bd = block->data;
if (bd && bd->arrs[av->aid]) {
struct ir3_array_value *dav = bd->arrs[av->aid];
@@ -476,7 +470,7 @@ add_array_phi_srcs(struct ir3_compile *ctx, nir_block *nblock,
static void
resolve_array_phis(struct ir3_compile *ctx, struct ir3_block *block)
{
- struct ir3_nir_block_data *bd = block->bd;
+ struct ir3_nir_block_data *bd = block->data;
unsigned bitset_words = BITSET_WORDS(ctx->impl->num_blocks);
if (!bd)
@@ -587,12 +581,17 @@ static struct ir3_instruction *
get_addr(struct ir3_compile *ctx, struct ir3_instruction *src)
{
struct ir3_instruction *addr;
- struct hash_entry *entry;
- entry = _mesa_hash_table_search(ctx->addr_ht, src);
- if (entry)
- return entry->data;
- /* TODO do we need to cache per block? */
+ if (!ctx->addr_ht) {
+ ctx->addr_ht = _mesa_hash_table_create(ctx,
+ _mesa_hash_pointer, _mesa_key_pointer_equal);
+ } else {
+ struct hash_entry *entry;
+ entry = _mesa_hash_table_search(ctx->addr_ht, src);
+ if (entry)
+ return entry->data;
+ }
+
addr = create_addr(ctx->block, src);
_mesa_hash_table_insert(ctx->addr_ht, src, addr);
@@ -722,11 +721,12 @@ create_input(struct ir3_block *block, unsigned n)
}
static struct ir3_instruction *
-create_frag_input(struct ir3_compile *ctx, unsigned n, bool use_ldlv)
+create_frag_input(struct ir3_compile *ctx, bool use_ldlv)
{
struct ir3_block *block = ctx->block;
struct ir3_instruction *instr;
- struct ir3_instruction *inloc = create_immed(block, n);
+ /* actual inloc is assigned and fixed up later: */
+ struct ir3_instruction *inloc = create_immed(block, 0);
if (use_ldlv) {
instr = ir3_LDLV(block, inloc, 0, create_immed(block, 1), 0);
@@ -1218,6 +1218,7 @@ emit_intrinsic_load_ubo(struct ir3_compile *ctx, nir_intrinsic_instr *intr,
{
struct ir3_block *b = ctx->block;
struct ir3_instruction *addr, *src0, *src1;
+ nir_const_value *const_offset;
/* UBO addresses are the first driver params: */
unsigned ubo = regid(ctx->so->first_driver_param + IR3_UBOS_OFF, 0);
unsigned off = intr->const_index[0];
@@ -1231,7 +1232,10 @@ emit_intrinsic_load_ubo(struct ir3_compile *ctx, nir_intrinsic_instr *intr,
addr = create_uniform_indirect(ctx, ubo, get_addr(ctx, src0));
}
- if (intr->intrinsic == nir_intrinsic_load_ubo_indirect) {
+ const_offset = nir_src_as_const_value(intr->src[1]);
+ if (const_offset) {
+ off += const_offset->u[0];
+ } else {
/* For load_ubo_indirect, second src is indirect offset: */
src1 = get_src(ctx, &intr->src[1])[0];
@@ -1394,6 +1398,7 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
struct ir3_instruction **dst, **src;
struct ir3_block *b = ctx->block;
unsigned idx = intr->const_index[0];
+ nir_const_value *const_offset;
if (info->has_dest) {
dst = get_dst(ctx, &intr->dest, intr->num_components);
@@ -1403,43 +1408,49 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
switch (intr->intrinsic) {
case nir_intrinsic_load_uniform:
- for (int i = 0; i < intr->num_components; i++) {
- unsigned n = idx * 4 + i;
- dst[i] = create_uniform(ctx, n);
+ const_offset = nir_src_as_const_value(intr->src[0]);
+ if (const_offset) {
+ idx += const_offset->u[0];
+ for (int i = 0; i < intr->num_components; i++) {
+ unsigned n = idx * 4 + i;
+ dst[i] = create_uniform(ctx, n);
+ }
+ } else {
+ src = get_src(ctx, &intr->src[0]);
+ for (int i = 0; i < intr->num_components; i++) {
+ unsigned n = idx * 4 + i;
+ dst[i] = create_uniform_indirect(ctx, n,
+ get_addr(ctx, src[0]));
+ }
+ /* NOTE: if relative addressing is used, we set
+ * constlen in the compiler (to worst-case value)
+ * since we don't know in the assembler what the max
+ * addr reg value can be:
+ */
+ ctx->so->constlen = ctx->s->num_uniforms;
}
break;
- case nir_intrinsic_load_uniform_indirect:
- src = get_src(ctx, &intr->src[0]);
- for (int i = 0; i < intr->num_components; i++) {
- unsigned n = idx * 4 + i;
- dst[i] = create_uniform_indirect(ctx, n,
- get_addr(ctx, src[0]));
- }
- /* NOTE: if relative addressing is used, we set constlen in
- * the compiler (to worst-case value) since we don't know in
- * the assembler what the max addr reg value can be:
- */
- ctx->so->constlen = ctx->s->num_uniforms;
- break;
case nir_intrinsic_load_ubo:
- case nir_intrinsic_load_ubo_indirect:
emit_intrinsic_load_ubo(ctx, intr, dst);
break;
case nir_intrinsic_load_input:
- for (int i = 0; i < intr->num_components; i++) {
- unsigned n = idx * 4 + i;
- dst[i] = ctx->ir->inputs[n];
- }
- break;
- case nir_intrinsic_load_input_indirect:
- src = get_src(ctx, &intr->src[0]);
- struct ir3_instruction *collect =
- create_collect(b, ctx->ir->inputs, ctx->ir->ninputs);
- struct ir3_instruction *addr = get_addr(ctx, src[0]);
- for (int i = 0; i < intr->num_components; i++) {
- unsigned n = idx * 4 + i;
- dst[i] = create_indirect_load(ctx, ctx->ir->ninputs,
- n, addr, collect);
+ const_offset = nir_src_as_const_value(intr->src[0]);
+ if (const_offset) {
+ idx += const_offset->u[0];
+ for (int i = 0; i < intr->num_components; i++) {
+ unsigned n = idx * 4 + i;
+ dst[i] = ctx->ir->inputs[n];
+ }
+ } else {
+ src = get_src(ctx, &intr->src[0]);
+ struct ir3_instruction *collect =
+ create_collect(b, ctx->ir->inputs, ctx->ir->ninputs);
+ struct ir3_instruction *addr = get_addr(ctx, src[0]);
+ for (int i = 0; i < intr->num_components; i++) {
+ unsigned n = idx * 4 + i;
+ dst[i] = create_indirect_load(ctx, ctx->ir->ninputs,
+ n, addr, collect);
+ }
}
break;
case nir_intrinsic_load_var:
@@ -1449,6 +1460,10 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
emit_intrinisic_store_var(ctx, intr);
break;
case nir_intrinsic_store_output:
+ const_offset = nir_src_as_const_value(intr->src[1]);
+ compile_assert(ctx, const_offset != NULL);
+ idx += const_offset->u[0];
+
src = get_src(ctx, &intr->src[0]);
for (int i = 0; i < intr->num_components; i++) {
unsigned n = idx * 4 + i;
@@ -1983,6 +1998,10 @@ emit_block(struct ir3_compile *ctx, nir_block *nblock)
ctx->block = block;
list_addtail(&block->node, &ctx->ir->block_list);
+ /* re-emit addr register in each block if needed: */
+ _mesa_hash_table_destroy(ctx->addr_ht, NULL);
+ ctx->addr_ht = NULL;
+
nir_foreach_instr(nblock, instr) {
emit_instr(ctx, instr);
if (ctx->error)
@@ -2185,8 +2204,6 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
so->inputs[n].slot = slot;
so->inputs[n].compmask = (1 << ncomp) - 1;
- so->inputs[n].inloc = ctx->next_inloc;
- so->inputs[n].interpolate = INTERP_QUALIFIER_NONE;
so->inputs_count = MAX2(so->inputs_count, n + 1);
so->inputs[n].interpolate = in->data.interpolation;
@@ -2231,8 +2248,7 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
so->inputs[n].bary = true;
- instr = create_frag_input(ctx,
- so->inputs[n].inloc + i - 8, use_ldlv);
+ instr = create_frag_input(ctx, use_ldlv);
}
ctx->ir->inputs[idx] = instr;
@@ -2247,7 +2263,6 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
}
if (so->inputs[n].bary || (ctx->so->type == SHADER_VERTEX)) {
- ctx->next_inloc += ncomp;
so->total_in += ncomp;
}
}
@@ -2471,7 +2486,7 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
struct ir3_compile *ctx;
struct ir3 *ir;
struct ir3_instruction **inputs;
- unsigned i, j, actual_in;
+ unsigned i, j, actual_in, inloc;
int ret = 0, max_bary;
assert(!so->ir);
@@ -2591,13 +2606,6 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
ir3_print(ir);
}
- ir3_legalize(ir, &so->has_samp, &max_bary);
-
- if (fd_mesa_debug & FD_DBG_OPTMSGS) {
- printf("AFTER LEGALIZE:\n");
- ir3_print(ir);
- }
-
/* fixup input/outputs: */
for (i = 0; i < so->outputs_count; i++) {
so->outputs[i].regid = ir->outputs[i*4]->regs[0]->num;
@@ -2611,32 +2619,46 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
/* Note that some or all channels of an input may be unused: */
actual_in = 0;
+ inloc = 0;
for (i = 0; i < so->inputs_count; i++) {
unsigned j, regid = ~0, compmask = 0;
so->inputs[i].ncomp = 0;
+ so->inputs[i].inloc = inloc + 8;
for (j = 0; j < 4; j++) {
struct ir3_instruction *in = inputs[(i*4) + j];
- if (in) {
+ if (in && !(in->flags & IR3_INSTR_UNUSED)) {
compmask |= (1 << j);
regid = in->regs[0]->num - j;
actual_in++;
so->inputs[i].ncomp++;
+ if ((so->type == SHADER_FRAGMENT) && so->inputs[i].bary) {
+ /* assign inloc: */
+ assert(in->regs[1]->flags & IR3_REG_IMMED);
+ in->regs[1]->iim_val = inloc++;
+ }
}
}
+ if ((so->type == SHADER_FRAGMENT) && compmask && so->inputs[i].bary)
+ so->varying_in++;
so->inputs[i].regid = regid;
so->inputs[i].compmask = compmask;
}
- /* fragment shader always gets full vec4's even if it doesn't
- * fetch all components, but vertex shader we need to update
- * with the actual number of components fetch, otherwise thing
- * will hang due to mismaptch between VFD_DECODE's and
- * TOTALATTRTOVS
+ /* We need to do legalize after (for frag shader's) the "bary.f"
+ * offsets (inloc) have been assigned.
*/
+ ir3_legalize(ir, &so->has_samp, &max_bary);
+
+ if (fd_mesa_debug & FD_DBG_OPTMSGS) {
+ printf("AFTER LEGALIZE:\n");
+ ir3_print(ir);
+ }
+
+ /* Note that actual_in counts inputs that are not bary.f'd for FS: */
if (so->type == SHADER_VERTEX)
so->total_in = actual_in;
else
- so->total_in = align(max_bary + 1, 4);
+ so->total_in = max_bary + 1;
out:
if (ret) {
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_depth.c b/src/gallium/drivers/freedreno/ir3/ir3_depth.c
index 97df0c2ac99..4bbc0458790 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_depth.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_depth.c
@@ -139,7 +139,7 @@ remove_unused_by_block(struct ir3_block *block)
/* mark it, in case it is input, so we can
* remove unused inputs:
*/
- instr->depth = DEPTH_UNUSED;
+ instr->flags |= IR3_INSTR_UNUSED;
/* and remove from instruction list: */
list_delinit(&instr->node);
}
@@ -175,14 +175,14 @@ ir3_depth(struct ir3 *ir)
*/
for (i = 0; i < ir->indirects_count; i++) {
struct ir3_instruction *instr = ir->indirects[i];
- if (instr->depth == DEPTH_UNUSED)
+ if (instr->flags & IR3_INSTR_UNUSED)
ir->indirects[i] = NULL;
}
/* cleanup unused inputs: */
for (i = 0; i < ir->ninputs; i++) {
struct ir3_instruction *in = ir->inputs[i];
- if (in && (in->depth == DEPTH_UNUSED))
+ if (in && (in->flags & IR3_INSTR_UNUSED))
ir->inputs[i] = NULL;
}
}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_ra.c b/src/gallium/drivers/freedreno/ir3/ir3_ra.c
index 88018398e96..74755eb3bc0 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_ra.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_ra.c
@@ -314,6 +314,14 @@ writes_gpr(struct ir3_instruction *instr)
return is_temp(instr->regs[0]);
}
+static bool
+instr_before(struct ir3_instruction *a, struct ir3_instruction *b)
+{
+ if (a->flags & IR3_INSTR_UNUSED)
+ return false;
+ return (a->ip < b->ip);
+}
+
static struct ir3_instruction *
get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
int *sz, int *off)
@@ -348,7 +356,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
dd = get_definer(ctx, src->instr, &dsz, &doff);
- if ((!d) || (dd->ip < d->ip)) {
+ if ((!d) || instr_before(dd, d)) {
d = dd;
*sz = dsz;
*off = doff - n;
@@ -369,9 +377,14 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
*/
int cnt = 0;
- d = f;
+ /* need to skip over unused in the group: */
+ while (f && (f->flags & IR3_INSTR_UNUSED)) {
+ f = f->cp.right;
+ cnt++;
+ }
+
while (f) {
- if (f->ip < d->ip)
+ if ((!d) || instr_before(f, d))
d = f;
if (f == instr)
*off = cnt;
@@ -414,7 +427,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
*sz = MAX2(*sz, dsz);
*off = doff;
- if (dd->ip < d->ip) {
+ if (instr_before(dd, d)) {
d = dd;
}
}
@@ -432,7 +445,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
foreach_src(src, d) {
if (!src->instr)
continue;
- if (src->instr->ip < dd->ip)
+ if (instr_before(src->instr, dd))
dd = src->instr;
}
@@ -446,7 +459,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
dd = get_definer(ctx, d->regs[1]->instr, &dsz, &doff);
/* by definition, should come before: */
- debug_assert(dd->ip < d->ip);
+ debug_assert(instr_before(dd, d));
*sz = MAX2(*sz, dsz);
@@ -577,7 +590,7 @@ ra_block_compute_live_ranges(struct ir3_ra_ctx *ctx, struct ir3_block *block)
bd->livein = rzalloc_array(bd, BITSET_WORD, bitset_words);
bd->liveout = rzalloc_array(bd, BITSET_WORD, bitset_words);
- block->bd = bd;
+ block->data = bd;
list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
struct ir3_instruction *src;
@@ -679,7 +692,7 @@ ra_compute_livein_liveout(struct ir3_ra_ctx *ctx)
bool progress = false;
list_for_each_entry (struct ir3_block, block, &ctx->ir->block_list, node) {
- struct ir3_ra_block_data *bd = block->bd;
+ struct ir3_ra_block_data *bd = block->data;
/* update livein: */
for (unsigned i = 0; i < bitset_words; i++) {
@@ -700,7 +713,7 @@ ra_compute_livein_liveout(struct ir3_ra_ctx *ctx)
if (!succ)
continue;
- succ_bd = succ->bd;
+ succ_bd = succ->data;
for (unsigned i = 0; i < bitset_words; i++) {
BITSET_WORD new_liveout =
@@ -736,7 +749,7 @@ ra_add_interference(struct ir3_ra_ctx *ctx)
/* extend start/end ranges based on livein/liveout info from cfg: */
unsigned bitset_words = BITSET_WORDS(ctx->alloc_count);
list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
- struct ir3_ra_block_data *bd = block->bd;
+ struct ir3_ra_block_data *bd = block->data;
for (unsigned i = 0; i < bitset_words; i++) {
if (BITSET_TEST(bd->livein, i)) {
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_sched.c b/src/gallium/drivers/freedreno/ir3/ir3_sched.c
index 2ee325518f7..6aaa16edbfe 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_sched.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_sched.c
@@ -34,11 +34,12 @@
/*
* Instruction Scheduling:
*
- * A priority-queue based scheduling algo. Add eligible instructions,
- * ie. ones with all their dependencies scheduled, to the priority
- * (depth) sorted queue (list). Pop highest priority instruction off
- * the queue and schedule it, add newly eligible instructions to the
- * priority queue, rinse, repeat.
+ * A recursive depth based scheduling algo. Recursively find an eligible
+ * instruction to schedule from the deepest instruction (recursing through
+ * it's unscheduled src instructions). Normally this would result in a
+ * lot of re-traversal of the same instructions, so we cache results in
+ * instr->data (and clear cached results that would be no longer valid
+ * after scheduling an instruction).
*
* There are a few special cases that need to be handled, since sched
* is currently independent of register allocation. Usages of address
@@ -52,6 +53,7 @@
struct ir3_sched_ctx {
struct ir3_block *block; /* the current block */
+ struct list_head depth_list; /* depth sorted unscheduled instrs */
struct ir3_instruction *scheduled; /* last scheduled instr XXX remove*/
struct ir3_instruction *addr; /* current a0.x user, if any */
struct ir3_instruction *pred; /* current p0.x user, if any */
@@ -63,6 +65,17 @@ static bool is_sfu_or_mem(struct ir3_instruction *instr)
return is_sfu(instr) || is_mem(instr);
}
+#define NULL_INSTR ((void *)~0)
+
+static void
+clear_cache(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
+{
+ list_for_each_entry (struct ir3_instruction, instr2, &ctx->depth_list, node) {
+ if ((instr2->data == instr) || (instr2->data == NULL_INSTR) || !instr)
+ instr2->data = NULL;
+ }
+}
+
static void
schedule(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
{
@@ -93,6 +106,34 @@ schedule(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
list_addtail(&instr->node, &instr->block->instr_list);
ctx->scheduled = instr;
+
+ if (writes_addr(instr) || writes_pred(instr) || is_input(instr)) {
+ clear_cache(ctx, NULL);
+ } else {
+ /* invalidate only the necessary entries.. */
+ clear_cache(ctx, instr);
+ }
+}
+
+static struct ir3_instruction *
+deepest(struct ir3_instruction **srcs, unsigned nsrcs)
+{
+ struct ir3_instruction *d = NULL;
+ unsigned i = 0, id = 0;
+
+ while ((i < nsrcs) && !(d = srcs[id = i]))
+ i++;
+
+ if (!d)
+ return NULL;
+
+ for (; i < nsrcs; i++)
+ if (srcs[i] && (srcs[i]->depth > d->depth))
+ d = srcs[id = i];
+
+ srcs[id] = NULL;
+
+ return d;
}
static unsigned
@@ -171,10 +212,51 @@ static bool is_scheduled(struct ir3_instruction *instr)
return !!(instr->flags & IR3_INSTR_MARK);
}
+/* could an instruction be scheduled if specified ssa src was scheduled? */
static bool
-check_conflict(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
+could_sched(struct ir3_instruction *instr, struct ir3_instruction *src)
+{
+ struct ir3_instruction *other_src;
+ foreach_ssa_src(other_src, instr) {
+ /* if dependency not scheduled, we aren't ready yet: */
+ if ((src != other_src) && !is_scheduled(other_src)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/* Check if instruction is ok to schedule. Make sure it is not blocked
+ * by use of addr/predicate register, etc.
+ */
+static bool
+check_instr(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
struct ir3_instruction *instr)
{
+ /* For instructions that write address register we need to
+ * make sure there is at least one instruction that uses the
+ * addr value which is otherwise ready.
+ *
+ * TODO if any instructions use pred register and have other
+ * src args, we would need to do the same for writes_pred()..
+ */
+ if (writes_addr(instr)) {
+ struct ir3 *ir = instr->block->shader;
+ bool ready = false;
+ for (unsigned i = 0; (i < ir->indirects_count) && !ready; i++) {
+ struct ir3_instruction *indirect = ir->indirects[i];
+ if (!indirect)
+ continue;
+ if (indirect->address != instr)
+ continue;
+ ready = could_sched(indirect, instr);
+ }
+
+ /* nothing could be scheduled, so keep looking: */
+ if (!ready)
+ return false;
+ }
+
/* if this is a write to address/predicate register, and that
* register is currently in use, we need to defer until it is
* free:
@@ -182,52 +264,15 @@ check_conflict(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
if (writes_addr(instr) && ctx->addr) {
debug_assert(ctx->addr != instr);
notes->addr_conflict = true;
- return true;
+ return false;
}
if (writes_pred(instr) && ctx->pred) {
debug_assert(ctx->pred != instr);
notes->pred_conflict = true;
- return true;
+ return false;
}
- return false;
-}
-
-/* is this instruction ready to be scheduled? Return negative for not
- * ready (updating notes if needed), or >= 0 to indicate number of
- * delay slots needed.
- */
-static int
-instr_eligibility(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
- struct ir3_instruction *instr)
-{
- struct ir3_instruction *src;
- unsigned delay = 0;
-
- /* Phi instructions can have a dependency on something not
- * scheduled yet (for ex, loops). But OTOH we don't really
- * care. By definition phi's should appear at the top of
- * the block, and it's sources should be values from the
- * previously executing block, so they are always ready to
- * be scheduled:
- */
- if (is_meta(instr) && (instr->opc == OPC_META_PHI))
- return 0;
-
- foreach_ssa_src(src, instr) {
- /* if dependency not scheduled, we aren't ready yet: */
- if (!is_scheduled(src))
- return -1;
- }
-
- /* all our dependents are scheduled, figure out if
- * we have enough delay slots to schedule ourself:
- */
- delay = delay_calc(ctx, instr);
- if (delay)
- return delay;
-
/* if the instruction is a kill, we need to ensure *every*
* bary.f is scheduled. The hw seems unhappy if the thread
* gets killed before the end-input (ei) flag is hit.
@@ -246,80 +291,109 @@ instr_eligibility(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
for (unsigned i = 0; i < ir->baryfs_count; i++) {
struct ir3_instruction *baryf = ir->baryfs[i];
- if (baryf->depth == DEPTH_UNUSED)
+ if (baryf->flags & IR3_INSTR_UNUSED)
continue;
if (!is_scheduled(baryf)) {
notes->blocked_kill = true;
- return -1;
+ return false;
}
}
}
- if (check_conflict(ctx, notes, instr))
- return -1;
-
- return 0;
-}
-
-/* could an instruction be scheduled if specified ssa src was scheduled? */
-static bool
-could_sched(struct ir3_instruction *instr, struct ir3_instruction *src)
-{
- struct ir3_instruction *other_src;
- foreach_ssa_src(other_src, instr) {
- /* if dependency not scheduled, we aren't ready yet: */
- if ((src != other_src) && !is_scheduled(other_src)) {
- return false;
- }
- }
return true;
}
-/* move eligible instructions to the priority list: */
-static unsigned
-add_eligible_instrs(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
- struct list_head *prio_queue, struct list_head *unscheduled_list)
+/* Find the best instruction to schedule from specified instruction or
+ * recursively it's ssa sources.
+ */
+static struct ir3_instruction *
+find_instr_recursive(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
+ struct ir3_instruction *instr)
{
- unsigned min_delay = ~0;
+ struct ir3_instruction *srcs[__ssa_src_cnt(instr)];
+ struct ir3_instruction *src;
+ unsigned nsrcs = 0;
- list_for_each_entry_safe (struct ir3_instruction, instr, unscheduled_list, node) {
- int e = instr_eligibility(ctx, notes, instr);
- if (e < 0)
- continue;
+ if (is_scheduled(instr))
+ return NULL;
- /* For instructions that write address register we need to
- * make sure there is at least one instruction that uses the
- * addr value which is otherwise ready.
- *
- * TODO if any instructions use pred register and have other
- * src args, we would need to do the same for writes_pred()..
- */
- if (unlikely(writes_addr(instr))) {
- struct ir3 *ir = instr->block->shader;
- bool ready = false;
- for (unsigned i = 0; (i < ir->indirects_count) && !ready; i++) {
- struct ir3_instruction *indirect = ir->indirects[i];
- if (!indirect)
- continue;
- if (indirect->address != instr)
- continue;
- ready = could_sched(indirect, instr);
- }
+ /* use instr->data to cache the results of recursing up the
+ * instr src's. Otherwise the recursive algo can scale quite
+ * badly w/ shader size. But this takes some care to clear
+ * the cache appropriately when instructions are scheduled.
+ */
+ if (instr->data) {
+ if (instr->data == NULL_INSTR)
+ return NULL;
+ return instr->data;
+ }
- /* nothing could be scheduled, so keep looking: */
- if (!ready)
- continue;
- }
-
- min_delay = MIN2(min_delay, e);
- if (e == 0) {
- /* remove from unscheduled list and into priority queue: */
- list_delinit(&instr->node);
- ir3_insert_by_depth(instr, prio_queue);
+ /* find unscheduled srcs: */
+ foreach_ssa_src(src, instr) {
+ if (!is_scheduled(src)) {
+ debug_assert(nsrcs < ARRAY_SIZE(srcs));
+ srcs[nsrcs++] = src;
}
}
- return min_delay;
+ /* if all our src's are already scheduled: */
+ if (nsrcs == 0) {
+ if (check_instr(ctx, notes, instr)) {
+ instr->data = instr;
+ return instr;
+ }
+ return NULL;
+ }
+
+ while ((src = deepest(srcs, nsrcs))) {
+ struct ir3_instruction *candidate;
+
+ candidate = find_instr_recursive(ctx, notes, src);
+ if (!candidate)
+ continue;
+
+ if (check_instr(ctx, notes, candidate)) {
+ instr->data = candidate;
+ return candidate;
+ }
+ }
+
+ instr->data = NULL_INSTR;
+ return NULL;
+}
+
+/* find instruction to schedule: */
+static struct ir3_instruction *
+find_eligible_instr(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes)
+{
+ struct ir3_instruction *best_instr = NULL;
+ unsigned min_delay = ~0;
+
+ /* TODO we'd really rather use the list/array of block outputs. But we
+ * don't have such a thing. Recursing *every* instruction in the list
+ * will result in a lot of repeated traversal, since instructions will
+ * get traversed both when they appear as ssa src to a later instruction
+ * as well as where they appear in the depth_list.
+ */
+ list_for_each_entry_rev (struct ir3_instruction, instr, &ctx->depth_list, node) {
+ struct ir3_instruction *candidate;
+ unsigned delay;
+
+ candidate = find_instr_recursive(ctx, notes, instr);
+ if (!candidate)
+ continue;
+
+ delay = delay_calc(ctx, candidate);
+ if (delay < min_delay) {
+ best_instr = candidate;
+ min_delay = delay;
+ }
+
+ if (min_delay == 0)
+ break;
+ }
+
+ return best_instr;
}
/* "spill" the address register by remapping any unscheduled
@@ -413,50 +487,55 @@ split_pred(struct ir3_sched_ctx *ctx)
static void
sched_block(struct ir3_sched_ctx *ctx, struct ir3_block *block)
{
- struct list_head unscheduled_list, prio_queue;
+ struct list_head unscheduled_list;
ctx->block = block;
+ /* addr/pred writes are per-block: */
+ ctx->addr = NULL;
+ ctx->pred = NULL;
+
/* move all instructions to the unscheduled list, and
* empty the block's instruction list (to which we will
- * be inserting.
+ * be inserting).
*/
list_replace(&block->instr_list, &unscheduled_list);
list_inithead(&block->instr_list);
- list_inithead(&prio_queue);
+ list_inithead(&ctx->depth_list);
/* first a pre-pass to schedule all meta:input/phi instructions
* (which need to appear first so that RA knows the register is
- * occupied:
+ * occupied), and move remaining to depth sorted list:
*/
list_for_each_entry_safe (struct ir3_instruction, instr, &unscheduled_list, node) {
if (is_meta(instr) && ((instr->opc == OPC_META_INPUT) ||
- (instr->opc == OPC_META_PHI)))
+ (instr->opc == OPC_META_PHI))) {
schedule(ctx, instr);
+ } else {
+ ir3_insert_by_depth(instr, &ctx->depth_list);
+ }
}
- while (!(list_empty(&unscheduled_list) &&
- list_empty(&prio_queue))) {
+ while (!list_empty(&ctx->depth_list)) {
struct ir3_sched_notes notes = {0};
- unsigned delay;
+ struct ir3_instruction *instr;
- delay = add_eligible_instrs(ctx, ¬es, &prio_queue, &unscheduled_list);
+ instr = find_eligible_instr(ctx, ¬es);
- if (!list_empty(&prio_queue)) {
- struct ir3_instruction *instr = list_last_entry(&prio_queue,
- struct ir3_instruction, node);
- /* ugg, this is a bit ugly, but between the time when
- * the instruction became eligible and now, a new
- * conflict may have arose..
+ if (instr) {
+ unsigned delay = delay_calc(ctx, instr);
+
+ /* and if we run out of instructions that can be scheduled,
+ * then it is time for nop's:
*/
- if (check_conflict(ctx, ¬es, instr)) {
- list_del(&instr->node);
- list_addtail(&instr->node, &unscheduled_list);
- continue;
+ debug_assert(delay <= 6);
+ while (delay > 0) {
+ ir3_NOP(block);
+ delay--;
}
schedule(ctx, instr);
- } else if (delay == ~0) {
+ } else {
struct ir3_instruction *new_instr = NULL;
/* nothing available to schedule.. if we are blocked on
@@ -475,23 +554,17 @@ sched_block(struct ir3_sched_ctx *ctx, struct ir3_block *block)
}
if (new_instr) {
- list_del(&new_instr->node);
- list_addtail(&new_instr->node, &unscheduled_list);
+ /* clearing current addr/pred can change what is
+ * available to schedule, so clear cache..
+ */
+ clear_cache(ctx, NULL);
+
+ ir3_insert_by_depth(new_instr, &ctx->depth_list);
/* the original instr that wrote addr/pred may have
* originated from a different block:
*/
new_instr->block = block;
}
-
- } else {
- /* and if we run out of instructions that can be scheduled,
- * then it is time for nop's:
- */
- debug_assert(delay <= 6);
- while (delay > 0) {
- ir3_NOP(block);
- delay--;
- }
}
}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.h b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
index 5d1cccb0daa..cf99a4c05ed 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_shader.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
@@ -195,7 +195,15 @@ struct ir3_shader_variant {
enum glsl_interp_qualifier interpolate;
} inputs[16 + 2]; /* +POSITION +FACE */
- unsigned total_in; /* sum of inputs (scalar) */
+ /* sum of input components (scalar). For frag shaders, it only counts
+ * the varying inputs:
+ */
+ unsigned total_in;
+
+ /* For frag shaders, the total number of inputs (not scalar,
+ * ie. SP_VS_PARAM_REG.TOTALVSOUTVAR)
+ */
+ unsigned varying_in;
/* do we have one or more texture sample instructions: */
bool has_samp;
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 05f8e93ddea..82798bbb543 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -160,7 +160,7 @@ i915_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
struct i915_context *i915;
i915 = CALLOC_STRUCT(i915_context);
- if (i915 == NULL)
+ if (!i915)
return NULL;
i915->iws = i915_screen(screen)->iws;
diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c
index 8f61f151e0c..c0ba23b3be8 100644
--- a/src/gallium/drivers/i915/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915/i915_prim_vbuf.c
@@ -761,11 +761,11 @@ struct draw_stage *i915_draw_vbuf_stage(struct i915_context *i915)
struct draw_stage *stage;
render = i915_vbuf_render_create(i915);
- if(!render)
+ if (!render)
return NULL;
stage = draw_vbuf_stage(i915->draw, render);
- if(!stage) {
+ if (!stage) {
render->destroy(render);
return NULL;
}
diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c
index 9fb3855a37e..fb2e53b014f 100644
--- a/src/gallium/drivers/i915/i915_resource_buffer.c
+++ b/src/gallium/drivers/i915/i915_resource_buffer.c
@@ -72,7 +72,7 @@ i915_buffer_transfer_map(struct pipe_context *pipe,
struct i915_buffer *buffer = i915_buffer(resource);
struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool);
- if (transfer == NULL)
+ if (!transfer)
return NULL;
transfer->resource = resource;
diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c
index 9a3279ccb75..03cdcf1c990 100644
--- a/src/gallium/drivers/i915/i915_resource_texture.c
+++ b/src/gallium/drivers/i915/i915_resource_texture.c
@@ -728,7 +728,7 @@ i915_texture_transfer_map(struct pipe_context *pipe,
unsigned offset;
char *map;
- if (transfer == NULL)
+ if (!transfer)
return NULL;
transfer->b.resource = resource;
@@ -774,7 +774,7 @@ i915_texture_transfer_map(struct pipe_context *pipe,
map = iws->buffer_map(iws, tex->buffer,
(transfer->b.usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
- if (map == NULL) {
+ if (!map) {
pipe_resource_reference(&transfer->staging_texture, NULL);
FREE(transfer);
return NULL;
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index 2441b3c0d88..223be931e05 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -337,7 +337,7 @@ lp_scene_new_data_block( struct lp_scene *scene )
}
else {
struct data_block *block = MALLOC_STRUCT(data_block);
- if (block == NULL)
+ if (!block)
return NULL;
scene->scene_size += sizeof *block;
diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.c b/src/gallium/drivers/llvmpipe/lp_scene_queue.c
index 975db43c4e9..debc7a6fe18 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene_queue.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.c
@@ -60,7 +60,7 @@ struct lp_scene_queue *
lp_scene_queue_create(void)
{
struct lp_scene_queue *queue = CALLOC_STRUCT(lp_scene_queue);
- if (queue == NULL)
+ if (!queue)
return NULL;
queue->ring = util_ringbuffer_create( MAX_SCENE_QUEUE *
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 9f5e7378ac7..899f28da7d3 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -460,7 +460,8 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
}
}
- if (format_desc->layout == UTIL_FORMAT_LAYOUT_BPTC) {
+ if (format_desc->layout == UTIL_FORMAT_LAYOUT_BPTC ||
+ format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC) {
/* Software decoding is not hooked up. */
return FALSE;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c
index a190254d9df..fac1cd61d77 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_line.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c
@@ -311,6 +311,7 @@ try_setup_line( struct lp_setup_context *setup,
float y2diff;
float dx, dy;
float area;
+ const float (*pv)[4];
boolean draw_start;
boolean draw_end;
@@ -320,22 +321,28 @@ try_setup_line( struct lp_setup_context *setup,
if (0)
print_line(setup, v1, v2);
+ if (setup->flatshade_first) {
+ pv = v1;
+ }
+ else {
+ pv = v2;
+ }
+ if (setup->viewport_index_slot > 0) {
+ unsigned *udata = (unsigned*)pv[setup->viewport_index_slot];
+ viewport_index = lp_clamp_viewport_idx(*udata);
+ }
+ if (setup->layer_slot > 0) {
+ layer = *(unsigned*)pv[setup->layer_slot];
+ layer = MIN2(layer, scene->fb_max_layer);
+ }
+
if (setup->scissor_test) {
nr_planes = 8;
- if (setup->viewport_index_slot > 0) {
- unsigned *udata = (unsigned*)v1[setup->viewport_index_slot];
- viewport_index = lp_clamp_viewport_idx(*udata);
- }
}
else {
nr_planes = 4;
}
- if (setup->layer_slot > 0) {
- layer = *(unsigned*)v1[setup->layer_slot];
- layer = MIN2(layer, scene->fb_max_layer);
- }
-
dx = v1[0][0] - v2[0][0];
dy = v1[0][1] - v2[0][1];
area = (dx * dx + dy * dy);
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index 98a9d4bc28b..b1671dd0ae2 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -96,7 +96,7 @@ lp_setup_alloc_triangle(struct lp_scene *scene,
plane_sz);
tri = lp_scene_alloc_aligned( scene, *tri_size, 16 );
- if (tri == NULL)
+ if (!tri)
return NULL;
tri->inputs.stride = input_array_sz;
@@ -276,6 +276,7 @@ do_triangle_ccw(struct lp_setup_context *setup,
int nr_planes = 3;
unsigned viewport_index = 0;
unsigned layer = 0;
+ const float (*pv)[4];
/* Area should always be positive here */
assert(position->area > 0);
@@ -283,20 +284,27 @@ do_triangle_ccw(struct lp_setup_context *setup,
if (0)
lp_setup_print_triangle(setup, v0, v1, v2);
+ if (setup->flatshade_first) {
+ pv = v0;
+ }
+ else {
+ pv = v2;
+ }
+ if (setup->viewport_index_slot > 0) {
+ unsigned *udata = (unsigned*)pv[setup->viewport_index_slot];
+ viewport_index = lp_clamp_viewport_idx(*udata);
+ }
+ if (setup->layer_slot > 0) {
+ layer = *(unsigned*)pv[setup->layer_slot];
+ layer = MIN2(layer, scene->fb_max_layer);
+ }
+
if (setup->scissor_test) {
nr_planes = 7;
- if (setup->viewport_index_slot > 0) {
- unsigned *udata = (unsigned*)v0[setup->viewport_index_slot];
- viewport_index = lp_clamp_viewport_idx(*udata);
- }
}
else {
nr_planes = 3;
}
- if (setup->layer_slot > 0) {
- layer = *(unsigned*)v1[setup->layer_slot];
- layer = MIN2(layer, scene->fb_max_layer);
- }
/* Bounding rectangle (in pixels) */
{
diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c
index e38de9aca0a..3c898c38c24 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c
@@ -87,7 +87,7 @@ llvmpipe_set_blend_color(struct pipe_context *pipe,
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
- if(!blend_color)
+ if (!blend_color)
return;
if(memcmp(&llvmpipe->blend_color, blend_color, sizeof *blend_color) == 0)
@@ -159,7 +159,7 @@ llvmpipe_set_stencil_ref(struct pipe_context *pipe,
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
- if(!stencil_ref)
+ if (!stencil_ref)
return;
if(memcmp(&llvmpipe->stencil_ref, stencil_ref, sizeof *stencil_ref) == 0)
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index f55f6b4fa4f..079083e9601 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -2563,7 +2563,7 @@ generate_variant(struct llvmpipe_context *lp,
char module_name[64];
variant = CALLOC_STRUCT(lp_fragment_shader_variant);
- if(!variant)
+ if (!variant)
return NULL;
util_snprintf(module_name, sizeof(module_name), "fs%u_variant%u",
diff --git a/src/gallium/drivers/llvmpipe/lp_state_gs.c b/src/gallium/drivers/llvmpipe/lp_state_gs.c
index 7ea7a390669..405a415624e 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_gs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_gs.c
@@ -47,7 +47,7 @@ llvmpipe_create_gs_state(struct pipe_context *pipe,
struct lp_geometry_shader *state;
state = CALLOC_STRUCT(lp_geometry_shader);
- if (state == NULL )
+ if (!state)
goto no_state;
/* debug */
diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
index 94ebf8ffffb..ef6958d99fe 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
@@ -64,7 +64,7 @@ llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
* handle, and what we'll look after ourselves.
*/
struct lp_rast_state *state = MALLOC_STRUCT(lp_rast_state);
- if (state == NULL)
+ if (!state)
return NULL;
memcpy(&state->draw_state, rast, sizeof *rast);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c
index 6397b5196d0..64215be91af 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c
@@ -723,7 +723,7 @@ generate_setup_variant(struct lp_setup_variant_key *key,
goto fail;
variant = CALLOC_STRUCT(lp_setup_variant);
- if (variant == NULL)
+ if (!variant)
goto fail;
variant->no = setup_no++;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vs.c b/src/gallium/drivers/llvmpipe/lp_state_vs.c
index 826ee5b72b1..96a00189b55 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vs.c
@@ -46,7 +46,7 @@ llvmpipe_create_vs_state(struct pipe_context *pipe,
struct draw_vertex_shader *vs;
vs = draw_create_vertex_shader(llvmpipe->draw, templ);
- if (vs == NULL) {
+ if (!vs) {
return NULL;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c
index 37420b02442..7b19174f345 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
@@ -625,9 +625,9 @@ const struct lp_type blend_types[] = {
};
-const unsigned num_funcs = sizeof(blend_funcs)/sizeof(blend_funcs[0]);
-const unsigned num_factors = sizeof(blend_factors)/sizeof(blend_factors[0]);
-const unsigned num_types = sizeof(blend_types)/sizeof(blend_types[0]);
+const unsigned num_funcs = ARRAY_SIZE(blend_funcs);
+const unsigned num_factors = ARRAY_SIZE(blend_factors);
+const unsigned num_types = ARRAY_SIZE(blend_types);
boolean
diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c
index 8290da4004b..a30f35c8149 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_conv.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c
@@ -382,7 +382,7 @@ const struct lp_type conv_types[] = {
};
-const unsigned num_types = sizeof(conv_types)/sizeof(conv_types[0]);
+const unsigned num_types = ARRAY_SIZE(conv_types);
boolean
diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c
index 0640a217874..3f2ed8458a3 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_format.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_format.c
@@ -382,6 +382,18 @@ test_all(unsigned verbose, FILE *fp)
continue;
}
+ /* only have util fetch func for etc1 */
+ if (format_desc->layout == UTIL_FORMAT_LAYOUT_ETC &&
+ format != PIPE_FORMAT_ETC1_RGB8) {
+ continue;
+ }
+
+ /* missing fetch funcs */
+ if (format_desc->layout == UTIL_FORMAT_LAYOUT_BPTC ||
+ format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC) {
+ continue;
+ }
+
if (!test_one(verbose, fp, format_desc)) {
success = FALSE;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_test_main.c b/src/gallium/drivers/llvmpipe/lp_test_main.c
index d835dbbd62e..3bcbac34601 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_main.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_main.c
@@ -397,7 +397,7 @@ int main(int argc, char **argv)
}
#endif
- if(fp) {
+ if (fp) {
/* Warm up the caches */
test_some(0, NULL, 100);
@@ -411,7 +411,7 @@ int main(int argc, char **argv)
else
success = test_all(verbose, fp);
- if(fp)
+ if (fp)
fclose(fp);
return success ? 0 : 1;
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
index 217abe963b7..5762b7b4833 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
@@ -309,7 +309,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state)
struct lp_llvm_sampler_soa *sampler;
sampler = CALLOC_STRUCT(lp_llvm_sampler_soa);
- if(!sampler)
+ if (!sampler)
return NULL;
sampler->base.destroy = lp_llvm_sampler_soa_destroy;
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 82868814581..ae266ceb082 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -695,7 +695,7 @@ llvmpipe_user_buffer_create(struct pipe_screen *screen,
struct llvmpipe_resource *buffer;
buffer = CALLOC_STRUCT(llvmpipe_resource);
- if(!buffer)
+ if (!buffer)
return NULL;
pipe_reference_init(&buffer->base.reference, 1);
diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c
index e644685123e..165284a90bf 100644
--- a/src/gallium/drivers/noop/noop_pipe.c
+++ b/src/gallium/drivers/noop/noop_pipe.c
@@ -96,7 +96,7 @@ static struct pipe_resource *noop_resource_create(struct pipe_screen *screen,
unsigned stride;
nresource = CALLOC_STRUCT(noop_resource);
- if (nresource == NULL)
+ if (!nresource)
return NULL;
stride = util_format_get_stride(templ->format, templ->width0);
@@ -158,7 +158,7 @@ static void *noop_transfer_map(struct pipe_context *pipe,
struct noop_resource *nresource = (struct noop_resource *)resource;
transfer = CALLOC_STRUCT(pipe_transfer);
- if (transfer == NULL)
+ if (!transfer)
return NULL;
pipe_resource_reference(&transfer->resource, resource);
transfer->level = level;
@@ -265,7 +265,7 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen,
{
struct pipe_context *ctx = CALLOC_STRUCT(pipe_context);
- if (ctx == NULL)
+ if (!ctx)
return NULL;
ctx->screen = screen;
ctx->priv = priv;
@@ -374,7 +374,7 @@ struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen)
}
noop_screen = CALLOC_STRUCT(noop_pipe_screen);
- if (noop_screen == NULL) {
+ if (!noop_screen) {
return NULL;
}
noop_screen->oscreen = oscreen;
diff --git a/src/gallium/drivers/noop/noop_state.c b/src/gallium/drivers/noop/noop_state.c
index 5cb37b656de..fe5b5e4696e 100644
--- a/src/gallium/drivers/noop/noop_state.c
+++ b/src/gallium/drivers/noop/noop_state.c
@@ -44,7 +44,7 @@ static void *noop_create_blend_state(struct pipe_context *ctx,
{
struct pipe_blend_state *nstate = CALLOC_STRUCT(pipe_blend_state);
- if (nstate == NULL) {
+ if (!nstate) {
return NULL;
}
*nstate = *state;
@@ -56,7 +56,7 @@ static void *noop_create_dsa_state(struct pipe_context *ctx,
{
struct pipe_depth_stencil_alpha_state *nstate = CALLOC_STRUCT(pipe_depth_stencil_alpha_state);
- if (nstate == NULL) {
+ if (!nstate) {
return NULL;
}
*nstate = *state;
@@ -68,7 +68,7 @@ static void *noop_create_rs_state(struct pipe_context *ctx,
{
struct pipe_rasterizer_state *nstate = CALLOC_STRUCT(pipe_rasterizer_state);
- if (nstate == NULL) {
+ if (!nstate) {
return NULL;
}
*nstate = *state;
@@ -80,7 +80,7 @@ static void *noop_create_sampler_state(struct pipe_context *ctx,
{
struct pipe_sampler_state *nstate = CALLOC_STRUCT(pipe_sampler_state);
- if (nstate == NULL) {
+ if (!nstate) {
return NULL;
}
*nstate = *state;
@@ -93,7 +93,7 @@ static struct pipe_sampler_view *noop_create_sampler_view(struct pipe_context *c
{
struct pipe_sampler_view *sampler_view = CALLOC_STRUCT(pipe_sampler_view);
- if (sampler_view == NULL)
+ if (!sampler_view)
return NULL;
/* initialize base object */
pipe_resource_reference(&sampler_view->texture, texture);
@@ -108,7 +108,7 @@ static struct pipe_surface *noop_create_surface(struct pipe_context *ctx,
{
struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
- if (surface == NULL)
+ if (!surface)
return NULL;
pipe_reference_init(&surface->reference, 1);
pipe_resource_reference(&surface->texture, texture);
@@ -228,7 +228,7 @@ static void *noop_create_vertex_elements(struct pipe_context *ctx,
{
struct pipe_vertex_element *nstate = CALLOC_STRUCT(pipe_vertex_element);
- if (nstate == NULL) {
+ if (!nstate) {
return NULL;
}
*nstate = *state;
@@ -240,7 +240,7 @@ static void *noop_create_shader_state(struct pipe_context *ctx,
{
struct pipe_shader_state *nstate = CALLOC_STRUCT(pipe_shader_state);
- if (nstate == NULL) {
+ if (!nstate) {
return NULL;
}
*nstate = *state;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_bb.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_bb.cpp
index fa8ee072a92..9f0e0733326 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_bb.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_bb.cpp
@@ -291,7 +291,7 @@ void BasicBlock::permuteAdjacent(Instruction *a, Instruction *b)
if (b->prev)
b->prev->next = b;
- if (a->prev)
+ if (a->next)
a->next->prev = a;
}
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
index b163cd2db4a..b1064bf0a92 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
@@ -75,6 +75,7 @@ private:
void emitLOAD(const Instruction *);
void emitSTORE(const Instruction *);
void emitMOV(const Instruction *);
+ void emitMEMBAR(const Instruction *);
void emitINTERP(const Instruction *);
void emitAFETCH(const Instruction *);
@@ -575,8 +576,8 @@ CodeEmitterGK110::emitIMUL(const Instruction *i)
if (isLIMM(i->src(1), TYPE_S32)) {
emitForm_L(i, 0x280, 2, Modifier(0));
- assert(i->subOp != NV50_IR_SUBOP_MUL_HIGH);
-
+ if (i->subOp == NV50_IR_SUBOP_MUL_HIGH)
+ code[1] |= 1 << 24;
if (i->sType == TYPE_S32)
code[1] |= 3 << 25;
} else {
@@ -695,14 +696,9 @@ CodeEmitterGK110::emitIMAD(const Instruction *i)
if (i->sType == TYPE_S32)
code[1] |= (1 << 19) | (1 << 24);
- if (code[0] & 0x1) {
- assert(!i->subOp);
- SAT_(39);
- } else {
- if (i->subOp == NV50_IR_SUBOP_MUL_HIGH)
- code[1] |= 1 << 25;
- SAT_(35);
- }
+ if (i->subOp == NV50_IR_SUBOP_MUL_HIGH)
+ code[1] |= 1 << 25;
+ SAT_(35);
}
void
@@ -1687,6 +1683,14 @@ CodeEmitterGK110::emitMOV(const Instruction *i)
}
}
+void CodeEmitterGK110::emitMEMBAR(const Instruction *i)
+{
+ code[0] = 0x00000002 | NV50_IR_SUBOP_MEMBAR_SCOPE(i->subOp) << 8;
+ code[1] = 0x7cc00000;
+
+ emitPredicate(i);
+}
+
bool
CodeEmitterGK110::emitInstruction(Instruction *insn)
{
@@ -1918,6 +1922,9 @@ CodeEmitterGK110::emitInstruction(Instruction *insn)
case OP_BAR:
emitBAR(insn);
break;
+ case OP_MEMBAR:
+ emitMEMBAR(insn);
+ break;
case OP_PHI:
case OP_UNION:
case OP_CONSTRAINT:
@@ -1930,7 +1937,7 @@ CodeEmitterGK110::emitInstruction(Instruction *insn)
ERROR("operation should have been lowered\n");
return false;
default:
- ERROR("unknow op\n");
+ ERROR("unknown op: %u\n", insn->op);
return false;
}
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
index 0b5288218d1..216e119af63 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
@@ -756,10 +756,10 @@ CodeEmitterNV50::emitMOV(const Instruction *i)
assert(sf == FILE_GPR || df == FILE_GPR);
if (sf == FILE_FLAGS) {
+ assert(i->flagsSrc >= 0);
code[0] = 0x00000001;
code[1] = 0x20000000;
defId(i->def(0), 2);
- srcId(i->src(0), 12);
emitFlagsRd(i);
} else
if (sf == FILE_ADDRESS) {
@@ -770,11 +770,12 @@ CodeEmitterNV50::emitMOV(const Instruction *i)
emitFlagsRd(i);
} else
if (df == FILE_FLAGS) {
+ assert(i->flagsDef >= 0);
code[0] = 0x00000001;
code[1] = 0xa0000000;
- defId(i->def(0), 4);
srcId(i->src(0), 9);
emitFlagsRd(i);
+ emitFlagsWr(i);
} else
if (sf == FILE_IMMEDIATE) {
code[0] = 0x10008001;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
index 9f84de03a4a..1d4f0d92f6b 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
@@ -2566,7 +2566,7 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn)
ERROR("operation should have been lowered\n");
return false;
default:
- ERROR("unknow op\n");
+ ERROR("unknown op: %u\n", insn->op);
return false;
}
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
index 08a73d79781..1d2caaba72f 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -2893,6 +2893,12 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
bb->cfg.attach(&loopBB->cfg, Graph::Edge::BACK);
}
setPosition(reinterpret_cast(breakBBs.pop().u.p), true);
+
+ // If the loop never breaks (e.g. only has RET's inside), then there
+ // will be no way to get to the break bb. However BGNLOOP will have
+ // already made a PREBREAK to it, so it must be in the CFG.
+ if (getBB()->cfg.incidentCount() == 0)
+ loopBB->cfg.attach(&getBB()->cfg, Graph::Edge::TREE);
}
break;
case TGSI_OPCODE_BRK:
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp
index 75164ef0641..64f5fc0031e 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp
@@ -202,7 +202,8 @@ NV50LegalizePostRA::visit(Function *fn)
Program *prog = fn->getProgram();
r63 = new_LValue(fn, FILE_GPR);
- if (prog->maxGPR < 63)
+ // GPR units on nv50 are in half-regs
+ if (prog->maxGPR < 126)
r63->reg.data.id = 63;
else
r63->reg.data.id = 127;
@@ -293,8 +294,7 @@ NV50LegalizePostRA::visit(BasicBlock *bb)
next = hi;
}
- if (i->op != OP_MOV && i->op != OP_PFETCH &&
- i->op != OP_BAR &&
+ if (i->op != OP_PFETCH && i->op != OP_BAR &&
(!i->defExists(0) || i->def(0).getFile() != FILE_ADDRESS))
replaceZero(i);
}
@@ -832,7 +832,7 @@ NV50LoweringPreSSA::handleTXB(TexInstruction *i)
}
Value *flags = bld.getScratch(1, FILE_FLAGS);
bld.setPosition(cond, true);
- bld.mkCvt(OP_CVT, TYPE_U8, flags, TYPE_U32, cond->getDef(0));
+ bld.mkCvt(OP_CVT, TYPE_U8, flags, TYPE_U32, cond->getDef(0))->flagsDef = 0;
Instruction *tex[4];
for (l = 0; l < 4; ++l) {
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
index b3fc73a2beb..0f575f2eedd 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -686,7 +686,7 @@ NVC0LoweringPass::handleTEX(TexInstruction *i)
i->tex.s = 0x1f;
i->setIndirectR(hnd);
i->setIndirectS(NULL);
- } else if (i->tex.r == i->tex.s) {
+ } else if (i->tex.r == i->tex.s || i->op == OP_TXF) {
i->tex.r += prog->driver->io.texBindBase / 4;
i->tex.s = 0; // only a single cX[] value possible here
} else {
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
index 0f1dcf0dacd..805be5fcb40 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
@@ -265,6 +265,60 @@ LoadPropagation::visit(BasicBlock *bb)
// =============================================================================
+class IndirectPropagation : public Pass
+{
+private:
+ virtual bool visit(BasicBlock *);
+};
+
+bool
+IndirectPropagation::visit(BasicBlock *bb)
+{
+ const Target *targ = prog->getTarget();
+ Instruction *next;
+
+ for (Instruction *i = bb->getEntry(); i; i = next) {
+ next = i->next;
+
+ for (int s = 0; i->srcExists(s); ++s) {
+ Instruction *insn;
+ ImmediateValue imm;
+ if (!i->src(s).isIndirect(0))
+ continue;
+ insn = i->getIndirect(s, 0)->getInsn();
+ if (!insn)
+ continue;
+ if (insn->op == OP_ADD && !isFloatType(insn->dType)) {
+ if (insn->src(0).getFile() != targ->nativeFile(FILE_ADDRESS) ||
+ !insn->src(1).getImmediate(imm) ||
+ !targ->insnCanLoadOffset(i, s, imm.reg.data.s32))
+ continue;
+ i->setIndirect(s, 0, insn->getSrc(0));
+ i->setSrc(s, cloneShallow(func, i->getSrc(s)));
+ i->src(s).get()->reg.data.offset += imm.reg.data.u32;
+ } else if (insn->op == OP_SUB && !isFloatType(insn->dType)) {
+ if (insn->src(0).getFile() != targ->nativeFile(FILE_ADDRESS) ||
+ !insn->src(1).getImmediate(imm) ||
+ !targ->insnCanLoadOffset(i, s, -imm.reg.data.s32))
+ continue;
+ i->setIndirect(s, 0, insn->getSrc(0));
+ i->setSrc(s, cloneShallow(func, i->getSrc(s)));
+ i->src(s).get()->reg.data.offset -= imm.reg.data.u32;
+ } else if (insn->op == OP_MOV) {
+ if (!insn->src(0).getImmediate(imm) ||
+ !targ->insnCanLoadOffset(i, s, imm.reg.data.s32))
+ continue;
+ i->setIndirect(s, 0, NULL);
+ i->setSrc(s, cloneShallow(func, i->getSrc(s)));
+ i->src(s).get()->reg.data.offset += imm.reg.data.u32;
+ }
+ }
+ }
+ return true;
+}
+
+// =============================================================================
+
// Evaluate constant expressions.
class ConstantFolding : public Pass
{
@@ -670,6 +724,34 @@ ConstantFolding::expr(Instruction *i,
res.data.u32 = ((a->data.u32 << offset) & bitmask) | (c->data.u32 & ~bitmask);
break;
}
+ case OP_MAD:
+ case OP_FMA: {
+ switch (i->dType) {
+ case TYPE_F32:
+ res.data.f32 = a->data.f32 * b->data.f32 * exp2f(i->postFactor) +
+ c->data.f32;
+ break;
+ case TYPE_F64:
+ res.data.f64 = a->data.f64 * b->data.f64 + c->data.f64;
+ break;
+ case TYPE_S32:
+ if (i->subOp == NV50_IR_SUBOP_MUL_HIGH) {
+ res.data.s32 = ((int64_t)a->data.s32 * b->data.s32 >> 32) + c->data.s32;
+ break;
+ }
+ /* fallthrough */
+ case TYPE_U32:
+ if (i->subOp == NV50_IR_SUBOP_MUL_HIGH) {
+ res.data.u32 = ((uint64_t)a->data.u32 * b->data.u32 >> 32) + c->data.u32;
+ break;
+ }
+ res.data.u32 = a->data.u32 * b->data.u32 + c->data.u32;
+ break;
+ default:
+ return;
+ }
+ break;
+ }
default:
return;
}
@@ -684,6 +766,8 @@ ConstantFolding::expr(Instruction *i,
i->setSrc(2, NULL);
i->getSrc(0)->reg.data = res.data;
+ i->getSrc(0)->reg.type = i->dType;
+ i->getSrc(0)->reg.size = typeSizeof(i->dType);
i->op = OP_MOV;
}
@@ -858,6 +942,12 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s)
i->src(0).mod = i->src(t).mod;
i->setSrc(1, new_ImmediateValue(prog, imm0.reg.data.u32));
i->src(1).mod = 0;
+ } else
+ if (i->postFactor && i->sType == TYPE_F32) {
+ /* Can't emit a postfactor with an immediate, have to fold it in */
+ i->setSrc(s, new_ImmediateValue(
+ prog, imm0.reg.data.f32 * exp2f(i->postFactor)));
+ i->postFactor = 0;
}
break;
case OP_MAD:
@@ -870,7 +960,8 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s)
if (i->op != OP_CVT)
i->src(0).mod = 0;
} else
- if (imm0.isInteger(1) || imm0.isInteger(-1)) {
+ if (i->subOp != NV50_IR_SUBOP_MUL_HIGH &&
+ (imm0.isInteger(1) || imm0.isInteger(-1))) {
if (imm0.isNegative())
i->src(t).mod = i->src(t).mod ^ Modifier(NV50_IR_MOD_NEG);
if (s == 0) {
@@ -1096,13 +1187,59 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s)
break;
// try to concatenate shifts
Instruction *si = i->getSrc(0)->getInsn();
- if (!si || si->op != OP_SHL)
+ if (!si)
break;
ImmediateValue imm1;
- if (si->src(1).getImmediate(imm1)) {
+ switch (si->op) {
+ case OP_SHL:
+ if (si->src(1).getImmediate(imm1)) {
+ bld.setPosition(i, false);
+ i->setSrc(0, si->getSrc(0));
+ i->setSrc(1, bld.loadImm(NULL, imm0.reg.data.u32 + imm1.reg.data.u32));
+ }
+ break;
+ case OP_MUL:
+ int muls;
+ if (isFloatType(si->dType))
+ return;
+ if (si->src(1).getImmediate(imm1))
+ muls = 1;
+ else if (si->src(0).getImmediate(imm1))
+ muls = 0;
+ else
+ return;
+
bld.setPosition(i, false);
- i->setSrc(0, si->getSrc(0));
- i->setSrc(1, bld.loadImm(NULL, imm0.reg.data.u32 + imm1.reg.data.u32));
+ i->op = OP_MUL;
+ i->setSrc(0, si->getSrc(!muls));
+ i->setSrc(1, bld.loadImm(NULL, imm1.reg.data.u32 << imm0.reg.data.u32));
+ break;
+ case OP_SUB:
+ case OP_ADD:
+ int adds;
+ if (isFloatType(si->dType))
+ return;
+ if (si->op != OP_SUB && si->src(0).getImmediate(imm1))
+ adds = 0;
+ else if (si->src(1).getImmediate(imm1))
+ adds = 1;
+ else
+ return;
+ // SHL(ADD(x, y), z) = ADD(SHL(x, z), SHL(y, z))
+
+ // This is more operations, but if one of x, y is an immediate, then
+ // we can get a situation where (a) we can use ISCADD, or (b)
+ // propagate the add bit into an indirect load.
+ bld.setPosition(i, false);
+ i->op = si->op;
+ i->setSrc(adds, bld.loadImm(NULL, imm1.reg.data.u32 << imm0.reg.data.u32));
+ i->setSrc(!adds, bld.mkOp2v(OP_SHL, i->dType,
+ bld.getSSA(i->def(0).getSize(), i->def(0).getFile()),
+ si->getSrc(!adds),
+ bld.mkImm(imm0.reg.data.u32)));
+ break;
+ default:
+ return;
}
}
break;
@@ -1456,12 +1593,11 @@ AlgebraicOpt::tryADDToMADOrSAD(Instruction *add, operation toOp)
else
return false;
- if ((src0->getUniqueInsn() && src0->getUniqueInsn()->bb != add->bb) ||
- (src1->getUniqueInsn() && src1->getUniqueInsn()->bb != add->bb))
- return false;
-
src = add->getSrc(s);
+ if (src->getUniqueInsn() && src->getUniqueInsn()->bb != add->bb)
+ return false;
+
if (src->getInsn()->postFactor)
return false;
if (toOp == OP_SAD) {
@@ -1472,6 +1608,10 @@ AlgebraicOpt::tryADDToMADOrSAD(Instruction *add, operation toOp)
return false;
}
+ if (typeSizeof(add->dType) != typeSizeof(src->getInsn()->dType) ||
+ isFloatType(add->dType) != isFloatType(src->getInsn()->dType))
+ return false;
+
mod[0] = add->src(0).mod;
mod[1] = add->src(1).mod;
mod[2] = src->getUniqueInsn()->src(0).mod;
@@ -1482,6 +1622,8 @@ AlgebraicOpt::tryADDToMADOrSAD(Instruction *add, operation toOp)
add->op = toOp;
add->subOp = src->getInsn()->subOp; // potentially mul-high
+ add->dType = src->getInsn()->dType; // sign matters for imad hi
+ add->sType = src->getInsn()->sType;
add->setSrc(2, add->src(s ? 0 : 1));
@@ -2654,7 +2796,7 @@ NV50PostRaConstantFolding::visit(BasicBlock *bb)
break;
def = i->getSrc(1)->getInsn();
- if (def->op == OP_MOV && def->src(0).getFile() == FILE_IMMEDIATE) {
+ if (def && def->op == OP_MOV && def->src(0).getFile() == FILE_IMMEDIATE) {
vtmp = i->getSrc(1);
i->setSrc(1, def->getSrc(0));
@@ -2956,6 +3098,16 @@ DeadCodeElim::visit(BasicBlock *bb)
return true;
}
+// Each load can go into up to 4 destinations, any of which might potentially
+// be dead (i.e. a hole). These can always be split into 2 loads, independent
+// of where the holes are. We find the first contiguous region, put it into
+// the first load, and then put the second contiguous region into the second
+// load. There can be at most 2 contiguous regions.
+//
+// Note that there are some restrictions, for example it's not possible to do
+// a 64-bit load that's not 64-bit aligned, so such a load has to be split
+// up. Also hardware doesn't support 96-bit loads, so those also have to be
+// split into a 64-bit and 32-bit load.
void
DeadCodeElim::checkSplitLoad(Instruction *ld1)
{
@@ -2976,6 +3128,8 @@ DeadCodeElim::checkSplitLoad(Instruction *ld1)
addr1 = ld1->getSrc(0)->reg.data.offset;
n1 = n2 = 0;
size1 = size2 = 0;
+
+ // Compute address/width for first load
for (d = 0; ld1->defExists(d); ++d) {
if (mask & (1 << d)) {
if (size1 && (addr1 & 0x7))
@@ -2989,16 +3143,34 @@ DeadCodeElim::checkSplitLoad(Instruction *ld1)
break;
}
}
+
+ // Scale back the size of the first load until it can be loaded. This
+ // typically happens for TYPE_B96 loads.
+ while (n1 &&
+ !prog->getTarget()->isAccessSupported(ld1->getSrc(0)->reg.file,
+ typeOfSize(size1))) {
+ size1 -= def1[--n1]->reg.size;
+ d--;
+ }
+
+ // Compute address/width for second load
for (addr2 = addr1 + size1; ld1->defExists(d); ++d) {
if (mask & (1 << d)) {
+ assert(!size2 || !(addr2 & 0x7));
def2[n2] = ld1->getDef(d);
size2 += def2[n2++]->reg.size;
- } else {
+ } else if (!n2) {
assert(!n2);
addr2 += ld1->getDef(d)->reg.size;
+ } else {
+ break;
}
}
+ // Make sure that we've processed all the values
+ for (; ld1->defExists(d); ++d)
+ assert(!(mask & (1 << d)));
+
updateLdStOffset(ld1, addr1, func);
ld1->setType(typeOfSize(size1));
for (d = 0; d < 4; ++d)
@@ -3039,6 +3211,7 @@ Program::optimizeSSA(int level)
RUN_PASS(2, ModifierFolding, run); // before load propagation -> less checks
RUN_PASS(1, ConstantFolding, foldAll);
RUN_PASS(1, LoadPropagation, run);
+ RUN_PASS(1, IndirectPropagation, run);
RUN_PASS(2, MemoryOpt, run);
RUN_PASS(2, LocalCSE, run);
RUN_PASS(0, DeadCodeElim, buryAll);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
index 41d2cc9167c..b32bc13f755 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
@@ -23,6 +23,7 @@
#include "codegen/nv50_ir.h"
#include "codegen/nv50_ir_target.h"
+#include
#include
#include
#if __cplusplus >= 201103L
@@ -102,6 +103,8 @@ public:
void print() const;
+ const bool restrictedGPR16Range;
+
private:
BitSet bits[LAST_REGISTER_FILE + 1];
@@ -109,8 +112,6 @@ private:
int last[LAST_REGISTER_FILE + 1];
int fill[LAST_REGISTER_FILE + 1];
-
- const bool restrictedGPR16Range;
};
void
@@ -839,6 +840,32 @@ GCRA::printNodeInfo() const
}
}
+static bool
+isShortRegOp(Instruction *insn)
+{
+ // Immediates are always in src1. Every other situation can be resolved by
+ // using a long encoding.
+ return insn->srcExists(1) && insn->src(1).getFile() == FILE_IMMEDIATE;
+}
+
+// Check if this LValue is ever used in an instruction that can't be encoded
+// with long registers (i.e. > r63)
+static bool
+isShortRegVal(LValue *lval)
+{
+ if (lval->defs.size() == 0)
+ return false;
+ for (Value::DefCIterator def = lval->defs.begin();
+ def != lval->defs.end(); ++def)
+ if (isShortRegOp((*def)->getInsn()))
+ return true;
+ for (Value::UseCIterator use = lval->uses.begin();
+ use != lval->uses.end(); ++use)
+ if (isShortRegOp((*use)->getInsn()))
+ return true;
+ return false;
+}
+
void
GCRA::RIG_Node::init(const RegisterSet& regs, LValue *lval)
{
@@ -854,7 +881,12 @@ GCRA::RIG_Node::init(const RegisterSet& regs, LValue *lval)
weight = std::numeric_limits::infinity();
degree = 0;
- degreeLimit = regs.getFileSize(f, lval->reg.size);
+ int size = regs.getFileSize(f, lval->reg.size);
+ // On nv50, we lose a bit of gpr encoding when there's an embedded
+ // immediate.
+ if (regs.restrictedGPR16Range && f == FILE_GPR && isShortRegVal(lval))
+ size /= 2;
+ degreeLimit = size;
degreeLimit -= relDegree[1][colors] - 1;
livei.insert(lval->livei);
@@ -1433,6 +1465,20 @@ GCRA::allocateRegisters(ArrayList& insns)
if (lval) {
nodes[i].init(regs, lval);
RIG.insert(&nodes[i]);
+
+ if (lval->inFile(FILE_GPR) && lval->defs.size() > 0 &&
+ prog->getTarget()->getChipset() < 0xc0) {
+ Instruction *insn = lval->getInsn();
+ if (insn->op == OP_MAD || insn->op == OP_SAD)
+ // Short encoding only possible if they're all GPRs, no need to
+ // affect them otherwise.
+ if (insn->flagsDef < 0 &&
+ isFloatType(insn->dType) &&
+ insn->src(0).getFile() == FILE_GPR &&
+ insn->src(1).getFile() == FILE_GPR &&
+ insn->src(2).getFile() == FILE_GPR)
+ nodes[i].addRegPreference(getNode(insn->getSrc(2)->asLValue()));
+ }
}
}
@@ -1599,6 +1645,8 @@ SpillCodeInserter::spill(Instruction *defi, Value *slot, LValue *lval)
st = new_Instruction(func, OP_CVT, ty);
st->setDef(0, slot);
st->setSrc(0, lval);
+ if (lval->reg.file == FILE_FLAGS)
+ st->flagsSrc = 0;
}
defi->bb->insertAfter(defi, st);
}
@@ -1640,11 +1688,20 @@ SpillCodeInserter::unspill(Instruction *usei, LValue *lval, Value *slot)
}
ld->setDef(0, lval);
ld->setSrc(0, slot);
+ if (lval->reg.file == FILE_FLAGS)
+ ld->flagsDef = 0;
usei->bb->insertBefore(usei, ld);
return lval;
}
+static bool
+value_cmp(ValueRef *a, ValueRef *b) {
+ Instruction *ai = a->getInsn(), *bi = b->getInsn();
+ if (ai->bb != bi->bb)
+ return ai->bb->getId() < bi->bb->getId();
+ return ai->serial < bi->serial;
+}
// For each value that is to be spilled, go through all its definitions.
// A value can have multiple definitions if it has been coalesced before.
@@ -1678,18 +1735,25 @@ SpillCodeInserter::run(const std::list& lst)
LValue *dval = (*d)->get()->asLValue();
Instruction *defi = (*d)->getInsn();
+ // Sort all the uses by BB/instruction so that we don't unspill
+ // multiple times in a row, and also remove a source of
+ // non-determinism.
+ std::vector refs(dval->uses.begin(), dval->uses.end());
+ std::sort(refs.begin(), refs.end(), value_cmp);
+
// Unspill at each use *before* inserting spill instructions,
// we don't want to have the spill instructions in the use list here.
- while (!dval->uses.empty()) {
- ValueRef *u = *dval->uses.begin();
+ for (std::vector::const_iterator it = refs.begin();
+ it != refs.end(); ++it) {
+ ValueRef *u = *it;
Instruction *usei = u->getInsn();
assert(usei);
if (usei->isPseudo()) {
tmp = (slot->reg.file == FILE_MEMORY_LOCAL) ? NULL : slot;
last = NULL;
- } else
- if (!last || usei != last->next) { // TODO: sort uses
- tmp = unspill(usei, dval, slot);
+ } else {
+ if (!last || (usei != last->next && usei != last))
+ tmp = unspill(usei, dval, slot);
last = usei;
}
u->set(tmp);
@@ -2084,7 +2148,8 @@ RegAlloc::InsertConstraintsPass::texConstraintNVC0(TexInstruction *tex)
{
int n, s;
- textureMask(tex);
+ if (isTextureOp(tex->op))
+ textureMask(tex);
if (tex->op == OP_TXQ) {
s = tex->srcCount(0xff);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ssa.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ssa.cpp
index 2e432349f24..9ea1065b806 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ssa.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ssa.cpp
@@ -87,6 +87,7 @@ DominatorTree::DominatorTree(Graph *cfgraph) : cfg(cfgraph),
LABEL(i) = i;
SEMI(i) = ANCESTOR(i) = -1;
}
+ assert(i == count);
build();
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
index 4e33997e1c1..673f8811ff3 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
@@ -191,6 +191,8 @@ public:
virtual bool insnCanLoad(const Instruction *insn, int s,
const Instruction *ld) const = 0;
+ virtual bool insnCanLoadOffset(const Instruction *insn, int s,
+ int offset) const { return true; }
virtual bool isOpSupported(operation, DataType) const = 0;
virtual bool isAccessSupported(DataFile, DataType) const = 0;
virtual bool isModSupported(const Instruction *,
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp
index 202d7443588..92caeb22c12 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp
@@ -55,11 +55,6 @@ bool
TargetGM107::isOpSupported(operation op, DataType ty) const
{
switch (op) {
- case OP_MAD:
- case OP_FMA:
- if (ty != TYPE_F32)
- return false;
- break;
case OP_SAD:
case OP_POW:
case OP_SQRT:
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
index 94cf0f0e05e..101082e7491 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
@@ -268,6 +268,12 @@ TargetNV50::insnCanLoad(const Instruction *i, int s,
{
DataFile sf = ld->src(0).getFile();
+ // immediate 0 can be represented by GPR $r63/$r127
+ if (sf == FILE_IMMEDIATE && ld->getSrc(0)->reg.data.u64 == 0)
+ return (!i->isPseudo() &&
+ !i->asTex() &&
+ i->op != OP_EXPORT && i->op != OP_STORE);
+
if (sf == FILE_IMMEDIATE && (i->predSrc >= 0 || i->flagsDef >= 0))
return false;
if (s >= opInfo[i->op].srcNr)
@@ -378,6 +384,21 @@ TargetNV50::insnCanLoad(const Instruction *i, int s,
return true;
}
+bool
+TargetNV50::insnCanLoadOffset(const Instruction *i, int s, int offset) const
+{
+ if (!i->src(s).isIndirect(0))
+ return true;
+ offset += i->src(s).get()->reg.data.offset;
+ if (i->op == OP_LOAD || i->op == OP_STORE) {
+ // There are some restrictions in theory, but in practice they're never
+ // going to be hit. When we enable shared/global memory, this will
+ // become more important.
+ return true;
+ }
+ return offset >= 0 && offset <= (int32_t)(127 * i->src(s).get()->reg.size);
+}
+
bool
TargetNV50::isAccessSupported(DataFile file, DataType ty) const
{
@@ -454,7 +475,7 @@ TargetNV50::isModSupported(const Instruction *insn, int s, Modifier mod) const
return false;
}
}
- if (s >= 3)
+ if (s >= opInfo[insn->op].srcNr || s >= 3)
return false;
return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod;
}
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.h
index 0cbf180d048..00243d7958e 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.h
@@ -46,6 +46,8 @@ public:
virtual bool insnCanLoad(const Instruction *insn, int s,
const Instruction *ld) const;
+ virtual bool insnCanLoadOffset(const Instruction *insn, int s,
+ int offset) const;
virtual bool isOpSupported(operation, DataType) const;
virtual bool isAccessSupported(DataFile, DataType) const;
virtual bool isModSupported(const Instruction *, int s, Modifier) const;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
index 8f59d86a72f..19637ce33f5 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
@@ -395,8 +395,6 @@ TargetNVC0::isAccessSupported(DataFile file, DataType ty) const
bool
TargetNVC0::isOpSupported(operation op, DataType ty) const
{
- if ((op == OP_MAD || op == OP_FMA) && (ty != TYPE_F32))
- return false;
if (op == OP_SAD && ty != TYPE_S32 && ty != TYPE_U32)
return false;
if (op == OP_POW || op == OP_SQRT || op == OP_DIV || op == OP_MOD)
@@ -439,7 +437,7 @@ TargetNVC0::isModSupported(const Instruction *insn, int s, Modifier mod) const
return false;
}
}
- if (s >= 3)
+ if (s >= opInfo[insn->op].srcNr || s >= 3)
return false;
return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_compiler.c b/src/gallium/drivers/nouveau/nouveau_compiler.c
index 495450b317a..670b0c8b135 100644
--- a/src/gallium/drivers/nouveau/nouveau_compiler.c
+++ b/src/gallium/drivers/nouveau/nouveau_compiler.c
@@ -168,7 +168,7 @@ main(int argc, char *argv[])
else
f = fopen(filename, "r");
- if (f == NULL) {
+ if (!f) {
_debug_printf("Error opening file '%s': %s\n", filename, strerror(errno));
return 1;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.c b/src/gallium/drivers/nouveau/nouveau_vp3_video.c
index 4652e56c49a..d76d93241f4 100644
--- a/src/gallium/drivers/nouveau/nouveau_vp3_video.c
+++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.c
@@ -83,10 +83,10 @@ nouveau_vp3_video_buffer_create(struct pipe_context *pipe,
struct pipe_sampler_view sv_templ;
struct pipe_surface surf_templ;
- assert(templat->interlaced);
if (getenv("XVMC_VL") || templat->buffer_format != PIPE_FORMAT_NV12)
return vl_video_buffer_create(pipe, templat);
+ assert(templat->interlaced);
assert(templat->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
buffer = CALLOC_STRUCT(nouveau_vp3_video_buffer);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
index 2452071762b..9ecbcd1087a 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
@@ -155,7 +155,7 @@ nv30_transfer_rect_blit(XFER_ARGS)
u32 format, stride;
if (nouveau_pushbuf_space(push, 512, 8, 0) ||
- nouveau_pushbuf_refn (push, refs, sizeof(refs) / sizeof(refs[0])))
+ nouveau_pushbuf_refn (push, refs, ARRAY_SIZE(refs)))
return;
/* various switches depending on cpp of the transfer */
diff --git a/src/gallium/drivers/nouveau/nv30/nvfx_fragprog.c b/src/gallium/drivers/nouveau/nv30/nvfx_fragprog.c
index e68d23e5587..b9cfb313fb5 100644
--- a/src/gallium/drivers/nouveau/nv30/nvfx_fragprog.c
+++ b/src/gallium/drivers/nouveau/nv30/nvfx_fragprog.c
@@ -1186,7 +1186,7 @@ _nvfx_fragprog_translate(uint16_t oclass, struct nv30_fragprog *fp)
out:
tgsi_parse_free(&parse);
- if(fpc)
+ if (fpc)
{
FREE(fpc->r_temp);
FREE(fpc->r_imm);
diff --git a/src/gallium/drivers/nouveau/nv30/nvfx_vertprog.c b/src/gallium/drivers/nouveau/nv30/nvfx_vertprog.c
index dbbb8baad79..7ce51a118c8 100644
--- a/src/gallium/drivers/nouveau/nv30/nvfx_vertprog.c
+++ b/src/gallium/drivers/nouveau/nv30/nvfx_vertprog.c
@@ -1113,7 +1113,7 @@ _nvfx_vertprog_translate(uint16_t oclass, struct nv30_vertprog *vp)
out:
tgsi_parse_free(&parse);
- if(vpc) {
+ if (vpc) {
util_dynarray_fini(&vpc->label_relocs);
util_dynarray_fini(&vpc->loop_stack);
FREE(vpc->r_temp);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_resource.c b/src/gallium/drivers/nouveau/nv50/nv50_resource.c
index 325c19fb80c..5d415ae77eb 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_resource.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_resource.c
@@ -68,8 +68,6 @@ nv50_surface_create(struct pipe_context *pipe,
struct pipe_resource *pres,
const struct pipe_surface *templ)
{
- /* surfaces are assumed to be miptrees all over the place. */
- assert(pres->target != PIPE_BUFFER);
if (unlikely(pres->target == PIPE_BUFFER))
return nv50_surface_from_buffer(pipe, pres, templ);
return nv50_miptree_surface_new(pipe, pres, templ);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c b/src/gallium/drivers/nouveau/nv50/nv50_state.c
index b4ea08d4d13..de655971b66 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_state.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c
@@ -189,7 +189,7 @@ nv50_blend_state_create(struct pipe_context *pipe,
SB_DATA (so, nv50_colormask(cso->rt[0].colormask));
}
- assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
+ assert(so->size <= ARRAY_SIZE(so->state));
return so;
}
@@ -326,7 +326,7 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
SB_BEGIN_3D(so, PIXEL_CENTER_INTEGER, 1);
SB_DATA (so, !cso->half_pixel_center);
- assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
+ assert(so->size <= ARRAY_SIZE(so->state));
return (void *)so;
}
@@ -415,7 +415,7 @@ nv50_zsa_state_create(struct pipe_context *pipe,
SB_DATA (so, 0);
}
- assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
+ assert(so->size <= ARRAY_SIZE(so->state));
return (void *)so;
}
@@ -994,6 +994,9 @@ nv50_set_vertex_buffers(struct pipe_context *pipe,
struct nv50_context *nv50 = nv50_context(pipe);
unsigned i;
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
+ nv50->dirty |= NV50_NEW_ARRAYS;
+
util_set_vertex_buffers_count(nv50->vtxbuf, &nv50->num_vtxbufs, vb,
start_slot, count);
@@ -1017,10 +1020,6 @@ nv50_set_vertex_buffers(struct pipe_context *pipe,
nv50->vbo_constant &= ~(1 << dst_index);
}
}
-
- nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
-
- nv50->dirty |= NV50_NEW_ARRAYS;
}
static void
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
index 02a759c23ad..d14d603adc9 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
@@ -60,6 +60,8 @@ nv50_validate_fb(struct nv50_context *nv50)
PUSH_DATA (push, mt->base.address + sf->offset);
PUSH_DATA (push, nv50_format_table[sf->base.format].rt);
if (likely(nouveau_bo_memtype(bo))) {
+ assert(sf->base.texture->target != PIPE_BUFFER);
+
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
PUSH_DATA (push, mt->layer_stride >> 2);
BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
@@ -506,7 +508,6 @@ static struct state_validate {
{ nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS },
{ nv50_validate_min_samples, NV50_NEW_MIN_SAMPLES },
};
-#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
bool
nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
@@ -521,7 +522,7 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
state_mask = nv50->dirty & mask;
if (state_mask) {
- for (i = 0; i < validate_list_len; ++i) {
+ for (i = 0; i < ARRAY_SIZE(validate_list); ++i) {
struct state_validate *validate = &validate_list[i];
if (state_mask & validate->states)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index 8ba19d2cc90..86be1b4c4ed 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -286,6 +286,8 @@ nv50_clear_render_target(struct pipe_context *pipe,
struct nouveau_bo *bo = mt->base.bo;
unsigned z;
+ assert(dst->texture->target != PIPE_BUFFER);
+
BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
PUSH_DATAf(push, color->f[0]);
PUSH_DATAf(push, color->f[1]);
@@ -371,6 +373,7 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
uint32_t mode = 0;
unsigned z;
+ assert(dst->texture->target != PIPE_BUFFER);
assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */
if (clear_flags & PIPE_CLEAR_DEPTH) {
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c b/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c
index 1a520d2df0c..38eca1771c5 100644
--- a/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c
@@ -200,7 +200,7 @@ nv84_decoder_bsp(struct nv84_decoder *dec,
memcpy(dec->bitstream->map + 0x600, more_params, sizeof(more_params));
PUSH_SPACE(push, 5 + 21 + 3 + 2 + 4 + 2);
- nouveau_pushbuf_refn(push, bo_refs, sizeof(bo_refs)/sizeof(bo_refs[0]));
+ nouveau_pushbuf_refn(push, bo_refs, ARRAY_SIZE(bo_refs));
/* Wait for the fence = 1 */
BEGIN_NV04(push, SUBC_BSP(0x10), 4);
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video_vp.c b/src/gallium/drivers/nouveau/nv50/nv84_video_vp.c
index 8b121477a37..811e0c60f83 100644
--- a/src/gallium/drivers/nouveau/nv50/nv84_video_vp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv84_video_vp.c
@@ -81,7 +81,7 @@ nv84_decoder_vp_h264(struct nv84_decoder *dec,
{ dec->vp_params, NOUVEAU_BO_RDWR | NOUVEAU_BO_GART },
{ dec->fence, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
};
- int num_refs = sizeof(bo_refs)/sizeof(*bo_refs);
+ int num_refs = ARRAY_SIZE(bo_refs);
bool is_ref = desc->is_reference;
STATIC_ASSERT(sizeof(struct h264_iparm1) == 0x218);
@@ -141,7 +141,7 @@ nv84_decoder_vp_h264(struct nv84_decoder *dec,
{ bo1, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
{ bo2, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
};
- nouveau_pushbuf_refn(push, bo_refs, sizeof(bo_refs)/sizeof(bo_refs[0]));
+ nouveau_pushbuf_refn(push, bo_refs, ARRAY_SIZE(bo_refs));
}
memcpy(dec->vp_params->map, ¶m1, sizeof(param1));
@@ -490,16 +490,16 @@ nv84_decoder_vp_mpeg12(struct nv84_decoder *dec,
{ NULL, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
{ dec->mpeg12_bo, NOUVEAU_BO_RDWR | NOUVEAU_BO_GART },
};
- int i, num_refs = sizeof(bo_refs) / sizeof(*bo_refs);
+ int i, num_refs = ARRAY_SIZE(bo_refs);
struct mpeg12_header header = {0};
struct nv50_miptree *y = nv50_miptree(dest->resources[0]);
struct nv50_miptree *uv = nv50_miptree(dest->resources[1]);
STATIC_ASSERT(sizeof(struct mpeg12_header) == 0x100);
- if (ref1 == NULL)
+ if (!ref1)
ref1 = dest;
- if (ref2 == NULL)
+ if (!ref2)
ref2 = dest;
bo_refs[1].bo = ref1->interlaced;
bo_refs[2].bo = ref2->interlaced;
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
index 6058c22138b..dbde1bfcebe 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
@@ -56,7 +56,7 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
#endif
{ dec->bitplane_bo, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
};
- int num_refs = sizeof(bo_refs)/sizeof(*bo_refs);
+ int num_refs = ARRAY_SIZE(bo_refs);
if (!dec->bitplane_bo)
num_refs--;
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c
index 6b0b7148dcb..48f16211afc 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c
@@ -40,7 +40,7 @@ nv98_decoder_setup_ppp(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video
{ dec->fence_bo, NOUVEAU_BO_WR | NOUVEAU_BO_GART },
#endif
};
- unsigned num_refs = sizeof(bo_refs)/sizeof(*bo_refs);
+ unsigned num_refs = ARRAY_SIZE(bo_refs);
for (i = 0; i < 2; ++i) {
struct nv50_miptree *mt = (struct nv50_miptree *)target->resources[i];
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
index d13480c21d5..37d7d443289 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
@@ -86,7 +86,7 @@ nv98_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
#endif
{ dec->fw_bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM },
};
- int num_refs = sizeof(bo_refs)/sizeof(*bo_refs) - !dec->fw_bo;
+ int num_refs = ARRAY_SIZE(bo_refs) - !dec->fw_bo;
#if NOUVEAU_VP3_DEBUG_FENCE
fence_extra = 4;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
index 43d7c7b1123..67a25acf778 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
@@ -502,7 +502,7 @@ nvc0_program_dump(struct nvc0_program *prog)
unsigned pos;
if (prog->type != PIPE_SHADER_COMPUTE) {
- for (pos = 0; pos < sizeof(prog->hdr) / sizeof(prog->hdr[0]); ++pos)
+ for (pos = 0; pos < ARRAY_SIZE(prog->hdr); ++pos)
debug_printf("HDR[%02"PRIxPTR"] = 0x%08x\n",
pos * sizeof(prog->hdr[0]), prog->hdr[pos]);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
index d992b10a23c..3845d616c3d 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
@@ -187,7 +187,7 @@ nvc0_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
if (screen->base.device->drm_version >= 0x01000101) {
if (screen->compute) {
if (screen->base.class_3d == NVE4_3D_CLASS) {
- count++;
+ count += 2;
} else
if (screen->base.class_3d < NVE4_3D_CLASS) {
count += 2;
@@ -222,6 +222,12 @@ nvc0_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
} else
if (id == NVC0_HW_METRIC_QUERY_GROUP) {
if (screen->compute) {
+ if (screen->base.class_3d == NVE4_3D_CLASS) {
+ info->name = "Performance metrics";
+ info->max_active_queries = 1;
+ info->num_queries = NVE4_HW_METRIC_QUERY_COUNT;
+ return 1;
+ } else
if (screen->base.class_3d < NVE4_3D_CLASS) {
info->name = "Performance metrics";
info->max_active_queries = 1;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_metric.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_metric.c
index fb2806a805e..12fb609b62a 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_metric.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_metric.c
@@ -157,6 +157,109 @@ static const struct nvc0_hw_metric_query_cfg *sm21_hw_metric_queries[] =
#undef _SM
#undef _M
+/* === PERFORMANCE MONITORING METRICS for NVE4+ === */
+static const char *nve4_hw_metric_names[] =
+{
+ "metric-achieved_occupancy",
+ "metric-branch_efficiency",
+ "metric-inst_issued",
+ "metric-inst_per_wrap",
+ "metric-inst_replay_overhead",
+ "metric-issued_ipc",
+ "metric-issue_slots",
+ "metric-issue_slot_utilization",
+ "metric-ipc",
+ "metric-shared_replay_overhead",
+};
+
+#define _SM(n) NVE4_HW_SM_QUERY(NVE4_HW_SM_QUERY_ ##n)
+#define _M(n, c) [NVE4_HW_METRIC_QUERY_##n] = c
+
+/* ==== Compute capability 3.0 (GK104/GK106/GK107) ==== */
+static const struct nvc0_hw_metric_query_cfg
+sm30_achieved_occupancy =
+{
+ .queries[0] = _SM(ACTIVE_WARPS),
+ .queries[1] = _SM(ACTIVE_CYCLES),
+ .num_queries = 2,
+};
+
+static const struct nvc0_hw_metric_query_cfg
+sm30_branch_efficiency =
+{
+ .queries[0] = _SM(BRANCH),
+ .queries[1] = _SM(DIVERGENT_BRANCH),
+ .num_queries = 2,
+};
+
+static const struct nvc0_hw_metric_query_cfg
+sm30_inst_issued =
+{
+ .queries[0] = _SM(INST_ISSUED1),
+ .queries[1] = _SM(INST_ISSUED2),
+ .num_queries = 2,
+};
+
+static const struct nvc0_hw_metric_query_cfg
+sm30_inst_per_wrap =
+{
+ .queries[0] = _SM(INST_EXECUTED),
+ .queries[1] = _SM(WARPS_LAUNCHED),
+ .num_queries = 2,
+};
+
+static const struct nvc0_hw_metric_query_cfg
+sm30_inst_replay_overhead =
+{
+ .queries[0] = _SM(INST_ISSUED1),
+ .queries[1] = _SM(INST_ISSUED2),
+ .queries[2] = _SM(INST_EXECUTED),
+ .num_queries = 3,
+};
+
+static const struct nvc0_hw_metric_query_cfg
+sm30_issued_ipc =
+{
+ .queries[0] = _SM(INST_ISSUED1),
+ .queries[1] = _SM(INST_ISSUED2),
+ .queries[2] = _SM(ACTIVE_CYCLES),
+ .num_queries = 3,
+};
+
+static const struct nvc0_hw_metric_query_cfg
+sm30_ipc =
+{
+ .queries[0] = _SM(INST_EXECUTED),
+ .queries[1] = _SM(ACTIVE_CYCLES),
+ .num_queries = 2,
+};
+
+static const struct nvc0_hw_metric_query_cfg
+sm30_shared_replay_overhead =
+{
+ .queries[0] = _SM(SHARED_LD_REPLAY),
+ .queries[1] = _SM(SHARED_ST_REPLAY),
+ .queries[2] = _SM(INST_EXECUTED),
+ .num_queries = 3,
+};
+
+static const struct nvc0_hw_metric_query_cfg *sm30_hw_metric_queries[] =
+{
+ _M(ACHIEVED_OCCUPANCY, &sm30_achieved_occupancy),
+ _M(BRANCH_EFFICIENCY, &sm30_branch_efficiency),
+ _M(INST_ISSUED, &sm30_inst_issued),
+ _M(INST_PER_WRAP, &sm30_inst_per_wrap),
+ _M(INST_REPLAY_OVERHEAD, &sm30_inst_replay_overhead),
+ _M(ISSUED_IPC, &sm30_issued_ipc),
+ _M(ISSUE_SLOTS, &sm30_inst_issued),
+ _M(ISSUE_SLOT_UTILIZATION, &sm30_issued_ipc),
+ _M(IPC, &sm30_ipc),
+ _M(SHARED_REPLAY_OVERHEAD, &sm30_shared_replay_overhead),
+};
+
+#undef _SM
+#undef _M
+
static inline const struct nvc0_hw_metric_query_cfg **
nvc0_hw_metric_get_queries(struct nvc0_screen *screen)
{
@@ -175,6 +278,9 @@ nvc0_hw_metric_query_get_cfg(struct nvc0_context *nvc0,
struct nvc0_screen *screen = nvc0->screen;
struct nvc0_query *q = &hq->base;
+ if (screen->base.class_3d >= NVE4_3D_CLASS)
+ return sm30_hw_metric_queries[q->type - NVE4_HW_METRIC_QUERY(0)];
+
queries = nvc0_hw_metric_get_queries(screen);
return queries[q->type - NVC0_HW_METRIC_QUERY(0)];
}
@@ -309,6 +415,52 @@ sm21_hw_metric_calc_result(struct nvc0_hw_query *hq, uint64_t res64[8])
return 0;
}
+static uint64_t
+sm30_hw_metric_calc_result(struct nvc0_hw_query *hq, uint64_t res64[8])
+{
+ switch (hq->base.type - NVE4_HW_METRIC_QUERY(0)) {
+ case NVE4_HW_METRIC_QUERY_ACHIEVED_OCCUPANCY:
+ return sm20_hw_metric_calc_result(hq, res64);
+ case NVE4_HW_METRIC_QUERY_BRANCH_EFFICIENCY:
+ return sm20_hw_metric_calc_result(hq, res64);
+ case NVE4_HW_METRIC_QUERY_INST_ISSUED:
+ /* inst_issued1 + inst_issued2 * 2 */
+ return res64[0] + res64[1] * 2;
+ case NVE4_HW_METRIC_QUERY_INST_PER_WRAP:
+ return sm20_hw_metric_calc_result(hq, res64);
+ case NVE4_HW_METRIC_QUERY_INST_REPLAY_OVERHEAD:
+ /* (metric-inst_issued - inst_executed) / inst_executed */
+ if (res64[2])
+ return (((res64[0] + res64[1] * 2) - res64[2]) / (double)res64[2]);
+ break;
+ case NVE4_HW_METRIC_QUERY_ISSUED_IPC:
+ /* metric-inst_issued / active_cycles */
+ if (res64[2])
+ return (res64[0] + res64[1] * 2) / (double)res64[2];
+ break;
+ case NVE4_HW_METRIC_QUERY_ISSUE_SLOTS:
+ /* inst_issued1 + inst_issued2 */
+ return res64[0] + res64[1];
+ case NVE4_HW_METRIC_QUERY_ISSUE_SLOT_UTILIZATION:
+ /* ((metric-issue_slots / 2) / active_cycles) * 100 */
+ if (res64[2])
+ return (((res64[0] + res64[1]) / 2) / (double)res64[2]) * 100;
+ break;
+ case NVE4_HW_METRIC_QUERY_IPC:
+ return sm20_hw_metric_calc_result(hq, res64);
+ case NVE4_HW_METRIC_QUERY_SHARED_REPLAY_OVERHEAD:
+ /* (shared_load_replay + shared_store_replay) / inst_executed */
+ if (res64[2])
+ return (res64[0] + res64[1]) / (double)res64[2];
+ break;
+ default:
+ debug_printf("invalid metric type: %d\n",
+ hq->base.type - NVE4_HW_METRIC_QUERY(0));
+ break;
+ }
+ return 0;
+}
+
static boolean
nvc0_hw_metric_get_query_result(struct nvc0_context *nvc0,
struct nvc0_hw_query *hq, boolean wait,
@@ -331,10 +483,14 @@ nvc0_hw_metric_get_query_result(struct nvc0_context *nvc0,
res64[i] = *(uint64_t *)&results[i];
}
- if (dev->chipset == 0xc0 || dev->chipset == 0xc8)
- value = sm20_hw_metric_calc_result(hq, res64);
- else
- value = sm21_hw_metric_calc_result(hq, res64);
+ if (screen->base.class_3d >= NVE4_3D_CLASS) {
+ value = sm30_hw_metric_calc_result(hq, res64);
+ } else {
+ if (dev->chipset == 0xc0 || dev->chipset == 0xc8)
+ value = sm20_hw_metric_calc_result(hq, res64);
+ else
+ value = sm21_hw_metric_calc_result(hq, res64);
+ }
*(uint64_t *)result = value;
return ret;
@@ -355,7 +511,8 @@ nvc0_hw_metric_create_query(struct nvc0_context *nvc0, unsigned type)
struct nvc0_hw_query *hq;
unsigned i;
- if (type < NVC0_HW_METRIC_QUERY(0) || type > NVC0_HW_METRIC_QUERY_LAST)
+ if ((type < NVE4_HW_METRIC_QUERY(0) || type > NVE4_HW_METRIC_QUERY_LAST) &&
+ (type < NVC0_HW_METRIC_QUERY(0) || type > NVC0_HW_METRIC_QUERY_LAST))
return NULL;
hmq = CALLOC_STRUCT(nvc0_hw_metric_query);
@@ -406,6 +563,9 @@ nvc0_hw_metric_get_driver_query_info(struct nvc0_screen *screen, unsigned id,
if (screen->base.device->drm_version >= 0x01000101) {
if (screen->compute) {
+ if (screen->base.class_3d == NVE4_3D_CLASS) {
+ count += NVE4_HW_METRIC_QUERY_COUNT;
+ } else
if (class_3d < NVE4_3D_CLASS) {
const struct nvc0_hw_metric_query_cfg **queries =
nvc0_hw_metric_get_queries(screen);
@@ -424,6 +584,12 @@ nvc0_hw_metric_get_driver_query_info(struct nvc0_screen *screen, unsigned id,
if (id < count) {
if (screen->compute) {
+ if (screen->base.class_3d == NVE4_3D_CLASS) {
+ info->name = nve4_hw_metric_names[id];
+ info->query_type = NVE4_HW_METRIC_QUERY(id);
+ info->group_id = NVC0_HW_METRIC_QUERY_GROUP;
+ return 1;
+ } else
if (class_3d < NVE4_3D_CLASS) {
const struct nvc0_hw_metric_query_cfg **queries =
nvc0_hw_metric_get_queries(screen);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_metric.h b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_metric.h
index 95675fd19b7..06cb355db40 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_metric.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_metric.h
@@ -18,6 +18,23 @@ nvc0_hw_metric_query(struct nvc0_hw_query *hq)
/*
* Driver metrics queries:
*/
+#define NVE4_HW_METRIC_QUERY(i) (PIPE_QUERY_DRIVER_SPECIFIC + 3072 + (i))
+#define NVE4_HW_METRIC_QUERY_LAST NVE4_HW_METRIC_QUERY(NVE4_HW_METRIC_QUERY_COUNT - 1)
+enum nve4_hw_metric_queries
+{
+ NVE4_HW_METRIC_QUERY_ACHIEVED_OCCUPANCY = 0,
+ NVE4_HW_METRIC_QUERY_BRANCH_EFFICIENCY,
+ NVE4_HW_METRIC_QUERY_INST_ISSUED,
+ NVE4_HW_METRIC_QUERY_INST_PER_WRAP,
+ NVE4_HW_METRIC_QUERY_INST_REPLAY_OVERHEAD,
+ NVE4_HW_METRIC_QUERY_ISSUED_IPC,
+ NVE4_HW_METRIC_QUERY_ISSUE_SLOTS,
+ NVE4_HW_METRIC_QUERY_ISSUE_SLOT_UTILIZATION,
+ NVE4_HW_METRIC_QUERY_IPC,
+ NVE4_HW_METRIC_QUERY_SHARED_REPLAY_OVERHEAD,
+ NVE4_HW_METRIC_QUERY_COUNT
+};
+
#define NVC0_HW_METRIC_QUERY(i) (PIPE_QUERY_DRIVER_SPECIFIC + 3072 + (i))
#define NVC0_HW_METRIC_QUERY_LAST NVC0_HW_METRIC_QUERY(NVC0_HW_METRIC_QUERY_COUNT - 1)
enum nvc0_hw_metric_queries
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
index 7962143d45a..7d1e75fd9d1 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
@@ -38,6 +38,7 @@ static const char *nve4_hw_sm_query_names[] =
/* MP counters */
"active_cycles",
"active_warps",
+ "atom_cas_count",
"atom_count",
"branch",
"divergent_branch",
@@ -48,11 +49,12 @@ static const char *nve4_hw_sm_query_names[] =
"gred_count",
"gst_request",
"inst_executed",
- "inst_issued",
"inst_issued1",
"inst_issued2",
"l1_global_load_hit",
"l1_global_load_miss",
+ "__l1_global_load_transactions",
+ "__l1_global_store_transactions",
"l1_local_load_hit",
"l1_local_load_miss",
"l1_local_store_hit",
@@ -79,13 +81,6 @@ static const char *nve4_hw_sm_query_names[] =
"threads_launched",
"uncached_global_load_transaction",
"warps_launched",
- /* metrics, i.e. functions of the MP counters */
- "metric-ipc", /* inst_executed, clock */
- "metric-ipac", /* inst_executed, active_cycles */
- "metric-ipec", /* inst_executed, (bool)inst_executed */
- "metric-achieved_occupancy", /* active_warps, active_cycles */
- "metric-sm_efficiency", /* active_cycles, clock */
- "metric-inst_replay_overhead" /* inst_issued, inst_executed */
};
/* Code to read out MP counters: They are accessible via mmio, too, but let's
@@ -190,47 +185,25 @@ struct nvc0_hw_sm_counter_cfg
uint32_t src_sel; /* signal selection for up to 4 sources */
};
-#define NVC0_COUNTER_OPn_SUM 0
-#define NVC0_COUNTER_OPn_OR 1
-#define NVC0_COUNTER_OPn_AND 2
-#define NVC0_COUNTER_OP2_REL_SUM_MM 3 /* (sum(ctr0) - sum(ctr1)) / sum(ctr0) */
-#define NVC0_COUNTER_OP2_DIV_SUM_M0 4 /* sum(ctr0) / ctr1 of MP[0]) */
-#define NVC0_COUNTER_OP2_AVG_DIV_MM 5 /* avg(ctr0 / ctr1) */
-#define NVC0_COUNTER_OP2_AVG_DIV_M0 6 /* avg(ctr0) / ctr1 of MP[0]) */
-
struct nvc0_hw_sm_query_cfg
{
struct nvc0_hw_sm_counter_cfg ctr[8];
uint8_t num_counters;
- uint8_t op;
uint8_t norm[2]; /* normalization num,denom */
};
-#define _Q1A(n, f, m, g, s, nu, dn) [NVE4_HW_SM_QUERY_##n] = { { { f, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g, 0, s }, {}, {}, {} }, 1, NVC0_COUNTER_OPn_SUM, { nu, dn } }
-#define _Q1B(n, f, m, g, s, nu, dn) [NVE4_HW_SM_QUERY_##n] = { { { f, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g, 0, s }, {}, {}, {} }, 1, NVC0_COUNTER_OPn_SUM, { nu, dn } }
-#define _M2A(n, f0, m0, g0, s0, f1, m1, g1, s1, o, nu, dn) [NVE4_HW_SM_QUERY_METRIC_##n] = { { \
- { f0, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m0, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g0, 0, s0 }, \
- { f1, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m1, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g1, 0, s1 }, \
- {}, {}, }, 2, NVC0_COUNTER_OP2_##o, { nu, dn } }
-#define _M2B(n, f0, m0, g0, s0, f1, m1, g1, s1, o, nu, dn) [NVE4_HW_SM_QUERY_METRIC_##n] = { { \
- { f0, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m0, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g0, 0, s0 }, \
- { f1, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m1, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g1, 0, s1 }, \
- {}, {}, }, 2, NVC0_COUNTER_OP2_##o, { nu, dn } }
-#define _M2AB(n, f0, m0, g0, s0, f1, m1, g1, s1, o, nu, dn) [NVE4_HW_SM_QUERY_METRIC_##n] = { { \
- { f0, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m0, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g0, 0, s0 }, \
- { f1, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m1, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g1, 0, s1 }, \
- {}, {}, }, 2, NVC0_COUNTER_OP2_##o, { nu, dn } }
+#define _Q1A(n, f, m, g, s, nu, dn) [NVE4_HW_SM_QUERY_##n] = { { { f, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g, 0, s }, {}, {}, {} }, 1, { nu, dn } }
+#define _Q1B(n, f, m, g, s, nu, dn) [NVE4_HW_SM_QUERY_##n] = { { { f, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g, 0, s }, {}, {}, {} }, 1, { nu, dn } }
/* NOTES:
* active_warps: bit 0 alternates btw 0 and 1 for odd nr of warps
* inst_executed etc.: we only count a single warp scheduler
- * metric-ipXc: we simply multiply by 4 to account for the 4 warp schedulers;
- * this is inaccurate !
*/
static const struct nvc0_hw_sm_query_cfg nve4_hw_sm_queries[] =
{
_Q1B(ACTIVE_CYCLES, 0x0001, B6, WARP, 0x00000000, 1, 1),
_Q1B(ACTIVE_WARPS, 0x003f, B6, WARP, 0x31483104, 2, 1),
+ _Q1A(ATOM_CAS_COUNT, 0x0001, B6, BRANCH, 0x000000004, 1, 1),
_Q1A(ATOM_COUNT, 0x0001, B6, BRANCH, 0x00000000, 1, 1),
_Q1A(BRANCH, 0x0001, B6, BRANCH, 0x0000000c, 1, 1),
_Q1A(DIVERGENT_BRANCH, 0x0001, B6, BRANCH, 0x00000010, 1, 1),
@@ -241,11 +214,12 @@ static const struct nvc0_hw_sm_query_cfg nve4_hw_sm_queries[] =
_Q1A(GRED_COUNT, 0x0001, B6, BRANCH, 0x00000008, 1, 1),
_Q1A(GST_REQUEST, 0x0001, B6, LDST, 0x00000014, 1, 1),
_Q1A(INST_EXECUTED, 0x0003, B6, EXEC, 0x00000398, 1, 1),
- _Q1A(INST_ISSUED, 0x0003, B6, ISSUE, 0x00000104, 1, 1),
_Q1A(INST_ISSUED1, 0x0001, B6, ISSUE, 0x00000004, 1, 1),
_Q1A(INST_ISSUED2, 0x0001, B6, ISSUE, 0x00000008, 1, 1),
_Q1B(L1_GLD_HIT, 0x0001, B6, L1, 0x00000010, 1, 1),
_Q1B(L1_GLD_MISS, 0x0001, B6, L1, 0x00000014, 1, 1),
+ _Q1B(L1_GLD_TRANSACTIONS, 0x0001, B6, UNK0F, 0x00000000, 1, 1),
+ _Q1B(L1_GST_TRANSACTIONS, 0x0001, B6, UNK0F, 0x00000004, 1, 1),
_Q1B(L1_LOCAL_LD_HIT, 0x0001, B6, L1, 0x00000000, 1, 1),
_Q1B(L1_LOCAL_LD_MISS, 0x0001, B6, L1, 0x00000004, 1, 1),
_Q1B(L1_LOCAL_ST_HIT, 0x0001, B6, L1, 0x00000008, 1, 1),
@@ -272,18 +246,10 @@ static const struct nvc0_hw_sm_query_cfg nve4_hw_sm_queries[] =
_Q1A(THREADS_LAUNCHED, 0x003f, B6, LAUNCH, 0x398a4188, 1, 1),
_Q1B(UNCACHED_GLD_TRANSACTIONS, 0x0001, B6, MEM, 0x00000000, 1, 1),
_Q1A(WARPS_LAUNCHED, 0x0001, B6, LAUNCH, 0x00000004, 1, 1),
- _M2AB(IPC, 0x3, B6, EXEC, 0x398, 0xffff, LOGOP, WARP, 0x0, DIV_SUM_M0, 10, 1),
- _M2AB(IPAC, 0x3, B6, EXEC, 0x398, 0x1, B6, WARP, 0x0, AVG_DIV_MM, 10, 1),
- _M2A(IPEC, 0x3, B6, EXEC, 0x398, 0xe, LOGOP, EXEC, 0x398, AVG_DIV_MM, 10, 1),
- _M2A(INST_REPLAY_OHEAD, 0x3, B6, ISSUE, 0x104, 0x3, B6, EXEC, 0x398, REL_SUM_MM, 100, 1),
- _M2B(MP_OCCUPANCY, 0x3f, B6, WARP, 0x31483104, 0x01, B6, WARP, 0x0, AVG_DIV_MM, 200, 64),
- _M2B(MP_EFFICIENCY, 0x01, B6, WARP, 0x0, 0xffff, LOGOP, WARP, 0x0, AVG_DIV_M0, 100, 1),
};
#undef _Q1A
#undef _Q1B
-#undef _M2A
-#undef _M2B
/* === PERFORMANCE MONITORING COUNTERS for NVC0:NVE4 === */
/* NOTES:
@@ -387,7 +353,6 @@ sm20_active_cycles =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x11, 0x000000ff, 0x00000000),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -401,7 +366,6 @@ sm20_active_warps =
.ctr[4] = _C(0xaaaa, LOGOP, 0x24, 0x000000ff, 0x00000050),
.ctr[5] = _C(0xaaaa, LOGOP, 0x24, 0x000000ff, 0x00000060),
.num_counters = 6,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -410,7 +374,6 @@ sm20_atom_count =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x63, 0x000000ff, 0x00000030),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -420,7 +383,6 @@ sm20_branch =
.ctr[0] = _C(0xaaaa, LOGOP, 0x1a, 0x000000ff, 0x00000000),
.ctr[1] = _C(0xaaaa, LOGOP, 0x1a, 0x000000ff, 0x00000010),
.num_counters = 2,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -430,7 +392,6 @@ sm20_divergent_branch =
.ctr[0] = _C(0xaaaa, LOGOP, 0x19, 0x000000ff, 0x00000020),
.ctr[1] = _C(0xaaaa, LOGOP, 0x19, 0x000000ff, 0x00000030),
.num_counters = 2,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -439,7 +400,6 @@ sm20_gld_request =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x64, 0x000000ff, 0x00000030),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -448,7 +408,6 @@ sm20_gred_count =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x63, 0x000000ff, 0x00000040),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -457,7 +416,6 @@ sm20_gst_request =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x64, 0x000000ff, 0x00000060),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -467,7 +425,6 @@ sm20_inst_executed =
.ctr[0] = _C(0xaaaa, LOGOP, 0x2d, 0x0000ffff, 0x00001000),
.ctr[1] = _C(0xaaaa, LOGOP, 0x2d, 0x0000ffff, 0x00001010),
.num_counters = 2,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -477,7 +434,6 @@ sm20_inst_issued =
.ctr[0] = _C(0xaaaa, LOGOP, 0x27, 0x0000ffff, 0x00007060),
.ctr[1] = _C(0xaaaa, LOGOP, 0x27, 0x0000ffff, 0x00007070),
.num_counters = 2,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -486,7 +442,6 @@ sm20_local_ld =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x64, 0x000000ff, 0x00000020),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -495,7 +450,6 @@ sm20_local_st =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x64, 0x000000ff, 0x00000050),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -504,7 +458,6 @@ sm20_prof_trigger_0 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x01, 0x000000ff, 0x00000000),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -513,7 +466,6 @@ sm20_prof_trigger_1 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x01, 0x000000ff, 0x00000010),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -522,7 +474,6 @@ sm20_prof_trigger_2 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x01, 0x000000ff, 0x00000020),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -531,7 +482,6 @@ sm20_prof_trigger_3 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x01, 0x000000ff, 0x00000030),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -540,7 +490,6 @@ sm20_prof_trigger_4 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x01, 0x000000ff, 0x00000040),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -549,7 +498,6 @@ sm20_prof_trigger_5 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x01, 0x000000ff, 0x00000050),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -558,7 +506,6 @@ sm20_prof_trigger_6 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x01, 0x000000ff, 0x00000060),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -567,7 +514,6 @@ sm20_prof_trigger_7 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x01, 0x000000ff, 0x00000070),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -576,7 +522,6 @@ sm20_shared_ld =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x64, 0x000000ff, 0x00000010),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -585,7 +530,6 @@ sm20_shared_st =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x64, 0x000000ff, 0x00000040),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -599,7 +543,6 @@ sm20_threads_launched =
.ctr[4] = _C(0xaaaa, LOGOP, 0x26, 0x000000ff, 0x00000050),
.ctr[5] = _C(0xaaaa, LOGOP, 0x26, 0x000000ff, 0x00000060),
.num_counters = 6,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -613,7 +556,6 @@ sm20_th_inst_executed_0 =
.ctr[4] = _C(0xaaaa, LOGOP, 0x2f, 0x000000ff, 0x00000040),
.ctr[5] = _C(0xaaaa, LOGOP, 0x2f, 0x000000ff, 0x00000050),
.num_counters = 6,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -627,7 +569,6 @@ sm20_th_inst_executed_1 =
.ctr[4] = _C(0xaaaa, LOGOP, 0x30, 0x000000ff, 0x00000040),
.ctr[5] = _C(0xaaaa, LOGOP, 0x30, 0x000000ff, 0x00000050),
.num_counters = 6,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -636,7 +577,6 @@ sm20_warps_launched =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x26, 0x000000ff, 0x00000000),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -684,7 +624,6 @@ sm21_inst_executed =
.ctr[1] = _C(0xaaaa, LOGOP, 0x2d, 0x000000ff, 0x00000010),
.ctr[2] = _C(0xaaaa, LOGOP, 0x2d, 0x000000ff, 0x00000020),
.num_counters = 3,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -693,7 +632,6 @@ sm21_inst_issued1_0 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x7e, 0x000000ff, 0x00000010),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -702,7 +640,6 @@ sm21_inst_issued1_1 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x7e, 0x000000ff, 0x00000040),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -711,7 +648,6 @@ sm21_inst_issued2_0 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x7e, 0x000000ff, 0x00000020),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -720,7 +656,6 @@ sm21_inst_issued2_1 =
{
.ctr[0] = _C(0xaaaa, LOGOP, 0x7e, 0x000000ff, 0x00000050),
.num_counters = 1,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -734,7 +669,6 @@ sm21_th_inst_executed_0 =
.ctr[4] = _C(0xaaaa, LOGOP, 0xa3, 0x000000ff, 0x00000040),
.ctr[5] = _C(0xaaaa, LOGOP, 0xa3, 0x000000ff, 0x00000050),
.num_counters = 6,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -748,7 +682,6 @@ sm21_th_inst_executed_1 =
.ctr[4] = _C(0xaaaa, LOGOP, 0xa5, 0x000000ff, 0x00000040),
.ctr[5] = _C(0xaaaa, LOGOP, 0xa5, 0x000000ff, 0x00000050),
.num_counters = 6,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -762,7 +695,6 @@ sm21_th_inst_executed_2 =
.ctr[4] = _C(0xaaaa, LOGOP, 0xa4, 0x000000ff, 0x00000040),
.ctr[5] = _C(0xaaaa, LOGOP, 0xa4, 0x000000ff, 0x00000050),
.num_counters = 6,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -776,7 +708,6 @@ sm21_th_inst_executed_3 =
.ctr[4] = _C(0xaaaa, LOGOP, 0xa6, 0x000000ff, 0x00000040),
.ctr[5] = _C(0xaaaa, LOGOP, 0xa6, 0x000000ff, 0x00000050),
.num_counters = 6,
- .op = NVC0_COUNTER_OPn_SUM,
.norm = { 1, 1 },
};
@@ -1175,62 +1106,10 @@ nvc0_hw_sm_get_query_result(struct nvc0_context *nvc0, struct nvc0_hw_query *hq,
if (!ret)
return false;
- if (cfg->op == NVC0_COUNTER_OPn_SUM) {
- for (c = 0; c < cfg->num_counters; ++c)
- for (p = 0; p < mp_count; ++p)
- value += count[p][c];
- value = (value * cfg->norm[0]) / cfg->norm[1];
- } else
- if (cfg->op == NVC0_COUNTER_OPn_OR) {
- uint32_t v = 0;
- for (c = 0; c < cfg->num_counters; ++c)
- for (p = 0; p < mp_count; ++p)
- v |= count[p][c];
- value = ((uint64_t)v * cfg->norm[0]) / cfg->norm[1];
- } else
- if (cfg->op == NVC0_COUNTER_OPn_AND) {
- uint32_t v = ~0;
- for (c = 0; c < cfg->num_counters; ++c)
- for (p = 0; p < mp_count; ++p)
- v &= count[p][c];
- value = ((uint64_t)v * cfg->norm[0]) / cfg->norm[1];
- } else
- if (cfg->op == NVC0_COUNTER_OP2_REL_SUM_MM) {
- uint64_t v[2] = { 0, 0 };
- for (p = 0; p < mp_count; ++p) {
- v[0] += count[p][0];
- v[1] += count[p][1];
- }
- if (v[0])
- value = ((v[0] - v[1]) * cfg->norm[0]) / (v[0] * cfg->norm[1]);
- } else
- if (cfg->op == NVC0_COUNTER_OP2_DIV_SUM_M0) {
+ for (c = 0; c < cfg->num_counters; ++c)
for (p = 0; p < mp_count; ++p)
- value += count[p][0];
- if (count[0][1])
- value = (value * cfg->norm[0]) / (count[0][1] * cfg->norm[1]);
- else
- value = 0;
- } else
- if (cfg->op == NVC0_COUNTER_OP2_AVG_DIV_MM) {
- unsigned mp_used = 0;
- for (p = 0; p < mp_count; ++p, mp_used += !!count[p][0])
- if (count[p][1])
- value += (count[p][0] * cfg->norm[0]) / count[p][1];
- if (mp_used)
- value /= (uint64_t)mp_used * cfg->norm[1];
- } else
- if (cfg->op == NVC0_COUNTER_OP2_AVG_DIV_M0) {
- unsigned mp_used = 0;
- for (p = 0; p < mp_count; ++p, mp_used += !!count[p][0])
- value += count[p][0];
- if (count[0][1] && mp_used) {
- value *= cfg->norm[0];
- value /= (uint64_t)count[0][1] * mp_used * cfg->norm[1];
- } else {
- value = 0;
- }
- }
+ value += count[p][c];
+ value = (value * cfg->norm[0]) / cfg->norm[1];
*(uint64_t *)result = value;
return true;
@@ -1272,6 +1151,11 @@ nvc0_hw_sm_create_query(struct nvc0_context *nvc0, unsigned type)
* [04] = WS0.C1
* [08] = WS0.C2
* [0c] = WS0.C3
+ * [10] = WS1.C0
+ * [14] = WS1.C1
+ * [18] = WS1.C2
+ * [1c] = WS1.C3
+ * [20] = WS2.C0
* [24] = WS2.C1
* [28] = WS2.C2
* [2c] = WS2.C3
@@ -1367,8 +1251,6 @@ nvc0_hw_sm_get_driver_query_info(struct nvc0_screen *screen, unsigned id,
if (screen->base.class_3d == NVE4_3D_CLASS) {
info->name = nve4_hw_sm_query_names[id];
info->query_type = NVE4_HW_SM_QUERY(id);
- info->max_value.u64 =
- (id < NVE4_HW_SM_QUERY_METRIC_MP_OCCUPANCY) ? 0 : 100;
info->group_id = NVC0_HW_SM_QUERY_GROUP;
return 1;
} else
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.h b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.h
index 26bde0c3e0d..94d55a04ff8 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.h
@@ -23,6 +23,7 @@ enum nve4_hw_sm_queries
{
NVE4_HW_SM_QUERY_ACTIVE_CYCLES = 0,
NVE4_HW_SM_QUERY_ACTIVE_WARPS,
+ NVE4_HW_SM_QUERY_ATOM_CAS_COUNT,
NVE4_HW_SM_QUERY_ATOM_COUNT,
NVE4_HW_SM_QUERY_BRANCH,
NVE4_HW_SM_QUERY_DIVERGENT_BRANCH,
@@ -33,11 +34,12 @@ enum nve4_hw_sm_queries
NVE4_HW_SM_QUERY_GRED_COUNT,
NVE4_HW_SM_QUERY_GST_REQUEST,
NVE4_HW_SM_QUERY_INST_EXECUTED,
- NVE4_HW_SM_QUERY_INST_ISSUED,
NVE4_HW_SM_QUERY_INST_ISSUED1,
NVE4_HW_SM_QUERY_INST_ISSUED2,
NVE4_HW_SM_QUERY_L1_GLD_HIT,
NVE4_HW_SM_QUERY_L1_GLD_MISS,
+ NVE4_HW_SM_QUERY_L1_GLD_TRANSACTIONS,
+ NVE4_HW_SM_QUERY_L1_GST_TRANSACTIONS,
NVE4_HW_SM_QUERY_L1_LOCAL_LD_HIT,
NVE4_HW_SM_QUERY_L1_LOCAL_LD_MISS,
NVE4_HW_SM_QUERY_L1_LOCAL_ST_HIT,
@@ -64,12 +66,6 @@ enum nve4_hw_sm_queries
NVE4_HW_SM_QUERY_THREADS_LAUNCHED,
NVE4_HW_SM_QUERY_UNCACHED_GLD_TRANSACTIONS,
NVE4_HW_SM_QUERY_WARPS_LAUNCHED,
- NVE4_HW_SM_QUERY_METRIC_IPC,
- NVE4_HW_SM_QUERY_METRIC_IPAC,
- NVE4_HW_SM_QUERY_METRIC_IPEC,
- NVE4_HW_SM_QUERY_METRIC_MP_OCCUPANCY,
- NVE4_HW_SM_QUERY_METRIC_MP_EFFICIENCY,
- NVE4_HW_SM_QUERY_METRIC_INST_REPLAY_OHEAD,
NVE4_HW_SM_QUERY_COUNT
};
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
index 15c803c4307..7fbc6e1fd8e 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
@@ -37,8 +37,6 @@ nvc0_surface_create(struct pipe_context *pipe,
struct pipe_resource *pres,
const struct pipe_surface *templ)
{
- /* surfaces are assumed to be miptrees all over the place. */
- assert(pres->target != PIPE_BUFFER);
if (unlikely(pres->target == PIPE_BUFFER))
return nv50_surface_from_buffer(pipe, pres, templ);
return nvc0_miptree_surface_new(pipe, pres, templ);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index 5dce5f0e65d..41a824a97a0 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -176,7 +176,7 @@ nvc0_blend_state_create(struct pipe_context *pipe,
}
}
- assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
+ assert(so->size <= ARRAY_SIZE(so->state));
return so;
}
@@ -305,7 +305,7 @@ nvc0_rasterizer_state_create(struct pipe_context *pipe,
SB_IMMED_3D(so, PIXEL_CENTER_INTEGER, !cso->half_pixel_center);
- assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
+ assert(so->size <= ARRAY_SIZE(so->state));
return (void *)so;
}
@@ -383,7 +383,7 @@ nvc0_zsa_state_create(struct pipe_context *pipe,
SB_DATA (so, nvgl_comparison_op(cso->alpha.func));
}
- assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
+ assert(so->size <= ARRAY_SIZE(so->state));
return (void *)so;
}
@@ -1000,6 +1000,9 @@ nvc0_set_vertex_buffers(struct pipe_context *pipe,
struct nvc0_context *nvc0 = nvc0_context(pipe);
unsigned i;
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
+ nvc0->dirty |= NVC0_NEW_ARRAYS;
+
util_set_vertex_buffers_count(nvc0->vtxbuf, &nvc0->num_vtxbufs, vb,
start_slot, count);
@@ -1023,9 +1026,6 @@ nvc0_set_vertex_buffers(struct pipe_context *pipe,
nvc0->constant_vbos &= ~(1 << dst_index);
}
}
-
- nvc0->dirty |= NVC0_NEW_ARRAYS;
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
}
static void
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
index 205e7dc6ae9..b02a590c375 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -667,7 +667,6 @@ static struct state_validate {
{ nvc0_tfb_validate, NVC0_NEW_TFB_TARGETS | NVC0_NEW_GMTYPROG },
{ nvc0_validate_min_samples, NVC0_NEW_MIN_SAMPLES },
};
-#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
bool
nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words)
@@ -682,7 +681,7 @@ nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words)
state_mask = nvc0->dirty & mask;
if (state_mask) {
- for (i = 0; i < validate_list_len; ++i) {
+ for (i = 0; i < ARRAY_SIZE(validate_list); ++i) {
struct state_validate *validate = &validate_list[i];
if (state_mask & validate->states)
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index 6a4ae5be2ab..f8e1efb9834 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -288,6 +288,8 @@ nvc0_clear_render_target(struct pipe_context *pipe,
struct nv04_resource *res = nv04_resource(sf->base.texture);
unsigned z;
+ assert(dst->texture->target != PIPE_BUFFER);
+
if (!PUSH_SPACE(push, 32 + sf->depth))
return;
@@ -516,6 +518,8 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
unsigned z;
+ assert(dst->texture->target != PIPE_BUFFER);
+
if (!PUSH_SPACE(push, 32 + sf->depth))
return;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
index 9139bc1c911..4392f62c530 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
@@ -56,7 +56,7 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
#endif
{ dec->bitplane_bo, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
};
- int num_refs = sizeof(bo_refs)/sizeof(*bo_refs);
+ int num_refs = ARRAY_SIZE(bo_refs);
if (!dec->bitplane_bo)
num_refs--;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c
index 4ceec4fbffc..e4504e6c411 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c
@@ -40,7 +40,7 @@ nvc0_decoder_setup_ppp(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video
{ dec->fence_bo, NOUVEAU_BO_WR | NOUVEAU_BO_GART },
#endif
};
- unsigned num_refs = sizeof(bo_refs)/sizeof(*bo_refs);
+ unsigned num_refs = ARRAY_SIZE(bo_refs);
for (i = 0; i < 2; ++i) {
struct nv50_miptree *mt = (struct nv50_miptree *)target->resources[i];
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
index 91543782dfc..73d55148151 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
@@ -86,7 +86,7 @@ nvc0_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
#endif
{ dec->fw_bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM },
};
- int num_refs = sizeof(bo_refs)/sizeof(*bo_refs) - !dec->fw_bo;
+ int num_refs = ARRAY_SIZE(bo_refs) - !dec->fw_bo;
#if NOUVEAU_VP3_DEBUG_FENCE
fence_extra = 4;
diff --git a/src/gallium/drivers/nouveau/nvc0/nve4_compute.xml.h b/src/gallium/drivers/nouveau/nvc0/nve4_compute.xml.h
index 41e0cc209c8..3fff1122b8f 100644
--- a/src/gallium/drivers/nouveau/nvc0/nve4_compute.xml.h
+++ b/src/gallium/drivers/nouveau/nvc0/nve4_compute.xml.h
@@ -304,6 +304,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVE4_COMPUTE_MP_PM_B_SIGSEL_WARP 0x00000002
#define NVE4_COMPUTE_MP_PM_B_SIGSEL_REPLAY 0x00000008
#define NVE4_COMPUTE_MP_PM_B_SIGSEL_TRANSACTION 0x0000000e
+#define NVE4_COMPUTE_MP_PM_B_SIGSEL_UNK0F 0x0000000f
#define NVE4_COMPUTE_MP_PM_B_SIGSEL_L1 0x00000010
#define NVE4_COMPUTE_MP_PM_B_SIGSEL_MEM 0x00000011
diff --git a/src/gallium/drivers/r300/compiler/r3xx_vertprog.c b/src/gallium/drivers/r300/compiler/r3xx_vertprog.c
index 2ff6db54637..810a79ac1e2 100644
--- a/src/gallium/drivers/r300/compiler/r3xx_vertprog.c
+++ b/src/gallium/drivers/r300/compiler/r3xx_vertprog.c
@@ -847,7 +847,7 @@ static void rc_emulate_negative_addressing(struct radeon_compiler *compiler, voi
if (inst->U.I.SrcReg[i].RelAddr &&
inst->U.I.SrcReg[i].Index < 0) {
/* ARL must precede any indirect addressing. */
- if (lastARL == NULL) {
+ if (!lastARL) {
rc_error(&c->Base, "Vertex shader: Found relative addressing without ARL/ARR.");
return;
}
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index 6451a2c8df2..e9395738d52 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -129,7 +129,7 @@ r300_buffer_transfer_map( struct pipe_context *context,
map = rws->buffer_map(rbuf->cs_buf, r300->cs, usage);
- if (map == NULL) {
+ if (!map) {
util_slab_free(&r300->pool_transfers, transfer);
return NULL;
}
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index d99d5ae0152..1d78134de6d 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1125,7 +1125,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
struct r300_context* r300 = r300_context(pipe);
struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
- if (fs == NULL) {
+ if (!fs) {
r300->fs.state = NULL;
return;
}
@@ -1950,7 +1950,7 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
struct r300_context *r300 = r300_context(pipe);
struct r300_vertex_element_state *velems = state;
- if (velems == NULL) {
+ if (!velems) {
return;
}
@@ -1996,7 +1996,7 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
struct r300_context* r300 = r300_context(pipe);
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
- if (vs == NULL) {
+ if (!vs) {
r300->vs_state.state = NULL;
return;
}
diff --git a/src/gallium/drivers/r600/compute_memory_pool.c b/src/gallium/drivers/r600/compute_memory_pool.c
index 7c5113e9197..93e3ffe256f 100644
--- a/src/gallium/drivers/r600/compute_memory_pool.c
+++ b/src/gallium/drivers/r600/compute_memory_pool.c
@@ -51,7 +51,7 @@ struct compute_memory_pool* compute_memory_pool_new(
{
struct compute_memory_pool* pool = (struct compute_memory_pool*)
CALLOC(sizeof(struct compute_memory_pool), 1);
- if (pool == NULL)
+ if (!pool)
return NULL;
COMPUTE_DBG(rscreen, "* compute_memory_pool_new()\n");
@@ -80,8 +80,8 @@ static void compute_memory_pool_init(struct compute_memory_pool * pool,
initial_size_in_dw);
pool->size_in_dw = initial_size_in_dw;
- pool->bo = (struct r600_resource*)r600_compute_buffer_alloc_vram(pool->screen,
- pool->size_in_dw * 4);
+ pool->bo = r600_compute_buffer_alloc_vram(pool->screen,
+ pool->size_in_dw * 4);
}
/**
@@ -202,8 +202,7 @@ int compute_memory_grow_defrag_pool(struct compute_memory_pool *pool,
} else {
struct r600_resource *temp = NULL;
- temp = (struct r600_resource *)r600_compute_buffer_alloc_vram(
- pool->screen, new_size_in_dw * 4);
+ temp = r600_compute_buffer_alloc_vram(pool->screen, new_size_in_dw * 4);
if (temp != NULL) {
struct pipe_resource *src = (struct pipe_resource *)pool->bo;
@@ -234,9 +233,7 @@ int compute_memory_grow_defrag_pool(struct compute_memory_pool *pool,
pool->screen->b.b.resource_destroy(
(struct pipe_screen *)pool->screen,
(struct pipe_resource *)pool->bo);
- pool->bo = (struct r600_resource*)r600_compute_buffer_alloc_vram(
- pool->screen,
- pool->size_in_dw * 4);
+ pool->bo = r600_compute_buffer_alloc_vram(pool->screen, pool->size_in_dw * 4);
compute_memory_shadow(pool, pipe, 0);
if (pool->status & POOL_FRAGMENTED) {
@@ -402,7 +399,7 @@ int compute_memory_promote_item(struct compute_memory_pool *pool,
list_addtail(&item->link, pool->item_list);
item->start_in_dw = start_in_dw;
- if (src != NULL) {
+ if (src) {
u_box_1d(0, item->size_in_dw * 4, &box);
rctx->b.b.resource_copy_region(pipe,
@@ -449,7 +446,7 @@ void compute_memory_demote_item(struct compute_memory_pool *pool,
/* We check if the intermediate buffer exists, and if it
* doesn't, we create it again */
if (item->real_buffer == NULL) {
- item->real_buffer = (struct r600_resource*)r600_compute_buffer_alloc_vram(
+ item->real_buffer = r600_compute_buffer_alloc_vram(
pool->screen, item->size_in_dw * 4);
}
@@ -633,7 +630,7 @@ struct compute_memory_item* compute_memory_alloc(
new_item = (struct compute_memory_item *)
CALLOC(sizeof(struct compute_memory_item), 1);
- if (new_item == NULL)
+ if (!new_item)
return NULL;
new_item->size_in_dw = size_in_dw;
diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c
index c32d317a1a5..46683c19020 100644
--- a/src/gallium/drivers/r600/eg_asm.c
+++ b/src/gallium/drivers/r600/eg_asm.c
@@ -193,3 +193,101 @@ int egcm_load_index_reg(struct r600_bytecode *bc, unsigned id, bool inside_alu_c
return 0;
}
+
+int eg_bytecode_gds_build(struct r600_bytecode *bc, struct r600_bytecode_gds *gds, unsigned id)
+{
+ unsigned opcode = r600_isa_fetch_opcode(bc->isa->hw_class, gds->op) >> 8;
+ bc->bytecode[id++] = S_SQ_MEM_GDS_WORD0_MEM_INST(2) |
+ S_SQ_MEM_GDS_WORD0_MEM_OP(opcode) |
+ S_SQ_MEM_GDS_WORD0_SRC_GPR(gds->src_gpr) |
+ S_SQ_MEM_GDS_WORD0_SRC_REL(gds->src_rel) |
+ S_SQ_MEM_GDS_WORD0_SRC_SEL_X(gds->src_sel_x) |
+ S_SQ_MEM_GDS_WORD0_SRC_SEL_Y(gds->src_sel_y) |
+ S_SQ_MEM_GDS_WORD0_SRC_SEL_Z(gds->src_sel_z);
+
+ bc->bytecode[id++] = S_SQ_MEM_GDS_WORD1_DST_GPR(gds->dst_gpr) |
+ S_SQ_MEM_GDS_WORD1_DST_REL(gds->dst_rel) |
+ S_SQ_MEM_GDS_WORD1_GDS_OP(gds->gds_op) |
+ S_SQ_MEM_GDS_WORD1_SRC_GPR(gds->src_gpr2);
+
+ bc->bytecode[id++] = S_SQ_MEM_GDS_WORD2_DST_SEL_X(gds->dst_sel_x) |
+ S_SQ_MEM_GDS_WORD2_DST_SEL_Y(gds->dst_sel_y) |
+ S_SQ_MEM_GDS_WORD2_DST_SEL_Z(gds->dst_sel_z) |
+ S_SQ_MEM_GDS_WORD2_DST_SEL_W(gds->dst_sel_w);
+ return 0;
+}
+
+int eg_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *alu, unsigned id)
+{
+ if (alu->is_lds_idx_op) {
+ assert(!alu->src[0].abs && !alu->src[1].abs && !alu->src[2].abs);
+ assert(!alu->src[0].neg && !alu->src[1].neg && !alu->src[2].neg);
+ bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+ S_SQ_ALU_WORD0_SRC0_REL(alu->src[0].rel) |
+ S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+ S_SQ_ALU_WORD0_LDS_IDX_OP_IDX_OFFSET_4(alu->lds_idx >> 4) |
+ S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+ S_SQ_ALU_WORD0_SRC1_REL(alu->src[1].rel) |
+ S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+ S_SQ_ALU_WORD0_LDS_IDX_OP_IDX_OFFSET_5(alu->lds_idx >> 5) |
+ S_SQ_ALU_WORD0_INDEX_MODE(alu->index_mode) |
+ S_SQ_ALU_WORD0_PRED_SEL(alu->pred_sel) |
+ S_SQ_ALU_WORD0_LAST(alu->last);
+ } else {
+ bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+ S_SQ_ALU_WORD0_SRC0_REL(alu->src[0].rel) |
+ S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+ S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
+ S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+ S_SQ_ALU_WORD0_SRC1_REL(alu->src[1].rel) |
+ S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+ S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
+ S_SQ_ALU_WORD0_PRED_SEL(alu->pred_sel) |
+ S_SQ_ALU_WORD0_LAST(alu->last);
+ }
+
+ /* don't replace gpr by pv or ps for destination register */
+ if (alu->is_lds_idx_op) {
+ unsigned lds_op = r600_isa_alu_opcode(bc->isa->hw_class, alu->op);
+ bc->bytecode[id++] =
+ S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
+ S_SQ_ALU_WORD1_OP3_SRC2_REL(alu->src[2].rel) |
+ S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
+ S_SQ_ALU_WORD1_LDS_IDX_OP_IDX_OFFSET_1(alu->lds_idx >> 1) |
+
+ S_SQ_ALU_WORD1_OP3_ALU_INST(lds_op & 0xff) |
+ S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle) |
+ S_SQ_ALU_WORD1_LDS_IDX_OP_LDS_OP((lds_op >> 8) & 0xff) |
+ S_SQ_ALU_WORD1_LDS_IDX_OP_IDX_OFFSET_0(alu->lds_idx) |
+ S_SQ_ALU_WORD1_LDS_IDX_OP_IDX_OFFSET_2(alu->lds_idx >> 2) |
+ S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+ S_SQ_ALU_WORD1_LDS_IDX_OP_IDX_OFFSET_3(alu->lds_idx >> 3);
+
+ } else if (alu->is_op3) {
+ assert(!alu->src[0].abs && !alu->src[1].abs && !alu->src[2].abs);
+ bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+ S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+ S_SQ_ALU_WORD1_DST_REL(alu->dst.rel) |
+ S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) |
+ S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
+ S_SQ_ALU_WORD1_OP3_SRC2_REL(alu->src[2].rel) |
+ S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
+ S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
+ S_SQ_ALU_WORD1_OP3_ALU_INST(r600_isa_alu_opcode(bc->isa->hw_class, alu->op)) |
+ S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle);
+ } else {
+ bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+ S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+ S_SQ_ALU_WORD1_DST_REL(alu->dst.rel) |
+ S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) |
+ S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
+ S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
+ S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) |
+ S_SQ_ALU_WORD1_OP2_OMOD(alu->omod) |
+ S_SQ_ALU_WORD1_OP2_ALU_INST(r600_isa_alu_opcode(bc->isa->hw_class, alu->op)) |
+ S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle) |
+ S_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(alu->execute_mask) |
+ S_SQ_ALU_WORD1_OP2_UPDATE_PRED(alu->update_pred);
+ }
+ return 0;
+}
diff --git a/src/gallium/drivers/r600/eg_sq.h b/src/gallium/drivers/r600/eg_sq.h
index 97e230f56c7..c118d3a007f 100644
--- a/src/gallium/drivers/r600/eg_sq.h
+++ b/src/gallium/drivers/r600/eg_sq.h
@@ -514,6 +514,66 @@
#define G_SQ_TEX_WORD2_SRC_SEL_W(x) (((x) >> 29) & 0x7)
#define C_SQ_TEX_WORD2_SRC_SEL_W 0x1FFFFFFF
+#define P_SQ_MEM_GDS_WORD0
+#define S_SQ_MEM_GDS_WORD0_MEM_INST(x) (((x) & 0x1f) << 0)
+#define S_SQ_MEM_GDS_WORD0_MEM_OP(x) (((x) & 0x7) << 8)
+#define S_SQ_MEM_GDS_WORD0_SRC_GPR(x) (((x) & 0x7f) << 11)
+#define S_SQ_MEM_GDS_WORD0_SRC_REL(x) (((x) & 0x3) << 18)
+#define S_SQ_MEM_GDS_WORD0_SRC_SEL_X(x) (((x) & 0x7) << 20)
+#define S_SQ_MEM_GDS_WORD0_SRC_SEL_Y(x) (((x) & 0x7) << 23)
+#define S_SQ_MEM_GDS_WORD0_SRC_SEL_Z(x) (((x) & 0x7) << 26)
+
+#define P_SQ_MEM_GDS_WORD1
+#define S_SQ_MEM_GDS_WORD1_DST_GPR(x) (((x) & 0x7f) << 0)
+#define S_SQ_MEM_GDS_WORD1_DST_REL(x) (((x) & 0x3) << 7)
+#define S_SQ_MEM_GDS_WORD1_GDS_OP(x) (((x) & 0x3f) << 9)
+#define S_SQ_MEM_GDS_WORD1_SRC_GPR(x) (((x) & 0x7f) << 16)
+
+#define P_SQ_MEM_GDS_WORD2
+#define S_SQ_MEM_GDS_WORD2_DST_SEL_X(x) (((x) & 0x7) << 0)
+#define S_SQ_MEM_GDS_WORD2_DST_SEL_Y(x) (((x) & 0x7) << 3)
+#define S_SQ_MEM_GDS_WORD2_DST_SEL_Z(x) (((x) & 0x7) << 6)
+#define S_SQ_MEM_GDS_WORD2_DST_SEL_W(x) (((x) & 0x7) << 9)
+
+/* LDS IDX redefines the neg bits on op3 */
+#define S_SQ_ALU_WORD0_LDS_IDX_OP_IDX_OFFSET_4(x) (((x) & 0x1) << 12)
+#define S_SQ_ALU_WORD0_LDS_IDX_OP_IDX_OFFSET_5(x) (((x) & 0x1) << 25)
+
+/* src2 neg */
+#define S_SQ_ALU_WORD1_LDS_IDX_OP_IDX_OFFSET_1(x) (((x) & 0x1) << 12)
+
+/* this was dst gpr */
+#define S_SQ_ALU_WORD1_LDS_IDX_OP_LDS_OP(x) (((x) & 0x3f) << 21)
+#define S_SQ_ALU_WORD1_LDS_IDX_OP_IDX_OFFSET_0(x) (((x) & 0x1) << 27)
+
+/* this was dst rel */
+#define S_SQ_ALU_WORD1_LDS_IDX_OP_IDX_OFFSET_2(x) (((x) & 0x1) << 28)
+/* this was clamp */
+#define S_SQ_ALU_WORD1_LDS_IDX_OP_IDX_OFFSET_3(x) (((x) & 0x1) << 31)
+
+#define V_SQ_LDS_INST_ADD 0x00
+#define V_SQ_LDS_INST_SUB 0x01
+#define V_SQ_LDS_INST_RSUB 0x02
+
+#define V_SQ_LDS_INST_INC 0x03
+#define V_SQ_LDS_INST_DEC 0x04
+#define V_SQ_LDS_INST_MIN_INT 0x05
+#define V_SQ_LDS_INST_MAX_INT 0x06
+#define V_SQ_LDS_INST_MIN_UINT 0x07
+#define V_SQ_LDS_INST_MAX_UINT 0x08
+#define V_SQ_LDS_INST_AND 0x09
+#define V_SQ_LDS_INST_OR 0x0a
+#define V_SQ_LDS_INST_XOR 0x0b
+#define V_SQ_LDS_INST_MSKOR 0x0c
+#define V_SQ_LDS_INST_WRITE 0x0d
+#define V_SQ_LDS_INST_WRITE_REL 0x0e
+#define V_SQ_LDS_INST_WRITE2 0x0f
+
+#define V_SQ_LDS_INST_READ_RET 0x32
+#define V_SQ_LDS_INST_READ_REL_RET 0x33
+#define V_SQ_LDS_INST_READ2_RET 0x34
+#define V_SQ_LDS_INST_READWRITE_RET 0x35
+
#define V_SQ_CF_COND_ACTIVE 0x00
#define V_SQ_CF_COND_FALSE 0x01
#define V_SQ_CF_COND_BOOL 0x02
diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index 5743e3fe538..ef6de8c98d1 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -237,7 +237,7 @@ void *evergreen_create_compute_state(
#endif
#endif
- shader->ctx = (struct r600_context*)ctx;
+ shader->ctx = ctx;
shader->local_size = cso->req_local_mem;
shader->private_size = cso->req_private_mem;
shader->input_size = cso->req_input_mem;
@@ -402,7 +402,7 @@ static void evergreen_emit_direct_dispatch(
assert(lds_size <= 8160);
}
- radeon_compute_set_context_reg(cs, CM_R_0288E8_SQ_LDS_ALLOC,
+ radeon_compute_set_context_reg(cs, R_0288E8_SQ_LDS_ALLOC,
lds_size | (num_waves << 14));
/* Dispatch packet */
@@ -432,6 +432,10 @@ static void compute_emit_cs(struct r600_context *ctx, const uint *block_layout,
*/
r600_emit_command_buffer(cs, &ctx->start_compute_cs_cmd);
+ /* emit config state */
+ if (ctx->b.chip_class == EVERGREEN)
+ r600_emit_atom(ctx, &ctx->config_state.atom);
+
ctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV;
r600_flush_emit(ctx);
@@ -791,7 +795,7 @@ void evergreen_init_atom_start_compute_cs(struct r600_context *ctx)
/* Config Registers */
if (ctx->b.chip_class < CAYMAN)
- evergreen_init_common_regs(cb, ctx->b.chip_class, ctx->b.family,
+ evergreen_init_common_regs(ctx, cb, ctx->b.chip_class, ctx->b.family,
ctx->screen->b.info.drm_minor);
else
cayman_init_common_regs(cb, ctx->b.chip_class, ctx->b.family,
@@ -997,7 +1001,7 @@ void *r600_compute_global_transfer_map(
}
else {
if (item->real_buffer == NULL) {
- item->real_buffer = (struct r600_resource*)
+ item->real_buffer =
r600_compute_buffer_alloc_vram(pool->screen, item->size_in_dw * 4);
}
}
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 684eee7a355..6e0c448ce8a 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -404,7 +404,7 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx,
unsigned db_depth_control, alpha_test_control, alpha_ref;
struct r600_dsa_state *dsa = CALLOC_STRUCT(r600_dsa_state);
- if (dsa == NULL) {
+ if (!dsa) {
return NULL;
}
@@ -461,7 +461,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
float psize_min, psize_max;
struct r600_rasterizer_state *rs = CALLOC_STRUCT(r600_rasterizer_state);
- if (rs == NULL) {
+ if (!rs) {
return NULL;
}
@@ -558,7 +558,7 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx,
struct r600_pipe_sampler_state *ss = CALLOC_STRUCT(r600_pipe_sampler_state);
unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 2 : 0;
- if (ss == NULL) {
+ if (!ss) {
return NULL;
}
@@ -669,7 +669,7 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
unsigned dim, last_layer;
uint64_t va;
- if (view == NULL)
+ if (!view)
return NULL;
/* initialize base object */
@@ -869,6 +869,33 @@ evergreen_create_sampler_view(struct pipe_context *ctx,
tex->width0, tex->height0, 0);
}
+static void evergreen_emit_config_state(struct r600_context *rctx, struct r600_atom *atom)
+{
+ struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct r600_config_state *a = (struct r600_config_state*)atom;
+
+ radeon_set_config_reg_seq(cs, R_008C04_SQ_GPR_RESOURCE_MGMT_1, 3);
+ if (a->dyn_gpr_enabled) {
+ radeon_emit(cs, S_008C04_NUM_CLAUSE_TEMP_GPRS(rctx->r6xx_num_clause_temp_gprs));
+ radeon_emit(cs, 0);
+ radeon_emit(cs, 0);
+ } else {
+ radeon_emit(cs, a->sq_gpr_resource_mgmt_1);
+ radeon_emit(cs, a->sq_gpr_resource_mgmt_2);
+ radeon_emit(cs, a->sq_gpr_resource_mgmt_3);
+ }
+ radeon_set_config_reg(cs, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, (a->dyn_gpr_enabled << 8));
+ if (a->dyn_gpr_enabled) {
+ radeon_set_context_reg(cs, R_028838_SQ_DYN_GPR_RESOURCE_LIMIT_1,
+ S_028838_PS_GPRS(0x1e) |
+ S_028838_VS_GPRS(0x1e) |
+ S_028838_GS_GPRS(0x1e) |
+ S_028838_ES_GPRS(0x1e) |
+ S_028838_HS_GPRS(0x1e) |
+ S_028838_LS_GPRS(0x1e)); /* workaround for hw issues with dyn gpr - must set all limits to 240 instead of 0, 0x1e == 240 / 8*/
+ }
+}
+
static void evergreen_emit_clip_state(struct r600_context *rctx, struct r600_atom *atom)
{
struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
@@ -1978,13 +2005,22 @@ static void evergreen_emit_constant_buffers(struct r600_context *rctx,
state->dirty_mask = 0;
}
+/* VS constants can be in VS/ES (same space) or LS if tess is enabled */
static void evergreen_emit_vs_constant_buffers(struct r600_context *rctx, struct r600_atom *atom)
{
- evergreen_emit_constant_buffers(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX],
- EG_FETCH_CONSTANTS_OFFSET_VS,
- R_028180_ALU_CONST_BUFFER_SIZE_VS_0,
- R_028980_ALU_CONST_CACHE_VS_0,
- 0 /* PKT3 flags */);
+ if (rctx->vs_shader->current->shader.vs_as_ls) {
+ evergreen_emit_constant_buffers(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX],
+ EG_FETCH_CONSTANTS_OFFSET_LS,
+ R_028FC0_ALU_CONST_BUFFER_SIZE_LS_0,
+ R_028F40_ALU_CONST_CACHE_LS_0,
+ 0 /* PKT3 flags */);
+ } else {
+ evergreen_emit_constant_buffers(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX],
+ EG_FETCH_CONSTANTS_OFFSET_VS,
+ R_028180_ALU_CONST_BUFFER_SIZE_VS_0,
+ R_028980_ALU_CONST_CACHE_VS_0,
+ 0 /* PKT3 flags */);
+ }
}
static void evergreen_emit_gs_constant_buffers(struct r600_context *rctx, struct r600_atom *atom)
@@ -2014,6 +2050,29 @@ static void evergreen_emit_cs_constant_buffers(struct r600_context *rctx, struct
RADEON_CP_PACKET3_COMPUTE_MODE);
}
+/* tes constants can be emitted to VS or ES - which are common */
+static void evergreen_emit_tes_constant_buffers(struct r600_context *rctx, struct r600_atom *atom)
+{
+ if (!rctx->tes_shader)
+ return;
+ evergreen_emit_constant_buffers(rctx, &rctx->constbuf_state[PIPE_SHADER_TESS_EVAL],
+ EG_FETCH_CONSTANTS_OFFSET_VS,
+ R_028180_ALU_CONST_BUFFER_SIZE_VS_0,
+ R_028980_ALU_CONST_CACHE_VS_0,
+ 0);
+}
+
+static void evergreen_emit_tcs_constant_buffers(struct r600_context *rctx, struct r600_atom *atom)
+{
+ if (!rctx->tes_shader)
+ return;
+ evergreen_emit_constant_buffers(rctx, &rctx->constbuf_state[PIPE_SHADER_TESS_CTRL],
+ EG_FETCH_CONSTANTS_OFFSET_HS,
+ R_028F80_ALU_CONST_BUFFER_SIZE_HS_0,
+ R_028F00_ALU_CONST_CACHE_HS_0,
+ 0);
+}
+
static void evergreen_emit_sampler_views(struct r600_context *rctx,
struct r600_samplerview_state *state,
unsigned resource_id_base, unsigned pkt_flags)
@@ -2049,8 +2108,13 @@ static void evergreen_emit_sampler_views(struct r600_context *rctx,
static void evergreen_emit_vs_sampler_views(struct r600_context *rctx, struct r600_atom *atom)
{
- evergreen_emit_sampler_views(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views,
- EG_FETCH_CONSTANTS_OFFSET_VS + R600_MAX_CONST_BUFFERS, 0);
+ if (rctx->vs_shader->current->shader.vs_as_ls) {
+ evergreen_emit_sampler_views(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views,
+ EG_FETCH_CONSTANTS_OFFSET_LS + R600_MAX_CONST_BUFFERS, 0);
+ } else {
+ evergreen_emit_sampler_views(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views,
+ EG_FETCH_CONSTANTS_OFFSET_VS + R600_MAX_CONST_BUFFERS, 0);
+ }
}
static void evergreen_emit_gs_sampler_views(struct r600_context *rctx, struct r600_atom *atom)
@@ -2059,6 +2123,18 @@ static void evergreen_emit_gs_sampler_views(struct r600_context *rctx, struct r6
EG_FETCH_CONSTANTS_OFFSET_GS + R600_MAX_CONST_BUFFERS, 0);
}
+static void evergreen_emit_tcs_sampler_views(struct r600_context *rctx, struct r600_atom *atom)
+{
+ evergreen_emit_sampler_views(rctx, &rctx->samplers[PIPE_SHADER_TESS_CTRL].views,
+ EG_FETCH_CONSTANTS_OFFSET_HS + R600_MAX_CONST_BUFFERS, 0);
+}
+
+static void evergreen_emit_tes_sampler_views(struct r600_context *rctx, struct r600_atom *atom)
+{
+ evergreen_emit_sampler_views(rctx, &rctx->samplers[PIPE_SHADER_TESS_EVAL].views,
+ EG_FETCH_CONSTANTS_OFFSET_VS + R600_MAX_CONST_BUFFERS, 0);
+}
+
static void evergreen_emit_ps_sampler_views(struct r600_context *rctx, struct r600_atom *atom)
{
evergreen_emit_sampler_views(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].views,
@@ -2102,8 +2178,13 @@ static void evergreen_emit_sampler_states(struct r600_context *rctx,
static void evergreen_emit_vs_sampler_states(struct r600_context *rctx, struct r600_atom *atom)
{
- evergreen_emit_sampler_states(rctx, &rctx->samplers[PIPE_SHADER_VERTEX], 18,
- R_00A414_TD_VS_SAMPLER0_BORDER_INDEX, 0);
+ if (rctx->vs_shader->current->shader.vs_as_ls) {
+ evergreen_emit_sampler_states(rctx, &rctx->samplers[PIPE_SHADER_VERTEX], 72,
+ R_00A450_TD_LS_SAMPLER0_BORDER_COLOR_INDEX, 0);
+ } else {
+ evergreen_emit_sampler_states(rctx, &rctx->samplers[PIPE_SHADER_VERTEX], 18,
+ R_00A414_TD_VS_SAMPLER0_BORDER_INDEX, 0);
+ }
}
static void evergreen_emit_gs_sampler_states(struct r600_context *rctx, struct r600_atom *atom)
@@ -2112,6 +2193,18 @@ static void evergreen_emit_gs_sampler_states(struct r600_context *rctx, struct r
R_00A428_TD_GS_SAMPLER0_BORDER_INDEX, 0);
}
+static void evergreen_emit_tcs_sampler_states(struct r600_context *rctx, struct r600_atom *atom)
+{
+ evergreen_emit_sampler_states(rctx, &rctx->samplers[PIPE_SHADER_TESS_CTRL], 54,
+ R_00A43C_TD_HS_SAMPLER0_BORDER_COLOR_INDEX, 0);
+}
+
+static void evergreen_emit_tes_sampler_states(struct r600_context *rctx, struct r600_atom *atom)
+{
+ evergreen_emit_sampler_states(rctx, &rctx->samplers[PIPE_SHADER_TESS_EVAL], 18,
+ R_00A414_TD_VS_SAMPLER0_BORDER_INDEX, 0);
+}
+
static void evergreen_emit_ps_sampler_states(struct r600_context *rctx, struct r600_atom *atom)
{
evergreen_emit_sampler_states(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT], 0,
@@ -2164,7 +2257,7 @@ static void evergreen_emit_shader_stages(struct r600_context *rctx, struct r600_
struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
struct r600_shader_stages_state *state = (struct r600_shader_stages_state*)a;
- uint32_t v = 0, v2 = 0, primid = 0;
+ uint32_t v = 0, v2 = 0, primid = 0, tf_param = 0;
if (rctx->vs_shader->current->shader.vs_as_gs_a) {
v2 = S_028A40_MODE(V_028A40_GS_SCENARIO_A);
@@ -2182,9 +2275,11 @@ static void evergreen_emit_shader_stages(struct r600_context *rctx, struct r600_
cut_val = V_028A40_GS_CUT_512;
else
cut_val = V_028A40_GS_CUT_1024;
- v = S_028B54_ES_EN(V_028B54_ES_STAGE_REAL) |
- S_028B54_GS_EN(1) |
- S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER);
+
+ v = S_028B54_GS_EN(1) |
+ S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER);
+ if (!rctx->tes_shader)
+ v |= S_028B54_ES_EN(V_028B54_ES_STAGE_REAL);
v2 = S_028A40_MODE(V_028A40_GS_SCENARIO_G) |
S_028A40_CUT_MODE(cut_val);
@@ -2193,9 +2288,72 @@ static void evergreen_emit_shader_stages(struct r600_context *rctx, struct r600_
primid = 1;
}
+ if (rctx->tes_shader) {
+ uint32_t type, partitioning, topology;
+ struct tgsi_shader_info *info = &rctx->tes_shader->current->selector->info;
+ unsigned tes_prim_mode = info->properties[TGSI_PROPERTY_TES_PRIM_MODE];
+ unsigned tes_spacing = info->properties[TGSI_PROPERTY_TES_SPACING];
+ bool tes_vertex_order_cw = info->properties[TGSI_PROPERTY_TES_VERTEX_ORDER_CW];
+ bool tes_point_mode = info->properties[TGSI_PROPERTY_TES_POINT_MODE];
+ switch (tes_prim_mode) {
+ case PIPE_PRIM_LINES:
+ type = V_028B6C_TESS_ISOLINE;
+ break;
+ case PIPE_PRIM_TRIANGLES:
+ type = V_028B6C_TESS_TRIANGLE;
+ break;
+ case PIPE_PRIM_QUADS:
+ type = V_028B6C_TESS_QUAD;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+
+ switch (tes_spacing) {
+ case PIPE_TESS_SPACING_FRACTIONAL_ODD:
+ partitioning = V_028B6C_PART_FRAC_ODD;
+ break;
+ case PIPE_TESS_SPACING_FRACTIONAL_EVEN:
+ partitioning = V_028B6C_PART_FRAC_EVEN;
+ break;
+ case PIPE_TESS_SPACING_EQUAL:
+ partitioning = V_028B6C_PART_INTEGER;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+
+ if (tes_point_mode)
+ topology = V_028B6C_OUTPUT_POINT;
+ else if (tes_prim_mode == PIPE_PRIM_LINES)
+ topology = V_028B6C_OUTPUT_LINE;
+ else if (tes_vertex_order_cw)
+ /* XXX follow radeonsi and invert */
+ topology = V_028B6C_OUTPUT_TRIANGLE_CCW;
+ else
+ topology = V_028B6C_OUTPUT_TRIANGLE_CW;
+
+ tf_param = S_028B6C_TYPE(type) |
+ S_028B6C_PARTITIONING(partitioning) |
+ S_028B6C_TOPOLOGY(topology);
+ }
+
+ if (rctx->tes_shader) {
+ v |= S_028B54_LS_EN(V_028B54_LS_STAGE_ON) |
+ S_028B54_HS_EN(1);
+ if (!state->geom_enable)
+ v |= S_028B54_VS_EN(V_028B54_VS_STAGE_DS);
+ else
+ v |= S_028B54_ES_EN(V_028B54_ES_STAGE_DS);
+ }
+
+ radeon_set_context_reg(cs, R_028AB8_VGT_VTX_CNT_EN, v ? 1 : 0 );
radeon_set_context_reg(cs, R_028B54_VGT_SHADER_STAGES_EN, v);
radeon_set_context_reg(cs, R_028A40_VGT_GS_MODE, v2);
radeon_set_context_reg(cs, R_028A84_VGT_PRIMITIVEID_EN, primid);
+ radeon_set_context_reg(cs, R_028B6C_VGT_TF_PARAM, tf_param);
}
static void evergreen_emit_gs_rings(struct r600_context *rctx, struct r600_atom *a)
@@ -2266,7 +2424,7 @@ static void cayman_init_atom_start_cs(struct r600_context *rctx)
struct r600_command_buffer *cb = &rctx->start_cs_cmd;
int tmp, i;
- r600_init_command_buffer(cb, 320);
+ r600_init_command_buffer(cb, 342);
/* This must be first. */
r600_store_value(cb, PKT3(PKT3_CONTEXT_CONTROL, 1, 0));
@@ -2283,6 +2441,12 @@ static void cayman_init_atom_start_cs(struct r600_context *rctx)
r600_store_config_reg(cb, R_009100_SPI_CONFIG_CNTL, 0);
r600_store_config_reg(cb, R_00913C_SPI_CONFIG_CNTL_1, S_00913C_VTX_DONE_DELAY(4));
+ /* remove LS/HS from one SIMD for hw workaround */
+ r600_store_config_reg_seq(cb, R_008E20_SQ_STATIC_THREAD_MGMT1, 3);
+ r600_store_value(cb, 0xffffffff);
+ r600_store_value(cb, 0xffffffff);
+ r600_store_value(cb, 0xfffffffe);
+
r600_store_context_reg_seq(cb, R_028900_SQ_ESGS_RING_ITEMSIZE, 6);
r600_store_value(cb, 0); /* R_028900_SQ_ESGS_RING_ITEMSIZE */
r600_store_value(cb, 0); /* R_028904_SQ_GSVS_RING_ITEMSIZE */
@@ -2300,9 +2464,9 @@ static void cayman_init_atom_start_cs(struct r600_context *rctx)
r600_store_context_reg_seq(cb, R_028A10_VGT_OUTPUT_PATH_CNTL, 13);
r600_store_value(cb, 0); /* R_028A10_VGT_OUTPUT_PATH_CNTL */
r600_store_value(cb, 0); /* R_028A14_VGT_HOS_CNTL */
- r600_store_value(cb, 0); /* R_028A18_VGT_HOS_MAX_TESS_LEVEL */
- r600_store_value(cb, 0); /* R_028A1C_VGT_HOS_MIN_TESS_LEVEL */
- r600_store_value(cb, 0); /* R_028A20_VGT_HOS_REUSE_DEPTH */
+ r600_store_value(cb, fui(64)); /* R_028A18_VGT_HOS_MAX_TESS_LEVEL */
+ r600_store_value(cb, fui(0)); /* R_028A1C_VGT_HOS_MIN_TESS_LEVEL */
+ r600_store_value(cb, 16); /* R_028A20_VGT_HOS_REUSE_DEPTH */
r600_store_value(cb, 0); /* R_028A24_VGT_GROUP_PRIM_TYPE */
r600_store_value(cb, 0); /* R_028A28_VGT_GROUP_FIRST_DECR */
r600_store_value(cb, 0); /* R_028A2C_VGT_GROUP_DECR */
@@ -2324,8 +2488,8 @@ static void cayman_init_atom_start_cs(struct r600_context *rctx)
r600_store_value(cb, 0x76543210); /* CM_R_028BD4_PA_SC_CENTROID_PRIORITY_0 */
r600_store_value(cb, 0xfedcba98); /* CM_R_028BD8_PA_SC_CENTROID_PRIORITY_1 */
- r600_store_context_reg_seq(cb, CM_R_0288E8_SQ_LDS_ALLOC, 2);
- r600_store_value(cb, 0); /* CM_R_0288E8_SQ_LDS_ALLOC */
+ r600_store_context_reg_seq(cb, R_0288E8_SQ_LDS_ALLOC, 2);
+ r600_store_value(cb, 0); /* R_0288E8_SQ_LDS_ALLOC */
r600_store_value(cb, 0); /* R_0288EC_SQ_LDS_ALLOC_PS */
r600_store_context_reg(cb, R_0288F0_SQ_VTX_SEMANTIC_CLEAR, ~0);
@@ -2375,6 +2539,9 @@ static void cayman_init_atom_start_cs(struct r600_context *rctx)
r600_store_context_reg(cb, R_028864_SQ_PGM_RESOURCES_2_VS, S_028864_SINGLE_ROUND(V_SQ_ROUND_NEAREST_EVEN));
r600_store_context_reg(cb, R_02887C_SQ_PGM_RESOURCES_2_GS, S_028848_SINGLE_ROUND(V_SQ_ROUND_NEAREST_EVEN));
r600_store_context_reg(cb, R_028894_SQ_PGM_RESOURCES_2_ES, S_028848_SINGLE_ROUND(V_SQ_ROUND_NEAREST_EVEN));
+ r600_store_context_reg(cb, R_0288C0_SQ_PGM_RESOURCES_2_HS, S_028848_SINGLE_ROUND(V_SQ_ROUND_NEAREST_EVEN));
+ r600_store_context_reg(cb, R_0288D8_SQ_PGM_RESOURCES_2_LS, S_028848_SINGLE_ROUND(V_SQ_ROUND_NEAREST_EVEN));
+
r600_store_context_reg(cb, R_0288A8_SQ_PGM_RESOURCES_FS, 0);
/* to avoid GPU doing any preloading of constant from random address */
@@ -2408,17 +2575,22 @@ static void cayman_init_atom_start_cs(struct r600_context *rctx)
r600_store_context_reg_seq(cb, R_0286E4_SPI_PS_IN_CONTROL_2, 2);
r600_store_value(cb, 0); /* R_0286E4_SPI_PS_IN_CONTROL_2 */
r600_store_value(cb, 0); /* R_0286E8_SPI_COMPUTE_INPUT_CNTL */
- r600_store_context_reg(cb, R_028B54_VGT_SHADER_STAGES_EN, 0);
+ r600_store_context_reg_seq(cb, R_028B54_VGT_SHADER_STAGES_EN, 2);
+ r600_store_value(cb, 0); /* R028B54_VGT_SHADER_STAGES_EN */
+ r600_store_value(cb, 0); /* R028B58_VGT_LS_HS_CONFIG */
+ r600_store_context_reg(cb, R_028B6C_VGT_TF_PARAM, 0);
eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0, 0x01000FFF);
eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF);
eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (64 * 4), 0x01000FFF);
+ eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (96 * 4), 0x01000FFF);
+ eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (128 * 4), 0x01000FFF);
}
-void evergreen_init_common_regs(struct r600_command_buffer *cb,
- enum chip_class ctx_chip_class,
- enum radeon_family ctx_family,
- int ctx_drm_minor)
+void evergreen_init_common_regs(struct r600_context *rctx, struct r600_command_buffer *cb,
+ enum chip_class ctx_chip_class,
+ enum radeon_family ctx_family,
+ int ctx_drm_minor)
{
int ps_prio;
int vs_prio;
@@ -2429,31 +2601,23 @@ void evergreen_init_common_regs(struct r600_command_buffer *cb,
int cs_prio;
int ls_prio;
- int num_ps_gprs;
- int num_vs_gprs;
- int num_gs_gprs;
- int num_es_gprs;
- int num_hs_gprs;
- int num_ls_gprs;
- int num_temp_gprs;
-
unsigned tmp;
ps_prio = 0;
vs_prio = 1;
gs_prio = 2;
es_prio = 3;
- hs_prio = 0;
- ls_prio = 0;
+ hs_prio = 3;
+ ls_prio = 3;
cs_prio = 0;
- num_ps_gprs = 93;
- num_vs_gprs = 46;
- num_temp_gprs = 4;
- num_gs_gprs = 31;
- num_es_gprs = 31;
- num_hs_gprs = 23;
- num_ls_gprs = 23;
+ rctx->default_gprs[R600_HW_STAGE_PS] = 93;
+ rctx->default_gprs[R600_HW_STAGE_VS] = 46;
+ rctx->r6xx_num_clause_temp_gprs = 4;
+ rctx->default_gprs[R600_HW_STAGE_GS] = 31;
+ rctx->default_gprs[R600_HW_STAGE_ES] = 31;
+ rctx->default_gprs[EG_HW_STAGE_HS] = 23;
+ rctx->default_gprs[EG_HW_STAGE_LS] = 23;
tmp = 0;
switch (ctx_family) {
@@ -2476,40 +2640,12 @@ void evergreen_init_common_regs(struct r600_command_buffer *cb,
tmp |= S_008C00_GS_PRIO(gs_prio);
tmp |= S_008C00_ES_PRIO(es_prio);
- /* enable dynamic GPR resource management */
- if (ctx_drm_minor >= 7) {
- r600_store_config_reg_seq(cb, R_008C00_SQ_CONFIG, 2);
- r600_store_value(cb, tmp); /* R_008C00_SQ_CONFIG */
- /* always set temp clauses */
- r600_store_value(cb, S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); /* R_008C04_SQ_GPR_RESOURCE_MGMT_1 */
- r600_store_config_reg_seq(cb, R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, 2);
- r600_store_value(cb, 0); /* R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1 */
- r600_store_value(cb, 0); /* R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2 */
- r600_store_config_reg(cb, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, (1 << 8));
- r600_store_context_reg(cb, R_028838_SQ_DYN_GPR_RESOURCE_LIMIT_1,
- S_028838_PS_GPRS(0x1e) |
- S_028838_VS_GPRS(0x1e) |
- S_028838_GS_GPRS(0x1e) |
- S_028838_ES_GPRS(0x1e) |
- S_028838_HS_GPRS(0x1e) |
- S_028838_LS_GPRS(0x1e)); /* workaround for hw issues with dyn gpr - must set all limits to 240 instead of 0, 0x1e == 240 / 8*/
- } else {
- r600_store_config_reg_seq(cb, R_008C00_SQ_CONFIG, 4);
- r600_store_value(cb, tmp); /* R_008C00_SQ_CONFIG */
+ r600_store_config_reg_seq(cb, R_008C00_SQ_CONFIG, 1);
+ r600_store_value(cb, tmp); /* R_008C00_SQ_CONFIG */
- tmp = S_008C04_NUM_PS_GPRS(num_ps_gprs);
- tmp |= S_008C04_NUM_VS_GPRS(num_vs_gprs);
- tmp |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs);
- r600_store_value(cb, tmp); /* R_008C04_SQ_GPR_RESOURCE_MGMT_1 */
-
- tmp = S_008C08_NUM_GS_GPRS(num_gs_gprs);
- tmp |= S_008C08_NUM_ES_GPRS(num_es_gprs);
- r600_store_value(cb, tmp); /* R_008C08_SQ_GPR_RESOURCE_MGMT_2 */
-
- tmp = S_008C0C_NUM_HS_GPRS(num_hs_gprs);
- tmp |= S_008C0C_NUM_HS_GPRS(num_ls_gprs);
- r600_store_value(cb, tmp); /* R_008C0C_SQ_GPR_RESOURCE_MGMT_3 */
- }
+ r600_store_config_reg_seq(cb, R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, 2);
+ r600_store_value(cb, 0); /* R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1 */
+ r600_store_value(cb, 0); /* R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2 */
/* The cs checker requires this register to be set. */
r600_store_context_reg(cb, R_028800_DB_DEPTH_CONTROL, 0);
@@ -2545,7 +2681,7 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
return;
}
- r600_init_command_buffer(cb, 320);
+ r600_init_command_buffer(cb, 342);
/* This must be first. */
r600_store_value(cb, PKT3(PKT3_CONTEXT_CONTROL, 1, 0));
@@ -2556,7 +2692,7 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
r600_store_value(cb, PKT3(PKT3_EVENT_WRITE, 0, 0));
r600_store_value(cb, EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4));
- evergreen_init_common_regs(cb, rctx->b.chip_class,
+ evergreen_init_common_regs(rctx, cb, rctx->b.chip_class,
rctx->b.family, rctx->screen->b.info.drm_minor);
family = rctx->b.family;
@@ -2638,8 +2774,8 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
num_vs_threads = 25;
num_gs_threads = 25;
num_es_threads = 25;
- num_hs_threads = 25;
- num_ls_threads = 25;
+ num_hs_threads = 16;
+ num_ls_threads = 16;
num_ps_stack_entries = 42;
num_vs_stack_entries = 42;
num_gs_stack_entries = 42;
@@ -2652,8 +2788,8 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
num_vs_threads = 25;
num_gs_threads = 25;
num_es_threads = 25;
- num_hs_threads = 25;
- num_ls_threads = 25;
+ num_hs_threads = 16;
+ num_ls_threads = 16;
num_ps_stack_entries = 85;
num_vs_stack_entries = 85;
num_gs_stack_entries = 85;
@@ -2690,7 +2826,7 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
num_ls_stack_entries = 42;
break;
case CHIP_CAICOS:
- num_ps_threads = 128;
+ num_ps_threads = 96;
num_vs_threads = 10;
num_gs_threads = 10;
num_es_threads = 10;
@@ -2732,6 +2868,12 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
r600_store_config_reg(cb, R_008E2C_SQ_LDS_RESOURCE_MGMT,
S_008E2C_NUM_PS_LDS(0x1000) | S_008E2C_NUM_LS_LDS(0x1000));
+ /* remove LS/HS from one SIMD for hw workaround */
+ r600_store_config_reg_seq(cb, R_008E20_SQ_STATIC_THREAD_MGMT1, 3);
+ r600_store_value(cb, 0xffffffff);
+ r600_store_value(cb, 0xffffffff);
+ r600_store_value(cb, 0xfffffffe);
+
r600_store_config_reg(cb, R_009100_SPI_CONFIG_CNTL, 0);
r600_store_config_reg(cb, R_00913C_SPI_CONFIG_CNTL_1, S_00913C_VTX_DONE_DELAY(4));
@@ -2752,9 +2894,9 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
r600_store_context_reg_seq(cb, R_028A10_VGT_OUTPUT_PATH_CNTL, 13);
r600_store_value(cb, 0); /* R_028A10_VGT_OUTPUT_PATH_CNTL */
r600_store_value(cb, 0); /* R_028A14_VGT_HOS_CNTL */
- r600_store_value(cb, 0); /* R_028A18_VGT_HOS_MAX_TESS_LEVEL */
- r600_store_value(cb, 0); /* R_028A1C_VGT_HOS_MIN_TESS_LEVEL */
- r600_store_value(cb, 0); /* R_028A20_VGT_HOS_REUSE_DEPTH */
+ r600_store_value(cb, fui(64)); /* R_028A18_VGT_HOS_MAX_TESS_LEVEL */
+ r600_store_value(cb, fui(1.0)); /* R_028A1C_VGT_HOS_MIN_TESS_LEVEL */
+ r600_store_value(cb, 16); /* R_028A20_VGT_HOS_REUSE_DEPTH */
r600_store_value(cb, 0); /* R_028A24_VGT_GROUP_PRIM_TYPE */
r600_store_value(cb, 0); /* R_028A28_VGT_GROUP_FIRST_DECR */
r600_store_value(cb, 0); /* R_028A2C_VGT_GROUP_DECR */
@@ -2817,6 +2959,8 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
r600_store_context_reg(cb, R_02887C_SQ_PGM_RESOURCES_2_GS, S_028848_SINGLE_ROUND(V_SQ_ROUND_NEAREST_EVEN));
r600_store_context_reg(cb, R_028894_SQ_PGM_RESOURCES_2_ES, S_028848_SINGLE_ROUND(V_SQ_ROUND_NEAREST_EVEN));
r600_store_context_reg(cb, R_0288A8_SQ_PGM_RESOURCES_FS, 0);
+ r600_store_context_reg(cb, R_0288C0_SQ_PGM_RESOURCES_2_HS, S_028848_SINGLE_ROUND(V_SQ_ROUND_NEAREST_EVEN));
+ r600_store_context_reg(cb, R_0288D8_SQ_PGM_RESOURCES_2_LS, S_028848_SINGLE_ROUND(V_SQ_ROUND_NEAREST_EVEN));
/* to avoid GPU doing any preloading of constant from random address */
r600_store_context_reg_seq(cb, R_028140_ALU_CONST_BUFFER_SIZE_PS_0, 16);
@@ -2851,12 +2995,32 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
r600_store_context_reg_seq(cb, R_0286E4_SPI_PS_IN_CONTROL_2, 2);
r600_store_value(cb, 0); /* R_0286E4_SPI_PS_IN_CONTROL_2 */
r600_store_value(cb, 0); /* R_0286E8_SPI_COMPUTE_INPUT_CNTL */
- r600_store_context_reg(cb, R_0288EC_SQ_LDS_ALLOC_PS, 0);
- r600_store_context_reg(cb, R_028B54_VGT_SHADER_STAGES_EN, 0);
+
+ r600_store_context_reg_seq(cb, R_0288E8_SQ_LDS_ALLOC, 2);
+ r600_store_value(cb, 0); /* R_0288E8_SQ_LDS_ALLOC */
+ r600_store_value(cb, 0); /* R_0288EC_SQ_LDS_ALLOC_PS */
+
+ if (rctx->b.family == CHIP_CAICOS) {
+ r600_store_context_reg_seq(cb, R_028B54_VGT_SHADER_STAGES_EN, 2);
+ r600_store_value(cb, 0); /* R028B54_VGT_SHADER_STAGES_EN */
+ r600_store_value(cb, 0); /* R028B58_VGT_LS_HS_CONFIG */
+ r600_store_context_reg(cb, R_028B6C_VGT_TF_PARAM, 0);
+ } else {
+ r600_store_context_reg_seq(cb, R_028B54_VGT_SHADER_STAGES_EN, 7);
+ r600_store_value(cb, 0); /* R028B54_VGT_SHADER_STAGES_EN */
+ r600_store_value(cb, 0); /* R028B58_VGT_LS_HS_CONFIG */
+ r600_store_value(cb, 0); /* R028B5C_VGT_LS_SIZE */
+ r600_store_value(cb, 0); /* R028B60_VGT_HS_SIZE */
+ r600_store_value(cb, 0); /* R028B64_VGT_LS_HS_ALLOC */
+ r600_store_value(cb, 0); /* R028B68_VGT_HS_PATCH_CONST */
+ r600_store_value(cb, 0); /* R028B68_VGT_TF_PARAM */
+ }
eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0, 0x01000FFF);
eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF);
eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (64 * 4), 0x01000FFF);
+ eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (96 * 4), 0x01000FFF);
+ eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (128 * 4), 0x01000FFF);
}
void evergreen_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
@@ -3071,7 +3235,6 @@ void evergreen_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader
/* VGT_GS_MODE is written by evergreen_emit_shader_stages */
- r600_store_context_reg(cb, R_028AB8_VGT_VTX_CNT_EN, 1);
r600_store_context_reg(cb, R_028B38_VGT_GS_MAX_VERT_OUT,
S_028B38_MAX_VERT_OUT(shader->selector->gs_max_out_vertices));
@@ -3177,6 +3340,31 @@ void evergreen_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader
S_02881C_USE_VTX_RENDER_TARGET_INDX(rshader->vs_out_layer);
}
+void evergreen_update_hs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
+{
+ struct r600_command_buffer *cb = &shader->command_buffer;
+ struct r600_shader *rshader = &shader->shader;
+
+ r600_init_command_buffer(cb, 32);
+ r600_store_context_reg(cb, R_0288BC_SQ_PGM_RESOURCES_HS,
+ S_0288BC_NUM_GPRS(rshader->bc.ngpr) |
+ S_0288BC_STACK_SIZE(rshader->bc.nstack));
+ r600_store_context_reg(cb, R_0288B8_SQ_PGM_START_HS,
+ shader->bo->gpu_address >> 8);
+}
+
+void evergreen_update_ls_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
+{
+ struct r600_command_buffer *cb = &shader->command_buffer;
+ struct r600_shader *rshader = &shader->shader;
+
+ r600_init_command_buffer(cb, 32);
+ r600_store_context_reg(cb, R_0288D4_SQ_PGM_RESOURCES_LS,
+ S_0288D4_NUM_GPRS(rshader->bc.ngpr) |
+ S_0288D4_STACK_SIZE(rshader->bc.nstack));
+ r600_store_context_reg(cb, R_0288D0_SQ_PGM_START_LS,
+ shader->bo->gpu_address >> 8);
+}
void *evergreen_create_resolve_blend(struct r600_context *rctx)
{
struct pipe_blend_state blend;
@@ -3484,10 +3672,21 @@ fallback:
src, src_level, src_box);
}
+static void evergreen_set_tess_state(struct pipe_context *ctx,
+ const float default_outer_level[4],
+ const float default_inner_level[2])
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+
+ memcpy(rctx->tess_state, default_outer_level, sizeof(float) * 4);
+ memcpy(rctx->tess_state+4, default_inner_level, sizeof(float) * 2);
+ rctx->tess_state_dirty = true;
+}
+
void evergreen_init_state_functions(struct r600_context *rctx)
{
unsigned id = 1;
-
+ unsigned i;
/* !!!
* To avoid GPU lockup registers must be emited in a specific order
* (no kidding ...). The order below is important and have been
@@ -3497,18 +3696,26 @@ void evergreen_init_state_functions(struct r600_context *rctx)
* or piglit regression).
* !!!
*/
-
+ if (rctx->b.chip_class == EVERGREEN) {
+ r600_init_atom(rctx, &rctx->config_state.atom, id++, evergreen_emit_config_state, 11);
+ if (rctx->screen->b.info.drm_minor >= 7)
+ rctx->config_state.dyn_gpr_enabled = true;
+ }
r600_init_atom(rctx, &rctx->framebuffer.atom, id++, evergreen_emit_framebuffer_state, 0);
/* shader const */
r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX].atom, id++, evergreen_emit_vs_constant_buffers, 0);
r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_GEOMETRY].atom, id++, evergreen_emit_gs_constant_buffers, 0);
r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_FRAGMENT].atom, id++, evergreen_emit_ps_constant_buffers, 0);
+ r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_TESS_CTRL].atom, id++, evergreen_emit_tcs_constant_buffers, 0);
+ r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_TESS_EVAL].atom, id++, evergreen_emit_tes_constant_buffers, 0);
r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_COMPUTE].atom, id++, evergreen_emit_cs_constant_buffers, 0);
/* shader program */
r600_init_atom(rctx, &rctx->cs_shader_state.atom, id++, evergreen_emit_cs_shader, 0);
/* sampler */
r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].states.atom, id++, evergreen_emit_vs_sampler_states, 0);
r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].states.atom, id++, evergreen_emit_gs_sampler_states, 0);
+ r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_TESS_CTRL].states.atom, id++, evergreen_emit_tcs_sampler_states, 0);
+ r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_TESS_EVAL].states.atom, id++, evergreen_emit_tes_sampler_states, 0);
r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].states.atom, id++, evergreen_emit_ps_sampler_states, 0);
r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_COMPUTE].states.atom, id++, evergreen_emit_cs_sampler_states, 0);
/* resources */
@@ -3516,6 +3723,8 @@ void evergreen_init_state_functions(struct r600_context *rctx)
r600_init_atom(rctx, &rctx->cs_vertex_buffer_state.atom, id++, evergreen_cs_emit_vertex_buffers, 0);
r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views.atom, id++, evergreen_emit_vs_sampler_views, 0);
r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].views.atom, id++, evergreen_emit_gs_sampler_views, 0);
+ r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_TESS_CTRL].views.atom, id++, evergreen_emit_tcs_sampler_views, 0);
+ r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_TESS_EVAL].views.atom, id++, evergreen_emit_tes_sampler_views, 0);
r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].views.atom, id++, evergreen_emit_ps_sampler_views, 0);
r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_COMPUTE].views.atom, id++, evergreen_emit_cs_sampler_views, 0);
@@ -3546,11 +3755,9 @@ void evergreen_init_state_functions(struct r600_context *rctx)
r600_add_atom(rctx, &rctx->b.render_cond_atom, id++);
r600_add_atom(rctx, &rctx->b.streamout.begin_atom, id++);
r600_add_atom(rctx, &rctx->b.streamout.enable_atom, id++);
- r600_init_atom(rctx, &rctx->vertex_shader.atom, id++, r600_emit_shader, 23);
- r600_init_atom(rctx, &rctx->pixel_shader.atom, id++, r600_emit_shader, 0);
- r600_init_atom(rctx, &rctx->geometry_shader.atom, id++, r600_emit_shader, 0);
- r600_init_atom(rctx, &rctx->export_shader.atom, id++, r600_emit_shader, 0);
- r600_init_atom(rctx, &rctx->shader_stages.atom, id++, evergreen_emit_shader_stages, 6);
+ for (i = 0; i < EG_NUM_HW_STAGES; i++)
+ r600_init_atom(rctx, &rctx->hw_shader_stages[i].atom, id++, r600_emit_shader, 0);
+ r600_init_atom(rctx, &rctx->shader_stages.atom, id++, evergreen_emit_shader_stages, 15);
r600_init_atom(rctx, &rctx->gs_rings.atom, id++, evergreen_emit_gs_rings, 26);
rctx->b.b.create_blend_state = evergreen_create_blend_state;
@@ -3562,7 +3769,7 @@ void evergreen_init_state_functions(struct r600_context *rctx)
rctx->b.b.set_polygon_stipple = evergreen_set_polygon_stipple;
rctx->b.b.set_min_samples = evergreen_set_min_samples;
rctx->b.b.set_scissor_states = evergreen_set_scissor_states;
-
+ rctx->b.b.set_tess_state = evergreen_set_tess_state;
if (rctx->b.chip_class == EVERGREEN)
rctx->b.b.get_sample_position = evergreen_get_sample_position;
else
@@ -3571,3 +3778,272 @@ void evergreen_init_state_functions(struct r600_context *rctx)
evergreen_init_compute_state_functions(rctx);
}
+
+/**
+ * This calculates the LDS size for tessellation shaders (VS, TCS, TES).
+ *
+ * The information about LDS and other non-compile-time parameters is then
+ * written to the const buffer.
+
+ * const buffer contains -
+ * uint32_t input_patch_size
+ * uint32_t input_vertex_size
+ * uint32_t num_tcs_input_cp
+ * uint32_t num_tcs_output_cp;
+ * uint32_t output_patch_size
+ * uint32_t output_vertex_size
+ * uint32_t output_patch0_offset
+ * uint32_t perpatch_output_offset
+ * and the same constbuf is bound to LS/HS/VS(ES).
+ */
+void evergreen_setup_tess_constants(struct r600_context *rctx, const struct pipe_draw_info *info, unsigned *num_patches)
+{
+ struct pipe_constant_buffer constbuf = {0};
+ struct r600_pipe_shader_selector *tcs = rctx->tcs_shader ? rctx->tcs_shader : rctx->tes_shader;
+ struct r600_pipe_shader_selector *ls = rctx->vs_shader;
+ unsigned num_tcs_input_cp = info->vertices_per_patch;
+ unsigned num_tcs_outputs;
+ unsigned num_tcs_output_cp;
+ unsigned num_tcs_patch_outputs;
+ unsigned num_tcs_inputs;
+ unsigned input_vertex_size, output_vertex_size;
+ unsigned input_patch_size, pervertex_output_patch_size, output_patch_size;
+ unsigned output_patch0_offset, perpatch_output_offset, lds_size;
+ uint32_t values[16];
+ unsigned num_waves;
+ unsigned num_pipes = rctx->screen->b.info.r600_max_pipes;
+ unsigned wave_divisor = (16 * num_pipes);
+
+ *num_patches = 1;
+
+ if (!rctx->tes_shader) {
+ rctx->lds_alloc = 0;
+ rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_VERTEX,
+ R600_LDS_INFO_CONST_BUFFER, NULL);
+ rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_CTRL,
+ R600_LDS_INFO_CONST_BUFFER, NULL);
+ rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_EVAL,
+ R600_LDS_INFO_CONST_BUFFER, NULL);
+ return;
+ }
+
+ if (rctx->lds_alloc != 0 &&
+ rctx->last_ls == ls &&
+ !rctx->tess_state_dirty &&
+ rctx->last_num_tcs_input_cp == num_tcs_input_cp &&
+ rctx->last_tcs == tcs)
+ return;
+
+ num_tcs_inputs = util_last_bit64(ls->lds_outputs_written_mask);
+
+ if (rctx->tcs_shader) {
+ num_tcs_outputs = util_last_bit64(tcs->lds_outputs_written_mask);
+ num_tcs_output_cp = tcs->info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT];
+ num_tcs_patch_outputs = util_last_bit64(tcs->lds_patch_outputs_written_mask);
+ } else {
+ num_tcs_outputs = num_tcs_inputs;
+ num_tcs_output_cp = num_tcs_input_cp;
+ num_tcs_patch_outputs = 2; /* TESSINNER + TESSOUTER */
+ }
+
+ /* size in bytes */
+ input_vertex_size = num_tcs_inputs * 16;
+ output_vertex_size = num_tcs_outputs * 16;
+
+ input_patch_size = num_tcs_input_cp * input_vertex_size;
+
+ pervertex_output_patch_size = num_tcs_output_cp * output_vertex_size;
+ output_patch_size = pervertex_output_patch_size + num_tcs_patch_outputs * 16;
+
+ output_patch0_offset = rctx->tcs_shader ? input_patch_size * *num_patches : 0;
+ perpatch_output_offset = output_patch0_offset + pervertex_output_patch_size;
+
+ lds_size = output_patch0_offset + output_patch_size * *num_patches;
+
+ values[0] = input_patch_size;
+ values[1] = input_vertex_size;
+ values[2] = num_tcs_input_cp;
+ values[3] = num_tcs_output_cp;
+
+ values[4] = output_patch_size;
+ values[5] = output_vertex_size;
+ values[6] = output_patch0_offset;
+ values[7] = perpatch_output_offset;
+
+ /* docs say HS_NUM_WAVES - CEIL((LS_HS_CONFIG.NUM_PATCHES *
+ LS_HS_CONFIG.HS_NUM_OUTPUT_CP) / (NUM_GOOD_PIPES * 16)) */
+ num_waves = ceilf((float)(*num_patches * num_tcs_output_cp) / (float)wave_divisor);
+
+ rctx->lds_alloc = (lds_size | (num_waves << 14));
+
+ memcpy(&values[8], rctx->tess_state, 6 * sizeof(float));
+ values[14] = 0;
+ values[15] = 0;
+
+ rctx->tess_state_dirty = false;
+ rctx->last_ls = ls;
+ rctx->last_tcs = tcs;
+ rctx->last_num_tcs_input_cp = num_tcs_input_cp;
+
+ constbuf.user_buffer = values;
+ constbuf.buffer_size = 16 * 4;
+
+ rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_VERTEX,
+ R600_LDS_INFO_CONST_BUFFER, &constbuf);
+ rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_CTRL,
+ R600_LDS_INFO_CONST_BUFFER, &constbuf);
+ rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_EVAL,
+ R600_LDS_INFO_CONST_BUFFER, &constbuf);
+ pipe_resource_reference(&constbuf.buffer, NULL);
+}
+
+uint32_t evergreen_get_ls_hs_config(struct r600_context *rctx,
+ const struct pipe_draw_info *info,
+ unsigned num_patches)
+{
+ unsigned num_output_cp;
+
+ if (!rctx->tes_shader)
+ return 0;
+
+ num_output_cp = rctx->tcs_shader ?
+ rctx->tcs_shader->info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT] :
+ info->vertices_per_patch;
+
+ return S_028B58_NUM_PATCHES(num_patches) |
+ S_028B58_HS_NUM_INPUT_CP(info->vertices_per_patch) |
+ S_028B58_HS_NUM_OUTPUT_CP(num_output_cp);
+}
+
+void evergreen_set_ls_hs_config(struct r600_context *rctx,
+ struct radeon_winsys_cs *cs,
+ uint32_t ls_hs_config)
+{
+ radeon_set_context_reg(cs, R_028B58_VGT_LS_HS_CONFIG, ls_hs_config);
+}
+
+void evergreen_set_lds_alloc(struct r600_context *rctx,
+ struct radeon_winsys_cs *cs,
+ uint32_t lds_alloc)
+{
+ radeon_set_context_reg(cs, R_0288E8_SQ_LDS_ALLOC, lds_alloc);
+}
+
+/* on evergreen if you are running tessellation you need to disable dynamic
+ GPRs to workaround a hardware bug.*/
+bool evergreen_adjust_gprs(struct r600_context *rctx)
+{
+ unsigned num_gprs[EG_NUM_HW_STAGES];
+ unsigned def_gprs[EG_NUM_HW_STAGES];
+ unsigned cur_gprs[EG_NUM_HW_STAGES];
+ unsigned new_gprs[EG_NUM_HW_STAGES];
+ unsigned def_num_clause_temp_gprs = rctx->r6xx_num_clause_temp_gprs;
+ unsigned max_gprs;
+ unsigned i;
+ unsigned total_gprs;
+ unsigned tmp[3];
+ bool rework = false, set_default = false, set_dirty = false;
+ max_gprs = 0;
+ for (i = 0; i < EG_NUM_HW_STAGES; i++) {
+ def_gprs[i] = rctx->default_gprs[i];
+ max_gprs += def_gprs[i];
+ }
+ max_gprs += def_num_clause_temp_gprs * 2;
+
+ /* if we have no TESS and dyn gpr is enabled then do nothing. */
+ if (!rctx->hw_shader_stages[EG_HW_STAGE_HS].shader || rctx->screen->b.info.drm_minor < 7) {
+ if (rctx->config_state.dyn_gpr_enabled)
+ return true;
+
+ /* transition back to dyn gpr enabled state */
+ rctx->config_state.dyn_gpr_enabled = true;
+ r600_mark_atom_dirty(rctx, &rctx->config_state.atom);
+ rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE;
+ return true;
+ }
+
+
+ /* gather required shader gprs */
+ for (i = 0; i < EG_NUM_HW_STAGES; i++) {
+ if (rctx->hw_shader_stages[i].shader)
+ num_gprs[i] = rctx->hw_shader_stages[i].shader->shader.bc.ngpr;
+ else
+ num_gprs[i] = 0;
+ }
+
+ cur_gprs[R600_HW_STAGE_PS] = G_008C04_NUM_PS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_1);
+ cur_gprs[R600_HW_STAGE_VS] = G_008C04_NUM_VS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_1);
+ cur_gprs[R600_HW_STAGE_GS] = G_008C08_NUM_GS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_2);
+ cur_gprs[R600_HW_STAGE_ES] = G_008C08_NUM_ES_GPRS(rctx->config_state.sq_gpr_resource_mgmt_2);
+ cur_gprs[EG_HW_STAGE_LS] = G_008C0C_NUM_LS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_3);
+ cur_gprs[EG_HW_STAGE_HS] = G_008C0C_NUM_HS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_3);
+
+ total_gprs = 0;
+ for (i = 0; i < EG_NUM_HW_STAGES; i++) {
+ new_gprs[i] = num_gprs[i];
+ total_gprs += num_gprs[i];
+ }
+
+ if (total_gprs > (max_gprs - (2 * def_num_clause_temp_gprs)))
+ return false;
+
+ for (i = 0; i < EG_NUM_HW_STAGES; i++) {
+ if (new_gprs[i] > cur_gprs[i]) {
+ rework = true;
+ break;
+ }
+ }
+
+ if (rctx->config_state.dyn_gpr_enabled) {
+ set_dirty = true;
+ rctx->config_state.dyn_gpr_enabled = false;
+ }
+
+ if (rework) {
+ set_default = true;
+ for (i = 0; i < EG_NUM_HW_STAGES; i++) {
+ if (new_gprs[i] > def_gprs[i])
+ set_default = false;
+ }
+
+ if (set_default) {
+ for (i = 0; i < EG_NUM_HW_STAGES; i++) {
+ new_gprs[i] = def_gprs[i];
+ }
+ } else {
+ unsigned ps_value = max_gprs;
+
+ ps_value -= (def_num_clause_temp_gprs * 2);
+ for (i = R600_HW_STAGE_VS; i < EG_NUM_HW_STAGES; i++)
+ ps_value -= new_gprs[i];
+
+ new_gprs[R600_HW_STAGE_PS] = ps_value;
+ }
+
+ tmp[0] = S_008C04_NUM_PS_GPRS(new_gprs[R600_HW_STAGE_PS]) |
+ S_008C04_NUM_VS_GPRS(new_gprs[R600_HW_STAGE_VS]) |
+ S_008C04_NUM_CLAUSE_TEMP_GPRS(def_num_clause_temp_gprs);
+
+ tmp[1] = S_008C08_NUM_ES_GPRS(new_gprs[R600_HW_STAGE_ES]) |
+ S_008C08_NUM_GS_GPRS(new_gprs[R600_HW_STAGE_GS]);
+
+ tmp[2] = S_008C0C_NUM_HS_GPRS(new_gprs[EG_HW_STAGE_HS]) |
+ S_008C0C_NUM_LS_GPRS(new_gprs[EG_HW_STAGE_LS]);
+
+ if (rctx->config_state.sq_gpr_resource_mgmt_1 != tmp[0] ||
+ rctx->config_state.sq_gpr_resource_mgmt_2 != tmp[1] ||
+ rctx->config_state.sq_gpr_resource_mgmt_3 != tmp[2]) {
+ rctx->config_state.sq_gpr_resource_mgmt_1 = tmp[0];
+ rctx->config_state.sq_gpr_resource_mgmt_2 = tmp[1];
+ rctx->config_state.sq_gpr_resource_mgmt_3 = tmp[2];
+ set_dirty = true;
+ }
+ }
+
+
+ if (set_dirty) {
+ r600_mark_atom_dirty(rctx, &rctx->config_state.atom);
+ rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE;
+ }
+ return true;
+}
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index 25237c6f650..ebe8c4a65ba 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -463,6 +463,39 @@
#define R_0286EC_SPI_COMPUTE_NUM_THREAD_X 0x0286EC
#define R_0286F0_SPI_COMPUTE_NUM_THREAD_Y 0x0286F0
#define R_0286F4_SPI_COMPUTE_NUM_THREAD_Z 0x0286F4
+#define R_028B6C_VGT_TF_PARAM 0x028B6C
+#define S_028B6C_TYPE(x) (((x) & 0x03) << 0)
+#define G_028B6C_TYPE(x) (((x) >> 0) & 0x03)
+#define C_028B6C_TYPE 0xFFFFFFFC
+#define V_028B6C_TESS_ISOLINE 0x00
+#define V_028B6C_TESS_TRIANGLE 0x01
+#define V_028B6C_TESS_QUAD 0x02
+#define S_028B6C_PARTITIONING(x) (((x) & 0x07) << 2)
+#define G_028B6C_PARTITIONING(x) (((x) >> 2) & 0x07)
+#define C_028B6C_PARTITIONING 0xFFFFFFE3
+#define V_028B6C_PART_INTEGER 0x00
+#define V_028B6C_PART_POW2 0x01
+#define V_028B6C_PART_FRAC_ODD 0x02
+#define V_028B6C_PART_FRAC_EVEN 0x03
+#define S_028B6C_TOPOLOGY(x) (((x) & 0x07) << 5)
+#define G_028B6C_TOPOLOGY(x) (((x) >> 5) & 0x07)
+#define C_028B6C_TOPOLOGY 0xFFFFFF1F
+#define V_028B6C_OUTPUT_POINT 0x00
+#define V_028B6C_OUTPUT_LINE 0x01
+#define V_028B6C_OUTPUT_TRIANGLE_CW 0x02
+#define V_028B6C_OUTPUT_TRIANGLE_CCW 0x03
+#define S_028B6C_RESERVED_REDUC_AXIS(x) (((x) & 0x1) << 8)
+#define G_028B6C_RESERVED_REDUC_AXIS(x) (((x) >> 8) & 0x1)
+#define C_028B6C_RESERVED_REDUC_AXIS 0xFFFFFEFF
+#define S_028B6C_BUFFER_ACCESS_MODE(x) (((x) & 0x1) << 9)
+#define G_028B6C_BUFFER_ACCESS_MODE(x) (((x) >> 9) & 0x1)
+#define C_028B6C_BUFFER_ACCESS_MODE 0xFFFFFDFF
+#define V_028B6C_PATCH_MAJOR 0x00
+#define V_028B6C_TF_MAJOR 0x01
+#define S_028B6C_NUM_DS_WAVES_PER_SIMD(x) (((x) & 0xf) << 10)
+#define G_028B6C_NUM_DS_WAVES_PER_SIMD(x) (((x) >> 10) & 0xF)
+#define C_028B6C_NUM_DS_WAVES_PER_SIMD 0xFFFFC3FF
+
#define R_028B74_VGT_DISPATCH_INITIATOR 0x028B74
#define R_028800_DB_DEPTH_CONTROL 0x028800
@@ -1260,6 +1293,16 @@
#define R_00A430_TD_GS_SAMPLER0_BORDER_GREEN 0x00A430
#define R_00A434_TD_GS_SAMPLER0_BORDER_BLUE 0x00A434
#define R_00A438_TD_GS_SAMPLER0_BORDER_ALPHA 0x00A438
+#define R_00A43C_TD_HS_SAMPLER0_BORDER_COLOR_INDEX 0x00A43C
+#define R_00A440_TD_HS_SAMPLER0_BORDER_COLOR_RED 0x00A440
+#define R_00A444_TD_HS_SAMPLER0_BORDER_COLOR_GREEN 0x00A444
+#define R_00A448_TD_HS_SAMPLER0_BORDER_COLOR_BLUE 0x00A448
+#define R_00A44C_TD_HS_SAMPLER0_BORDER_COLOR_ALPHA 0x00A44C
+#define R_00A450_TD_LS_SAMPLER0_BORDER_COLOR_INDEX 0x00A450
+#define R_00A454_TD_LS_SAMPLER0_BORDER_COLOR_RED 0x00A454
+#define R_00A458_TD_LS_SAMPLER0_BORDER_COLOR_GREEN 0x00A458
+#define R_00A45C_TD_LS_SAMPLER0_BORDER_COLOR_BLUE 0x00A45C
+#define R_00A460_TD_LS_SAMPLER0_BORDER_COLOR_ALPHA 0x00A460
#define R_00A464_TD_CS_SAMPLER0_BORDER_INDEX 0x00A464
#define R_00A468_TD_CS_SAMPLER0_BORDER_RED 0x00A468
#define R_00A46C_TD_CS_SAMPLER0_BORDER_GREEN 0x00A46C
@@ -1383,7 +1426,7 @@
#define V_008958_DI_PT_TRISTRIP 0x00000006
#define V_008958_DI_PT_UNUSED_0 0x00000007
#define V_008958_DI_PT_UNUSED_1 0x00000008
-#define V_008958_DI_PT_UNUSED_2 0x00000009
+#define V_008958_DI_PT_PATCH 0x00000009
#define V_008958_DI_PT_LINELIST_ADJ 0x0000000A
#define V_008958_DI_PT_LINESTRIP_ADJ 0x0000000B
#define V_008958_DI_PT_TRILIST_ADJ 0x0000000C
@@ -1585,27 +1628,24 @@
#define G_028848_ALLOW_DOUBLE_DENORM_OUT(x) (((x) >> 7) & 0x1)
#define C_028848_ALLOW_DOUBLE_DENORM_OUT 0xFFFFFF7F
-#define R_0288D4_SQ_PGM_RESOURCES_LS 0x0288d4
-#define S_0288D4_NUM_GPRS(x) (((x) & 0xFF) << 0)
-#define G_0288D4_NUM_GPRS(x) (((x) >> 0) & 0xFF)
-#define C_0288D4_NUM_GPRS 0xFFFFFF00
-#define S_0288D4_STACK_SIZE(x) (((x) & 0xFF) << 8)
-#define G_0288D4_STACK_SIZE(x) (((x) >> 8) & 0xFF)
-#define C_0288D4_STACK_SIZE 0xFFFF00FF
-#define S_0288D4_DX10_CLAMP(x) (((x) & 0x1) << 21)
-#define G_0288D4_DX10_CLAMP(x) (((x) >> 21) & 0x1)
-#define C_0288D4_DX10_CLAMP 0xFFDFFFFF
-#define S_0288D4_PRIME_CACHE_ON_DRAW(x) (((x) & 0x1) << 23)
-#define G_0288D4_PRIME_CACHE_ON_DRAW(x) (((x) >> 23) & 0x1)
-#define S_0288D4_UNCACHED_FIRST_INST(x) (((x) & 0x1) << 28)
-#define G_0288D4_UNCACHED_FIRST_INST(x) (((x) >> 28) & 0x1)
-#define C_0288D4_UNCACHED_FIRST_INST 0xEFFFFFFF
-#define S_0288D4_CLAMP_CONSTS(x) (((x) & 0x1) << 31)
-#define G_0288D4_CLAMP_CONSTS(x) (((x) >> 31) & 0x1)
-#define C_0288D4_CLAMP_CONSTS 0x7FFFFFFF
-
-#define R_0288D8_SQ_PGM_RESOURCES_LS_2 0x0288d8
+#define R_0288BC_SQ_PGM_RESOURCES_HS 0x0288BC
+#define S_0288BC_NUM_GPRS(x) (((x) & 0xFF) << 0)
+#define G_0288BC_NUM_GPRS(x) (((x) >> 0) & 0xFF)
+#define C_0288BC_NUM_GPRS 0xFFFFFF00
+#define S_0288BC_STACK_SIZE(x) (((x) & 0xFF) << 8)
+#define G_0288BC_STACK_SIZE(x) (((x) >> 8) & 0xFF)
+#define C_0288BC_STACK_SIZE 0xFFFF00FF
+#define S_0288BC_DX10_CLAMP(x) (((x) & 0x1) << 21)
+#define G_0288BC_DX10_CLAMP(x) (((x) >> 21) & 0x1)
+#define C_0288BC_DX10_CLAMP 0xFFDFFFFF
+#define S_0288BC_PRIME_CACHE_ON_DRAW(x) (((x) & 0x1) << 23)
+#define G_0288BC_PRIME_CACHE_ON_DRAW(x) (((x) >> 23) & 0x1)
+#define C_028844_PRIME_CACHE_ON_DRAW 0xFF7FFFFF
+#define S_0288BC_UNCACHED_FIRST_INST(x) (((x) & 0x1) << 28)
+#define G_0288BC_UNCACHED_FIRST_INST(x) (((x) >> 28) & 0x1)
+#define C_0288BC_UNCACHED_FIRST_INST 0xEFFFFFFF
+#define R_0288C0_SQ_PGM_RESOURCES_2_HS 0x0288c0
#define R_0288D4_SQ_PGM_RESOURCES_LS 0x0288d4
#define S_0288D4_NUM_GPRS(x) (((x) & 0xFF) << 0)
@@ -1622,12 +1662,8 @@
#define S_0288D4_UNCACHED_FIRST_INST(x) (((x) & 0x1) << 28)
#define G_0288D4_UNCACHED_FIRST_INST(x) (((x) >> 28) & 0x1)
#define C_0288D4_UNCACHED_FIRST_INST 0xEFFFFFFF
-#define S_0288D4_CLAMP_CONSTS(x) (((x) & 0x1) << 31)
-#define G_0288D4_CLAMP_CONSTS(x) (((x) >> 31) & 0x1)
-#define C_0288D4_CLAMP_CONSTS 0x7FFFFFFF
-
-#define R_0288D8_SQ_PGM_RESOURCES_LS_2 0x0288d8
+#define R_0288D8_SQ_PGM_RESOURCES_2_LS 0x0288d8
#define R_028644_SPI_PS_INPUT_CNTL_0 0x028644
#define S_028644_SEMANTIC(x) (((x) & 0xFF) << 0)
@@ -1957,6 +1993,7 @@
#define C_028818_VTX_W0_FMT 0xFFFFFBFF
#define R_028820_PA_CL_NANINF_CNTL 0x00028820
+#define R_028830_SQ_LSTMP_RING_ITEMSIZE 0x00028830
#define R_028838_SQ_DYN_GPR_RESOURCE_LIMIT_1 0x00028838
#define S_028838_PS_GPRS(x) (((x) & 0x1F) << 0)
#define S_028838_VS_GPRS(x) (((x) & 0x1F) << 5)
@@ -1976,8 +2013,10 @@
#define R_028874_SQ_PGM_START_GS 0x00028874
#define R_02888C_SQ_PGM_START_ES 0x0002888C
#define R_0288A4_SQ_PGM_START_FS 0x000288A4
-#define R_0288D0_SQ_PGM_START_LS 0x000288d0
+#define R_0288B8_SQ_PGM_START_HS 0x000288B8
+#define R_0288D0_SQ_PGM_START_LS 0x000288D0
#define R_0288A8_SQ_PGM_RESOURCES_FS 0x000288A8
+#define R_0288E8_SQ_LDS_ALLOC 0x000288E8
#define R_0288EC_SQ_LDS_ALLOC_PS 0x000288EC
#define R_028900_SQ_ESGS_RING_ITEMSIZE 0x00028900
#define R_028904_SQ_GSVS_RING_ITEMSIZE 0x00028904
@@ -1997,6 +2036,7 @@
#define R_028980_ALU_CONST_CACHE_VS_0 0x00028980
#define R_028984_ALU_CONST_CACHE_VS_1 0x00028984
#define R_0289C0_ALU_CONST_CACHE_GS_0 0x000289C0
+#define R_028F00_ALU_CONST_CACHE_HS_0 0x00028F00
#define R_028F40_ALU_CONST_CACHE_LS_0 0x00028F40
#define R_028A04_PA_SU_POINT_MINMAX 0x00028A04
#define S_028A04_MIN_SIZE(x) (((x) & 0xFFFF) << 0)
@@ -2090,6 +2130,44 @@
#define V_028B54_VS_STAGE_REAL 0x00
#define V_028B54_VS_STAGE_DS 0x01
#define V_028B54_VS_STAGE_COPY_SHADER 0x02
+#define R_028B58_VGT_LS_HS_CONFIG 0x00028B58
+#define S_028B58_NUM_PATCHES(x) (((x) & 0xFF) << 0)
+#define G_028B58_NUM_PATCHES(x) (((x) >> 0) & 0xFF)
+#define C_028B58_NUM_PATCHES 0xFFFFFF00
+#define S_028B58_HS_NUM_INPUT_CP(x) (((x) & 0x3F) << 8)
+#define G_028B58_HS_NUM_INPUT_CP(x) (((x) >> 8) & 0x3F)
+#define C_028B58_HS_NUM_INPUT_CP 0xFFFFC0FF
+#define S_028B58_HS_NUM_OUTPUT_CP(x) (((x) & 0x3F) << 14)
+#define G_028B58_HS_NUM_OUTPUT_CP(x) (((x) >> 14) & 0x3F)
+#define C_028B58_HS_NUM_OUTPUT_CP 0xFFF03FFF
+#define R_028B5C_VGT_LS_SIZE 0x00028B5C
+#define S_028B5C_SIZE(x) (((x) & 0xFF) << 0)
+#define G_028B5C_SIZE(x) (((x) >> 0) & 0xFF)
+#define C_028B5C_SIZE 0xFFFFFF00
+#define S_028B5C_PATCH_CP_SIZE(x) (((x) & 0x1FFF) << 8)
+#define G_028B5C_PATCH_CP_SIZE(x) (((x) >> 8) & 0x1FFF)
+#define C_028B5C_PATCH_CP_SIZE 0xFFE000FF
+#define R_028B60_VGT_HS_SIZE 0x00028B60
+#define S_028B60_SIZE(x) (((x) & 0xFF) << 0)
+#define G_028B60_SIZE(x) (((x) >> 0) & 0xFF)
+#define C_028B60_SIZE 0xFFFFFF00
+#define S_028B60_PATCH_CP_SIZE(x) (((x) & 0x1FFF) << 8)
+#define G_028B60_PATCH_CP_SIZE(x) (((x) >> 8) & 0x1FFF)
+#define C_028B60_PATCH_CP_SIZE 0xFFE000FF
+#define R_028B64_VGT_LS_HS_ALLOC 0x00028B64
+#define S_028B64_HS_TOTAL_OUTPUT(x) (((x) & 0x1FFF) << 0)
+#define G_028B64_HS_TOTAL_OUTPUT(x) (((x) >> 0) & 0x1FFF)
+#define C_028B64_HS_TOTAL_OUTPUT 0xFFFFE000
+#define S_028B64_LS_HS_TOTAL_OUTPUT(x) (((x) & 0x1FFF) << 13)
+#define G_028B64_LS_HS_TOTAL_OUTPUT(x) (((x) >> 13) & 0x1FFF)
+#define C_028B64_LS_HS_TOTAL_OUTPUT 0xFC001FFF
+#define R_028B68_VGT_HS_PATCH_CONST 0x00028B68
+#define S_028B68_SIZE(x) (((x) & 0x1FFF) << 0)
+#define G_028B68_SIZE(x) (((x) >> 0) & 0x1FFF)
+#define C_028B68_SIZE 0xFFFFE000
+#define S_028B68_STRIDE(x) (((x) & 0x1FFF) << 13)
+#define G_028B68_STRIDE(x) (((x) >> 13) & 0x1FFF)
+#define C_028B68_STRIDE 0xFC001FFF
#define R_028B70_DB_ALPHA_TO_MASK 0x00028B70
#define S_028B70_ALPHA_TO_MASK_ENABLE(x) (((x) & 0x1) << 0)
#define S_028B70_ALPHA_TO_MASK_OFFSET0(x) (((x) & 0x3) << 8)
@@ -2423,7 +2501,6 @@
#define CM_R_0286FC_SPI_LDS_MGMT 0x286fc
#define S_0286FC_NUM_PS_LDS(x) ((x) & 0xff)
#define S_0286FC_NUM_LS_LDS(x) ((x) & 0xff) << 8
-#define CM_R_0288E8_SQ_LDS_ALLOC 0x000288E8
#define CM_R_028804_DB_EQAA 0x00028804
#define S_028804_MAX_ANCHOR_SAMPLES(x) (((x) & 0x7) << 0)
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index ee7beee3001..77bd768356d 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -37,6 +37,11 @@
#define NUM_OF_CYCLES 3
#define NUM_OF_COMPONENTS 4
+static inline bool alu_writes(struct r600_bytecode_alu *alu)
+{
+ return alu->dst.write || alu->is_op3;
+}
+
static inline unsigned int r600_bytecode_get_num_operands(
struct r600_bytecode *bc, struct r600_bytecode_alu *alu)
{
@@ -50,12 +55,13 @@ static struct r600_bytecode_cf *r600_bytecode_cf(void)
{
struct r600_bytecode_cf *cf = CALLOC_STRUCT(r600_bytecode_cf);
- if (cf == NULL)
+ if (!cf)
return NULL;
LIST_INITHEAD(&cf->list);
LIST_INITHEAD(&cf->alu);
LIST_INITHEAD(&cf->vtx);
LIST_INITHEAD(&cf->tex);
+ LIST_INITHEAD(&cf->gds);
return cf;
}
@@ -63,7 +69,7 @@ static struct r600_bytecode_alu *r600_bytecode_alu(void)
{
struct r600_bytecode_alu *alu = CALLOC_STRUCT(r600_bytecode_alu);
- if (alu == NULL)
+ if (!alu)
return NULL;
LIST_INITHEAD(&alu->list);
return alu;
@@ -73,7 +79,7 @@ static struct r600_bytecode_vtx *r600_bytecode_vtx(void)
{
struct r600_bytecode_vtx *vtx = CALLOC_STRUCT(r600_bytecode_vtx);
- if (vtx == NULL)
+ if (!vtx)
return NULL;
LIST_INITHEAD(&vtx->list);
return vtx;
@@ -83,12 +89,22 @@ static struct r600_bytecode_tex *r600_bytecode_tex(void)
{
struct r600_bytecode_tex *tex = CALLOC_STRUCT(r600_bytecode_tex);
- if (tex == NULL)
+ if (!tex)
return NULL;
LIST_INITHEAD(&tex->list);
return tex;
}
+static struct r600_bytecode_gds *r600_bytecode_gds(void)
+{
+ struct r600_bytecode_gds *gds = CALLOC_STRUCT(r600_bytecode_gds);
+
+ if (gds == NULL)
+ return NULL;
+ LIST_INITHEAD(&gds->list);
+ return gds;
+}
+
static unsigned stack_entry_size(enum radeon_family chip) {
/* Wavefront size:
* 64: R600/RV670/RV770/Cypress/R740/Barts/Turks/Caicos/
@@ -152,7 +168,7 @@ int r600_bytecode_add_cf(struct r600_bytecode *bc)
{
struct r600_bytecode_cf *cf = r600_bytecode_cf();
- if (cf == NULL)
+ if (!cf)
return -ENOMEM;
LIST_ADDTAIL(&cf->list, &bc->cf);
if (bc->cf_last) {
@@ -221,7 +237,7 @@ int r600_bytecode_add_output(struct r600_bytecode *bc,
/* alu instructions that can ony exits once per group */
static int is_alu_once_inst(struct r600_bytecode *bc, struct r600_bytecode_alu *alu)
{
- return r600_isa_alu(alu->op)->flags & (AF_KILL | AF_PRED);
+ return r600_isa_alu(alu->op)->flags & (AF_KILL | AF_PRED) || alu->is_lds_idx_op || alu->op == ALU_OP0_GROUP_BARRIER;
}
static int is_alu_reduction_inst(struct r600_bytecode *bc, struct r600_bytecode_alu *alu)
@@ -252,6 +268,24 @@ static int alu_uses_rel(struct r600_bytecode *bc, struct r600_bytecode_alu *alu)
return 0;
}
+static int is_lds_read(int sel)
+{
+ return sel == EG_V_SQ_ALU_SRC_LDS_OQ_A_POP || sel == EG_V_SQ_ALU_SRC_LDS_OQ_B_POP;
+}
+
+static int alu_uses_lds(struct r600_bytecode *bc, struct r600_bytecode_alu *alu)
+{
+ unsigned num_src = r600_bytecode_get_num_operands(bc, alu);
+ unsigned src;
+
+ for (src = 0; src < num_src; ++src) {
+ if (is_lds_read(alu->src[src].sel)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int is_alu_64bit_inst(struct r600_bytecode *bc, struct r600_bytecode_alu *alu)
{
const struct alu_op_info *op = r600_isa_alu(alu->op);
@@ -581,7 +615,7 @@ static int replace_gpr_with_pv_ps(struct r600_bytecode *bc,
return r;
for (i = 0; i < max_slots; ++i) {
- if (prev[i] && (prev[i]->dst.write || prev[i]->is_op3) && !prev[i]->dst.rel) {
+ if (prev[i] && alu_writes(prev[i]) && !prev[i]->dst.rel) {
if (is_alu_64bit_inst(bc, prev[i])) {
gpr[i] = -1;
@@ -600,7 +634,7 @@ static int replace_gpr_with_pv_ps(struct r600_bytecode *bc,
for (i = 0; i < max_slots; ++i) {
struct r600_bytecode_alu *alu = slots[i];
- if(!alu)
+ if (!alu)
continue;
if (is_alu_64bit_inst(bc, alu))
@@ -771,6 +805,8 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu
}
have_rel = 1;
}
+ if (alu_uses_lds(bc, prev[i]))
+ return 0;
num_once_inst += is_alu_once_inst(bc, prev[i]);
}
@@ -784,13 +820,13 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu
} else if (prev[i] && slots[i]) {
if (max_slots == 5 && result[4] == NULL && prev[4] == NULL && slots[4] == NULL) {
/* Trans unit is still free try to use it. */
- if (is_alu_any_unit_inst(bc, slots[i])) {
+ if (is_alu_any_unit_inst(bc, slots[i]) && !alu_uses_lds(bc, slots[i])) {
result[i] = prev[i];
result[4] = slots[i];
} else if (is_alu_any_unit_inst(bc, prev[i])) {
if (slots[i]->dst.sel == prev[i]->dst.sel &&
- (slots[i]->dst.write == 1 || slots[i]->is_op3) &&
- (prev[i]->dst.write == 1 || prev[i]->is_op3))
+ alu_writes(slots[i]) &&
+ alu_writes(prev[i]))
return 0;
result[i] = slots[i];
@@ -805,8 +841,8 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu
if (max_slots == 5 && slots[i] && prev[4] &&
slots[i]->dst.sel == prev[4]->dst.sel &&
slots[i]->dst.chan == prev[4]->dst.chan &&
- (slots[i]->dst.write == 1 || slots[i]->is_op3) &&
- (prev[4]->dst.write == 1 || prev[4]->is_op3))
+ alu_writes(slots[i]) &&
+ alu_writes(prev[4]))
return 0;
result[i] = slots[i];
@@ -846,7 +882,7 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu
continue;
for (j = 0; j < max_slots; ++j) {
- if (!prev[j] || !(prev[j]->dst.write || prev[j]->is_op3))
+ if (!prev[j] || !alu_writes(prev[j]))
continue;
/* If it's relative then we can't determin which gpr is really used. */
@@ -1143,7 +1179,7 @@ int r600_bytecode_add_alu_type(struct r600_bytecode *bc,
struct r600_bytecode_alu *lalu;
int i, r;
- if (nalu == NULL)
+ if (!nalu)
return -ENOMEM;
memcpy(nalu, alu, sizeof(struct r600_bytecode_alu));
@@ -1304,7 +1340,7 @@ int r600_bytecode_add_vtx(struct r600_bytecode *bc, const struct r600_bytecode_v
struct r600_bytecode_vtx *nvtx = r600_bytecode_vtx();
int r;
- if (nvtx == NULL)
+ if (!nvtx)
return -ENOMEM;
memcpy(nvtx, vtx, sizeof(struct r600_bytecode_vtx));
@@ -1356,7 +1392,7 @@ int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_t
struct r600_bytecode_tex *ntex = r600_bytecode_tex();
int r;
- if (ntex == NULL)
+ if (!ntex)
return -ENOMEM;
memcpy(ntex, tex, sizeof(struct r600_bytecode_tex));
@@ -1407,6 +1443,33 @@ int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_t
return 0;
}
+int r600_bytecode_add_gds(struct r600_bytecode *bc, const struct r600_bytecode_gds *gds)
+{
+ struct r600_bytecode_gds *ngds = r600_bytecode_gds();
+ int r;
+
+ if (ngds == NULL)
+ return -ENOMEM;
+ memcpy(ngds, gds, sizeof(struct r600_bytecode_gds));
+
+ if (bc->cf_last == NULL ||
+ bc->cf_last->op != CF_OP_GDS ||
+ bc->force_add_cf) {
+ r = r600_bytecode_add_cf(bc);
+ if (r) {
+ free(ngds);
+ return r;
+ }
+ bc->cf_last->op = CF_OP_GDS;
+ }
+
+ LIST_ADDTAIL(&ngds->list, &bc->cf_last->gds);
+ bc->cf_last->ndw += 4; /* each GDS uses 4 dwords */
+ if ((bc->cf_last->ndw / 4) >= r600_bytecode_num_tex_and_vtx_instructions(bc))
+ bc->force_add_cf = 1;
+ return 0;
+}
+
int r600_bytecode_add_cfinst(struct r600_bytecode *bc, unsigned op)
{
int r;
@@ -1618,6 +1681,7 @@ int r600_bytecode_build(struct r600_bytecode *bc)
struct r600_bytecode_alu *alu;
struct r600_bytecode_vtx *vtx;
struct r600_bytecode_tex *tex;
+ struct r600_bytecode_gds *gds;
uint32_t literal[4];
unsigned nliteral;
unsigned addr;
@@ -1626,7 +1690,7 @@ int r600_bytecode_build(struct r600_bytecode *bc)
if (!bc->nstack) // If not 0, Stack_size already provided by llvm
bc->nstack = bc->stack.max_entries;
- if (bc->type == TGSI_PROCESSOR_VERTEX && !bc->nstack) {
+ if ((bc->type == TGSI_PROCESSOR_VERTEX || bc->type == TGSI_PROCESSOR_TESS_EVAL || bc->type == TGSI_PROCESSOR_TESS_CTRL) && !bc->nstack) {
bc->nstack = 1;
}
@@ -1670,10 +1734,12 @@ int r600_bytecode_build(struct r600_bytecode *bc)
r = r600_bytecode_alu_build(bc, alu, addr);
break;
case R700:
- case EVERGREEN: /* eg alu is same encoding as r700 */
- case CAYMAN:
r = r700_bytecode_alu_build(bc, alu, addr);
break;
+ case EVERGREEN:
+ case CAYMAN:
+ r = eg_bytecode_alu_build(bc, alu, addr);
+ break;
default:
R600_ERR("unknown chip class %d.\n", bc->chip_class);
return -EINVAL;
@@ -1696,6 +1762,14 @@ int r600_bytecode_build(struct r600_bytecode *bc)
return r;
addr += 4;
}
+ } else if (cf->op == CF_OP_GDS) {
+ assert(bc->chip_class >= EVERGREEN);
+ LIST_FOR_EACH_ENTRY(gds, &cf->gds, list) {
+ r = eg_bytecode_gds_build(bc, gds, addr);
+ if (r)
+ return r;
+ addr += 4;
+ }
} else if (cf->op == CF_OP_TEX) {
LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
assert(bc->chip_class >= EVERGREEN);
@@ -1726,6 +1800,7 @@ void r600_bytecode_clear(struct r600_bytecode *bc)
struct r600_bytecode_alu *alu = NULL, *next_alu;
struct r600_bytecode_tex *tex = NULL, *next_tex;
struct r600_bytecode_tex *vtx = NULL, *next_vtx;
+ struct r600_bytecode_gds *gds = NULL, *next_gds;
LIST_FOR_EACH_ENTRY_SAFE(alu, next_alu, &cf->alu, list) {
free(alu);
@@ -1745,6 +1820,12 @@ void r600_bytecode_clear(struct r600_bytecode *bc)
LIST_INITHEAD(&cf->vtx);
+ LIST_FOR_EACH_ENTRY_SAFE(gds, next_gds, &cf->gds, list) {
+ free(gds);
+ }
+
+ LIST_INITHEAD(&cf->gds);
+
free(cf);
}
@@ -1790,7 +1871,7 @@ static int print_dst(struct r600_bytecode_alu *alu)
reg_char = 'T';
}
- if (alu->dst.write || alu->is_op3) {
+ if (alu_writes(alu)) {
o += fprintf(stderr, "%c", reg_char);
o += print_sel(alu->dst.sel, alu->dst.rel, alu->index_mode, 0);
} else {
@@ -1845,6 +1926,28 @@ static int print_src(struct r600_bytecode_alu *alu, unsigned idx)
need_sel = 0;
need_chan = 0;
switch (sel) {
+ case EG_V_SQ_ALU_SRC_LDS_DIRECT_A:
+ o += fprintf(stderr, "LDS_A[0x%08X]", src->value);
+ break;
+ case EG_V_SQ_ALU_SRC_LDS_DIRECT_B:
+ o += fprintf(stderr, "LDS_B[0x%08X]", src->value);
+ break;
+ case EG_V_SQ_ALU_SRC_LDS_OQ_A:
+ o += fprintf(stderr, "LDS_OQ_A");
+ need_chan = 1;
+ break;
+ case EG_V_SQ_ALU_SRC_LDS_OQ_B:
+ o += fprintf(stderr, "LDS_OQ_B");
+ need_chan = 1;
+ break;
+ case EG_V_SQ_ALU_SRC_LDS_OQ_A_POP:
+ o += fprintf(stderr, "LDS_OQ_A_POP");
+ need_chan = 1;
+ break;
+ case EG_V_SQ_ALU_SRC_LDS_OQ_B_POP:
+ o += fprintf(stderr, "LDS_OQ_B_POP");
+ need_chan = 1;
+ break;
case V_SQ_ALU_SRC_PS:
o += fprintf(stderr, "PS");
break;
@@ -1906,6 +2009,7 @@ void r600_bytecode_disasm(struct r600_bytecode *bc)
struct r600_bytecode_alu *alu = NULL;
struct r600_bytecode_vtx *vtx = NULL;
struct r600_bytecode_tex *tex = NULL;
+ struct r600_bytecode_gds *gds = NULL;
unsigned i, id, ngr = 0, last;
uint32_t literal[4];
@@ -2189,6 +2293,33 @@ void r600_bytecode_disasm(struct r600_bytecode *bc)
id += 4;
}
+
+ LIST_FOR_EACH_ENTRY(gds, &cf->gds, list) {
+ int o = 0;
+ o += fprintf(stderr, " %04d %08X %08X %08X ", id, bc->bytecode[id],
+ bc->bytecode[id + 1], bc->bytecode[id + 2]);
+
+ o += fprintf(stderr, "%s ", r600_isa_fetch(gds->op)->name);
+
+ if (gds->op != FETCH_OP_TF_WRITE) {
+ o += fprintf(stderr, "R%d.", gds->dst_gpr);
+ o += print_swizzle(gds->dst_sel_x);
+ o += print_swizzle(gds->dst_sel_y);
+ o += print_swizzle(gds->dst_sel_z);
+ o += print_swizzle(gds->dst_sel_w);
+ }
+
+ o += fprintf(stderr, ", R%d.", gds->src_gpr);
+ o += print_swizzle(gds->src_sel_x);
+ o += print_swizzle(gds->src_sel_y);
+ o += print_swizzle(gds->src_sel_z);
+
+ if (gds->op != FETCH_OP_TF_WRITE) {
+ o += fprintf(stderr, ", R%d.", gds->src_gpr2);
+ }
+ fprintf(stderr, "\n");
+ id += 4;
+ }
}
fprintf(stderr, "--------------------------------------\n");
@@ -2415,7 +2546,7 @@ void *r600_create_vertex_fetch_shader(struct pipe_context *ctx,
&format, &num_format, &format_comp, &endian);
desc = util_format_description(elements[i].src_format);
- if (desc == NULL) {
+ if (!desc) {
r600_bytecode_clear(&bc);
R600_ERR("unknown format %d\n", elements[i].src_format);
return NULL;
diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h
index d48ad1ebf01..0b78290295a 100644
--- a/src/gallium/drivers/r600/r600_asm.h
+++ b/src/gallium/drivers/r600/r600_asm.h
@@ -52,6 +52,7 @@ struct r600_bytecode_alu {
unsigned op;
unsigned last;
unsigned is_op3;
+ unsigned is_lds_idx_op;
unsigned execute_mask;
unsigned update_pred;
unsigned pred_sel;
@@ -59,6 +60,7 @@ struct r600_bytecode_alu {
unsigned bank_swizzle_force;
unsigned omod;
unsigned index_mode;
+ unsigned lds_idx;
};
struct r600_bytecode_tex {
@@ -115,6 +117,24 @@ struct r600_bytecode_vtx {
unsigned buffer_index_mode;
};
+struct r600_bytecode_gds {
+ struct list_head list;
+ unsigned op;
+ unsigned gds_op;
+ unsigned src_gpr;
+ unsigned src_rel;
+ unsigned src_sel_x;
+ unsigned src_sel_y;
+ unsigned src_sel_z;
+ unsigned src_gpr2;
+ unsigned dst_gpr;
+ unsigned dst_rel;
+ unsigned dst_sel_x;
+ unsigned dst_sel_y;
+ unsigned dst_sel_z;
+ unsigned dst_sel_w;
+};
+
struct r600_bytecode_output {
unsigned array_base;
unsigned array_size;
@@ -159,6 +179,7 @@ struct r600_bytecode_cf {
struct list_head alu;
struct list_head tex;
struct list_head vtx;
+ struct list_head gds;
struct r600_bytecode_output output;
struct r600_bytecode_alu *curr_bs_head;
struct r600_bytecode_alu *prev_bs_head;
@@ -233,7 +254,9 @@ struct r600_bytecode {
/* eg_asm.c */
int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf);
int egcm_load_index_reg(struct r600_bytecode *bc, unsigned id, bool inside_alu_clause);
-
+int eg_bytecode_gds_build(struct r600_bytecode *bc, struct r600_bytecode_gds *gds, unsigned id);
+int eg_bytecode_alu_build(struct r600_bytecode *bc,
+ struct r600_bytecode_alu *alu, unsigned id);
/* r600_asm.c */
void r600_bytecode_init(struct r600_bytecode *bc,
enum chip_class chip_class,
@@ -246,6 +269,8 @@ int r600_bytecode_add_vtx(struct r600_bytecode *bc,
const struct r600_bytecode_vtx *vtx);
int r600_bytecode_add_tex(struct r600_bytecode *bc,
const struct r600_bytecode_tex *tex);
+int r600_bytecode_add_gds(struct r600_bytecode *bc,
+ const struct r600_bytecode_gds *gds);
int r600_bytecode_add_output(struct r600_bytecode *bc,
const struct r600_bytecode_output *output);
int r600_bytecode_build(struct r600_bytecode *bc);
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 8a90489318e..8a08dbdd82a 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -60,6 +60,8 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_fetch_shader.cso);
util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
util_blitter_save_geometry_shader(rctx->blitter, rctx->gs_shader);
+ util_blitter_save_tessctrl_shader(rctx->blitter, rctx->tcs_shader);
+ util_blitter_save_tesseval_shader(rctx->blitter, rctx->tes_shader);
util_blitter_save_so_targets(rctx->blitter, rctx->b.streamout.num_targets,
(struct pipe_stream_output_target**)rctx->b.streamout.targets);
util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer_state.cso);
@@ -553,7 +555,7 @@ static void r600_copy_global_buffer(struct pipe_context *ctx,
src = (struct pipe_resource *)pool->bo;
} else {
if (item->real_buffer == NULL) {
- item->real_buffer = (struct r600_resource*)
+ item->real_buffer =
r600_compute_buffer_alloc_vram(pool->screen,
item->size_in_dw * 4);
}
@@ -570,7 +572,7 @@ static void r600_copy_global_buffer(struct pipe_context *ctx,
dst = (struct pipe_resource *)pool->bo;
} else {
if (item->real_buffer == NULL) {
- item->real_buffer = (struct r600_resource*)
+ item->real_buffer =
r600_compute_buffer_alloc_vram(pool->screen,
item->size_in_dw * 4);
}
@@ -654,7 +656,8 @@ void r600_resource_copy_region(struct pipe_context *ctx,
util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
util_blitter_default_src_texture(&src_templ, src, src_level);
- if (util_format_is_compressed(src->format)) {
+ if (util_format_is_compressed(src->format) ||
+ util_format_is_compressed(dst->format)) {
unsigned blocksize = util_format_get_blocksize(src->format);
if (blocksize == 8)
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index 6409f0bd9f7..90b99e8a275 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -300,7 +300,7 @@ void r600_begin_new_cs(struct r600_context *ctx)
r600_mark_atom_dirty(ctx, &ctx->db_misc_state.atom);
r600_mark_atom_dirty(ctx, &ctx->db_state.atom);
r600_mark_atom_dirty(ctx, &ctx->framebuffer.atom);
- r600_mark_atom_dirty(ctx, &ctx->pixel_shader.atom);
+ r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[R600_HW_STAGE_PS].atom);
r600_mark_atom_dirty(ctx, &ctx->poly_offset_state.atom);
r600_mark_atom_dirty(ctx, &ctx->vgt_state.atom);
r600_mark_atom_dirty(ctx, &ctx->sample_mask.atom);
@@ -310,18 +310,22 @@ void r600_begin_new_cs(struct r600_context *ctx)
ctx->viewport.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
ctx->viewport.atom.num_dw = R600_MAX_VIEWPORTS * 8;
r600_mark_atom_dirty(ctx, &ctx->viewport.atom);
- if (ctx->b.chip_class < EVERGREEN) {
+ if (ctx->b.chip_class <= EVERGREEN) {
r600_mark_atom_dirty(ctx, &ctx->config_state.atom);
}
r600_mark_atom_dirty(ctx, &ctx->stencil_ref.atom);
r600_mark_atom_dirty(ctx, &ctx->vertex_fetch_shader.atom);
- r600_mark_atom_dirty(ctx, &ctx->export_shader.atom);
+ r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[R600_HW_STAGE_ES].atom);
r600_mark_atom_dirty(ctx, &ctx->shader_stages.atom);
if (ctx->gs_shader) {
- r600_mark_atom_dirty(ctx, &ctx->geometry_shader.atom);
+ r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[R600_HW_STAGE_GS].atom);
r600_mark_atom_dirty(ctx, &ctx->gs_rings.atom);
}
- r600_mark_atom_dirty(ctx, &ctx->vertex_shader.atom);
+ if (ctx->tes_shader) {
+ r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[EG_HW_STAGE_HS].atom);
+ r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[EG_HW_STAGE_LS].atom);
+ }
+ r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[R600_HW_STAGE_VS].atom);
r600_mark_atom_dirty(ctx, &ctx->b.streamout.enable_atom);
r600_mark_atom_dirty(ctx, &ctx->b.render_cond_atom);
diff --git a/src/gallium/drivers/r600/r600_llvm.c b/src/gallium/drivers/r600/r600_llvm.c
index 372cd419c73..1cc30317ba5 100644
--- a/src/gallium/drivers/r600/r600_llvm.c
+++ b/src/gallium/drivers/r600/r600_llvm.c
@@ -887,7 +887,7 @@ void r600_shader_binary_read_config(const struct radeon_shader_binary *binary,
case R_02880C_DB_SHADER_CONTROL:
*use_kill = G_02880C_KILL_ENABLE(value);
break;
- case CM_R_0288E8_SQ_LDS_ALLOC:
+ case R_0288E8_SQ_LDS_ALLOC:
bc->nlds_dw = value;
break;
}
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index bd00dcb642c..ba5d9be2e37 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -76,6 +76,9 @@ static void r600_destroy_context(struct pipe_context *context)
pipe_resource_reference((struct pipe_resource**)&rctx->dummy_cmask, NULL);
pipe_resource_reference((struct pipe_resource**)&rctx->dummy_fmask, NULL);
+ if (rctx->fixed_func_tcs_shader)
+ rctx->b.b.delete_tcs_state(&rctx->b.b, rctx->fixed_func_tcs_shader);
+
if (rctx->dummy_pixel_shader) {
rctx->b.b.delete_fs_state(&rctx->b.b, rctx->dummy_pixel_shader);
}
@@ -115,7 +118,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen,
struct r600_screen* rscreen = (struct r600_screen *)screen;
struct radeon_winsys *ws = rscreen->b.ws;
- if (rctx == NULL)
+ if (!rctx)
return NULL;
rctx->b.b.screen = screen;
@@ -274,6 +277,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
case PIPE_CAP_TGSI_TXQS:
+ case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
return 1;
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
@@ -340,14 +344,17 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_USER_VERTEX_BUFFERS:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_VERTEXID_NOBASE:
- case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
case PIPE_CAP_DEPTH_BOUNDS_TEST:
case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
case PIPE_CAP_SHAREABLE_SHADERS:
- case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
case PIPE_CAP_CLEAR_TEXTURE:
return 0;
+ case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
+ if (family >= CHIP_CEDAR)
+ return 30;
+ else
+ return 0;
/* Stream output. */
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
return rscreen->b.has_streamout ? 4 : 0;
@@ -443,8 +450,11 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
if (rscreen->b.info.drm_minor >= 37)
break;
return 0;
+ case PIPE_SHADER_TESS_CTRL:
+ case PIPE_SHADER_TESS_EVAL:
+ if (rscreen->b.family >= CHIP_CEDAR)
+ break;
default:
- /* XXX: support tessellation on Evergreen */
return 0;
}
@@ -527,7 +537,7 @@ static void r600_destroy_screen(struct pipe_screen* pscreen)
{
struct r600_screen *rscreen = (struct r600_screen *)pscreen;
- if (rscreen == NULL)
+ if (!rscreen)
return;
if (!rscreen->b.ws->unref(rscreen->b.ws))
@@ -554,7 +564,7 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
{
struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen);
- if (rscreen == NULL) {
+ if (!rscreen) {
return NULL;
}
@@ -580,7 +590,7 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
if (debug_get_bool_option("R600_DEBUG_COMPUTE", FALSE))
rscreen->b.debug_flags |= DBG_COMPUTE;
if (debug_get_bool_option("R600_DUMP_SHADERS", FALSE))
- rscreen->b.debug_flags |= DBG_FS | DBG_VS | DBG_GS | DBG_PS | DBG_CS;
+ rscreen->b.debug_flags |= DBG_FS | DBG_VS | DBG_GS | DBG_PS | DBG_CS | DBG_TCS | DBG_TES;
if (!debug_get_bool_option("R600_HYPERZ", TRUE))
rscreen->b.debug_flags |= DBG_NO_HYPERZ;
if (debug_get_bool_option("R600_LLVM", FALSE))
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index bbb55adef82..795fb9a9513 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -38,7 +38,7 @@
#include "tgsi/tgsi_scan.h"
-#define R600_NUM_ATOMS 43
+#define R600_NUM_ATOMS 52
#define R600_MAX_VIEWPORTS 16
@@ -59,11 +59,11 @@
/* the number of CS dwords for flushing and drawing */
#define R600_MAX_FLUSH_CS_DWORDS 16
-#define R600_MAX_DRAW_CS_DWORDS 47
+#define R600_MAX_DRAW_CS_DWORDS 58
#define R600_TRACE_CS_DWORDS 7
#define R600_MAX_USER_CONST_BUFFERS 13
-#define R600_MAX_DRIVER_CONST_BUFFERS 2
+#define R600_MAX_DRIVER_CONST_BUFFERS 3
#define R600_MAX_CONST_BUFFERS (R600_MAX_USER_CONST_BUFFERS + R600_MAX_DRIVER_CONST_BUFFERS)
/* start driver buffers after user buffers */
@@ -71,7 +71,12 @@
#define R600_UCP_SIZE (4*4*8)
#define R600_BUFFER_INFO_OFFSET (R600_UCP_SIZE)
-#define R600_GS_RING_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS + 1)
+#define R600_LDS_INFO_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS + 1)
+/*
+ * Note GS doesn't use a constant buffer binding, just a resource index,
+ * so it's fine to have it exist at index 16.
+ */
+#define R600_GS_RING_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS + 2)
/* Currently R600_MAX_CONST_BUFFERS just fits on the hw, which has a limit
* of 16 const buffers.
* UCP/SAMPLE_POSITIONS are never accessed by same shader stage so they can use the same id.
@@ -81,6 +86,17 @@
*/
#define R600_MAX_CONST_BUFFER_SIZE (4096 * sizeof(float[4]))
+/* HW stages */
+#define R600_HW_STAGE_PS 0
+#define R600_HW_STAGE_VS 1
+#define R600_HW_STAGE_GS 2
+#define R600_HW_STAGE_ES 3
+#define EG_HW_STAGE_LS 4
+#define EG_HW_STAGE_HS 5
+
+#define R600_NUM_HW_STAGES 4
+#define EG_NUM_HW_STAGES 6
+
#ifdef PIPE_ARCH_BIG_ENDIAN
#define R600_BIG_ENDIAN 1
#else
@@ -190,6 +206,8 @@ struct r600_config_state {
struct r600_atom atom;
unsigned sq_gpr_resource_mgmt_1;
unsigned sq_gpr_resource_mgmt_2;
+ unsigned sq_gpr_resource_mgmt_3;
+ bool dyn_gpr_enabled;
};
struct r600_stencil_ref
@@ -319,6 +337,9 @@ struct r600_pipe_shader_selector {
unsigned gs_max_out_vertices;
unsigned gs_num_invocations;
+ /* TCS/VS */
+ uint64_t lds_patch_outputs_written_mask;
+ uint64_t lds_outputs_written_mask;
unsigned nr_ps_max_color_exports;
};
@@ -421,7 +442,8 @@ struct r600_context {
/* Hardware info. */
boolean has_vertex_cache;
boolean keep_tiling_flags;
- unsigned default_ps_gprs, default_vs_gprs;
+ unsigned default_gprs[EG_NUM_HW_STAGES];
+ unsigned current_gprs[EG_NUM_HW_STAGES];
unsigned r6xx_num_clause_temp_gprs;
/* Miscellaneous state objects. */
@@ -470,10 +492,7 @@ struct r600_context {
struct r600_viewport_state viewport;
/* Shaders and shader resources. */
struct r600_cso_state vertex_fetch_shader;
- struct r600_shader_state vertex_shader;
- struct r600_shader_state pixel_shader;
- struct r600_shader_state geometry_shader;
- struct r600_shader_state export_shader;
+ struct r600_shader_state hw_shader_stages[EG_NUM_HW_STAGES];
struct r600_cs_shader_state cs_shader_state;
struct r600_shader_stages_state shader_stages;
struct r600_gs_rings_state gs_rings;
@@ -492,6 +511,12 @@ struct r600_context {
struct r600_pipe_shader_selector *ps_shader;
struct r600_pipe_shader_selector *vs_shader;
struct r600_pipe_shader_selector *gs_shader;
+
+ struct r600_pipe_shader_selector *tcs_shader;
+ struct r600_pipe_shader_selector *tes_shader;
+
+ struct r600_pipe_shader_selector *fixed_func_tcs_shader;
+
struct r600_rasterizer_state *rasterizer;
bool alpha_to_one;
bool force_blend_disable;
@@ -509,6 +534,12 @@ struct r600_context {
void *sb_context;
struct r600_isa *isa;
float sample_positions[4 * 16];
+ float tess_state[8];
+ bool tess_state_dirty;
+ struct r600_pipe_shader_selector *last_ls;
+ struct r600_pipe_shader_selector *last_tcs;
+ unsigned last_num_tcs_input_cp;
+ unsigned lds_alloc;
};
static inline void r600_emit_command_buffer(struct radeon_winsys_cs *cs,
@@ -580,7 +611,8 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
const struct pipe_sampler_view *state,
unsigned width0, unsigned height0,
unsigned force_level);
-void evergreen_init_common_regs(struct r600_command_buffer *cb,
+void evergreen_init_common_regs(struct r600_context *ctx,
+ struct r600_command_buffer *cb,
enum chip_class ctx_chip_class,
enum radeon_family ctx_family,
int ctx_drm_minor);
@@ -595,6 +627,8 @@ void evergreen_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader
void evergreen_update_es_state(struct pipe_context *ctx, struct r600_pipe_shader *shader);
void evergreen_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader);
void evergreen_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader);
+void evergreen_update_ls_state(struct pipe_context *ctx, struct r600_pipe_shader *shader);
+void evergreen_update_hs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader);
void *evergreen_create_db_flush_dsa(struct r600_context *rctx);
void *evergreen_create_resolve_blend(struct r600_context *rctx);
void *evergreen_create_decompress_blend(struct r600_context *rctx);
@@ -609,7 +643,7 @@ void evergreen_init_color_surface(struct r600_context *rctx,
void evergreen_init_color_surface_rat(struct r600_context *rctx,
struct r600_surface *surf);
void evergreen_update_db_shader_control(struct r600_context * rctx);
-
+bool evergreen_adjust_gprs(struct r600_context *rctx);
/* r600_blit.c */
void r600_init_blit_functions(struct r600_context *rctx);
void r600_decompress_depth_textures(struct r600_context *rctx,
@@ -684,6 +718,18 @@ void evergreen_dma_copy_buffer(struct r600_context *rctx,
uint64_t dst_offset,
uint64_t src_offset,
uint64_t size);
+void evergreen_setup_tess_constants(struct r600_context *rctx,
+ const struct pipe_draw_info *info,
+ unsigned *num_patches);
+uint32_t evergreen_get_ls_hs_config(struct r600_context *rctx,
+ const struct pipe_draw_info *info,
+ unsigned num_patches);
+void evergreen_set_ls_hs_config(struct r600_context *rctx,
+ struct radeon_winsys_cs *cs,
+ uint32_t ls_hs_config);
+void evergreen_set_lds_alloc(struct r600_context *rctx,
+ struct radeon_winsys_cs *cs,
+ uint32_t lds_alloc);
/* r600_state_common.c */
void r600_init_common_state_functions(struct r600_context *rctx);
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 560197c82b5..3c65610a788 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -60,12 +60,33 @@ issued in the w slot as well.
The compiler must issue the source argument to slots z, y, and x
*/
+/* Contents of r0 on entry to various shaders
+
+ VS - .x = VertexID
+ .y = RelVertexID (??)
+ .w = InstanceID
+
+ GS - r0.xyw, r1.xyz = per-vertex offsets
+ r0.z = PrimitiveID
+
+ TCS - .x = PatchID
+ .y = RelPatchID (??)
+ .z = InvocationID
+ .w = tess factor base.
+
+ TES - .x = TessCoord.x
+ - .y = TessCoord.y
+ - .z = RelPatchID (??)
+ - .w = PrimitiveID
+
+ PS - face_gpr.z = SampleMask
+ face_gpr.w = SampleID
+*/
#define R600_SHADER_BUFFER_INFO_SEL (512 + R600_BUFFER_INFO_OFFSET / 16)
static int r600_shader_from_tgsi(struct r600_context *rctx,
struct r600_pipe_shader *pipeshader,
union r600_shader_key key);
-
static void r600_add_gpr_array(struct r600_shader *ps, int start_gpr,
int size, unsigned comp_mask) {
@@ -161,6 +182,13 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
R600_ERR("translation from TGSI failed !\n");
goto error;
}
+ if (shader->shader.processor_type == TGSI_PROCESSOR_VERTEX) {
+ /* only disable for vertex shaders in tess paths */
+ if (key.vs.as_ls)
+ use_sb = 0;
+ }
+ use_sb &= (shader->shader.processor_type != TGSI_PROCESSOR_TESS_CTRL);
+ use_sb &= (shader->shader.processor_type != TGSI_PROCESSOR_TESS_EVAL);
/* disable SB for shaders using doubles */
use_sb &= !shader->shader.uses_doubles;
@@ -209,6 +237,15 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
/* Build state. */
switch (shader->shader.processor_type) {
+ case TGSI_PROCESSOR_TESS_CTRL:
+ evergreen_update_hs_state(ctx, shader);
+ break;
+ case TGSI_PROCESSOR_TESS_EVAL:
+ if (key.tes.as_es)
+ evergreen_update_es_state(ctx, shader);
+ else
+ evergreen_update_vs_state(ctx, shader);
+ break;
case TGSI_PROCESSOR_GEOMETRY:
if (rctx->b.chip_class >= EVERGREEN) {
evergreen_update_gs_state(ctx, shader);
@@ -221,7 +258,9 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
case TGSI_PROCESSOR_VERTEX:
export_shader = key.vs.as_es;
if (rctx->b.chip_class >= EVERGREEN) {
- if (export_shader)
+ if (key.vs.as_ls)
+ evergreen_update_ls_state(ctx, shader);
+ else if (key.vs.as_es)
evergreen_update_es_state(ctx, shader);
else
evergreen_update_vs_state(ctx, shader);
@@ -312,6 +351,8 @@ struct r600_shader_ctx {
int gs_export_gpr_tregs[4];
const struct pipe_stream_output_info *gs_stream_output_info;
unsigned enabled_stream_buffers_mask;
+ unsigned tess_input_info; /* temp with tess input offsets */
+ unsigned tess_output_info; /* temp with tess input offsets */
};
struct r600_shader_tgsi_instruction {
@@ -335,6 +376,20 @@ static int tgsi_fetch_rel_const(struct r600_shader_ctx *ctx,
static void r600_bytecode_src(struct r600_bytecode_alu_src *bc_src,
const struct r600_shader_src *shader_src,
unsigned chan);
+static int do_lds_fetch_values(struct r600_shader_ctx *ctx, unsigned temp_reg,
+ unsigned dst_reg);
+
+static int tgsi_last_instruction(unsigned writemask)
+{
+ int i, lasti = 0;
+
+ for (i = 0; i < 4; i++) {
+ if (writemask & (1 << i)) {
+ lasti = i;
+ }
+ }
+ return lasti;
+}
static int tgsi_is_supported(struct r600_shader_ctx *ctx)
{
@@ -361,10 +416,16 @@ static int tgsi_is_supported(struct r600_shader_ctx *ctx)
case TGSI_FILE_CONSTANT:
break;
case TGSI_FILE_INPUT:
- if (ctx->type == TGSI_PROCESSOR_GEOMETRY)
+ if (ctx->type == TGSI_PROCESSOR_GEOMETRY ||
+ ctx->type == TGSI_PROCESSOR_TESS_CTRL ||
+ ctx->type == TGSI_PROCESSOR_TESS_EVAL)
+ break;
+ case TGSI_FILE_OUTPUT:
+ if (ctx->type == TGSI_PROCESSOR_TESS_CTRL)
break;
default:
- R600_ERR("unsupported src %d (dimension %d)\n", j,
+ R600_ERR("unsupported src %d (file %d, dimension %d)\n", j,
+ i->Src[j].Register.File,
i->Src[j].Register.Dimension);
return -EINVAL;
}
@@ -372,6 +433,8 @@ static int tgsi_is_supported(struct r600_shader_ctx *ctx)
}
for (j = 0; j < i->Instruction.NumDstRegs; j++) {
if (i->Dst[j].Register.Dimension) {
+ if (ctx->type == TGSI_PROCESSOR_TESS_CTRL)
+ continue;
R600_ERR("unsupported dst (dimension)\n");
return -EINVAL;
}
@@ -550,6 +613,44 @@ static int r600_spi_sid(struct r600_shader_io * io)
return index;
};
+/* we need this to get a common lds index for vs/tcs/tes input/outputs */
+int r600_get_lds_unique_index(unsigned semantic_name, unsigned index)
+{
+ switch (semantic_name) {
+ case TGSI_SEMANTIC_POSITION:
+ return 0;
+ case TGSI_SEMANTIC_PSIZE:
+ return 1;
+ case TGSI_SEMANTIC_CLIPDIST:
+ assert(index <= 1);
+ return 2 + index;
+ case TGSI_SEMANTIC_GENERIC:
+ if (index <= 63-4)
+ return 4 + index - 9;
+ else
+ /* same explanation as in the default statement,
+ * the only user hitting this is st/nine.
+ */
+ return 0;
+
+ /* patch indices are completely separate and thus start from 0 */
+ case TGSI_SEMANTIC_TESSOUTER:
+ return 0;
+ case TGSI_SEMANTIC_TESSINNER:
+ return 1;
+ case TGSI_SEMANTIC_PATCH:
+ return 2 + index;
+
+ default:
+ /* Don't fail here. The result of this function is only used
+ * for LS, TCS, TES, and GS, where legacy GL semantics can't
+ * occur, but this function is called for all vertex shaders
+ * before it's known whether LS will be compiled or not.
+ */
+ return 0;
+ }
+}
+
/* turn input into interpolate on EG */
static int evergreen_interp_input(struct r600_shader_ctx *ctx, int index)
{
@@ -598,6 +699,133 @@ static int select_twoside_color(struct r600_shader_ctx *ctx, int front, int back
return 0;
}
+/* execute a single slot ALU calculation */
+static int single_alu_op2(struct r600_shader_ctx *ctx, int op,
+ int dst_sel, int dst_chan,
+ int src0_sel, unsigned src0_chan_val,
+ int src1_sel, unsigned src1_chan_val)
+{
+ struct r600_bytecode_alu alu;
+ int r, i;
+
+ if (ctx->bc->chip_class == CAYMAN && op == ALU_OP2_MULLO_INT) {
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = op;
+ alu.src[0].sel = src0_sel;
+ if (src0_sel == V_SQ_ALU_SRC_LITERAL)
+ alu.src[0].value = src0_chan_val;
+ else
+ alu.src[0].chan = src0_chan_val;
+ alu.src[1].sel = src1_sel;
+ if (src1_sel == V_SQ_ALU_SRC_LITERAL)
+ alu.src[1].value = src1_chan_val;
+ else
+ alu.src[1].chan = src1_chan_val;
+ alu.dst.sel = dst_sel;
+ alu.dst.chan = i;
+ alu.dst.write = i == dst_chan;
+ alu.last = (i == 3);
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+ }
+
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = op;
+ alu.src[0].sel = src0_sel;
+ if (src0_sel == V_SQ_ALU_SRC_LITERAL)
+ alu.src[0].value = src0_chan_val;
+ else
+ alu.src[0].chan = src0_chan_val;
+ alu.src[1].sel = src1_sel;
+ if (src1_sel == V_SQ_ALU_SRC_LITERAL)
+ alu.src[1].value = src1_chan_val;
+ else
+ alu.src[1].chan = src1_chan_val;
+ alu.dst.sel = dst_sel;
+ alu.dst.chan = dst_chan;
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ return 0;
+}
+
+/* execute a single slot ALU calculation */
+static int single_alu_op3(struct r600_shader_ctx *ctx, int op,
+ int dst_sel, int dst_chan,
+ int src0_sel, unsigned src0_chan_val,
+ int src1_sel, unsigned src1_chan_val,
+ int src2_sel, unsigned src2_chan_val)
+{
+ struct r600_bytecode_alu alu;
+ int r;
+
+ /* validate this for other ops */
+ assert(op == ALU_OP3_MULADD_UINT24);
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = op;
+ alu.src[0].sel = src0_sel;
+ if (src0_sel == V_SQ_ALU_SRC_LITERAL)
+ alu.src[0].value = src0_chan_val;
+ else
+ alu.src[0].chan = src0_chan_val;
+ alu.src[1].sel = src1_sel;
+ if (src1_sel == V_SQ_ALU_SRC_LITERAL)
+ alu.src[1].value = src1_chan_val;
+ else
+ alu.src[1].chan = src1_chan_val;
+ alu.src[2].sel = src2_sel;
+ if (src2_sel == V_SQ_ALU_SRC_LITERAL)
+ alu.src[2].value = src2_chan_val;
+ else
+ alu.src[2].chan = src2_chan_val;
+ alu.dst.sel = dst_sel;
+ alu.dst.chan = dst_chan;
+ alu.is_op3 = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ return 0;
+}
+
+/* put it in temp_reg.x */
+static int get_lds_offset0(struct r600_shader_ctx *ctx,
+ int rel_patch_chan,
+ int temp_reg, bool is_patch_var)
+{
+ int r;
+
+ /* MUL temp.x, patch_stride (input_vals.x), rel_patch_id (r0.y (tcs)) */
+ /* ADD
+ Dimension - patch0_offset (input_vals.z),
+ Non-dim - patch0_data_offset (input_vals.w)
+ */
+ r = single_alu_op3(ctx, ALU_OP3_MULADD_UINT24,
+ temp_reg, 0,
+ ctx->tess_output_info, 0,
+ 0, rel_patch_chan,
+ ctx->tess_output_info, is_patch_var ? 3 : 2);
+ if (r)
+ return r;
+ return 0;
+}
+
+static inline int get_address_file_reg(struct r600_shader_ctx *ctx, int index)
+{
+ return index > 0 ? ctx->bc->index_reg[index - 1] : ctx->bc->ar_reg;
+}
+
+static int r600_get_temp(struct r600_shader_ctx *ctx)
+{
+ return ctx->temp_reg + ctx->max_driver_temp_used++;
+}
+
static int vs_add_primid_output(struct r600_shader_ctx *ctx, int prim_id_sid)
{
int i;
@@ -612,6 +840,21 @@ static int vs_add_primid_output(struct r600_shader_ctx *ctx, int prim_id_sid)
return 0;
}
+static int tgsi_barrier(struct r600_shader_ctx *ctx)
+{
+ struct r600_bytecode_alu alu;
+ int r;
+
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ctx->inst_info->op;
+ alu.last = 1;
+
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ return 0;
+}
+
static int tgsi_declaration(struct r600_shader_ctx *ctx)
{
struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration;
@@ -672,7 +915,8 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
ctx->shader->output[i].interpolate = d->Interp.Interpolate;
ctx->shader->output[i].write_mask = d->Declaration.UsageMask;
if (ctx->type == TGSI_PROCESSOR_VERTEX ||
- ctx->type == TGSI_PROCESSOR_GEOMETRY) {
+ ctx->type == TGSI_PROCESSOR_GEOMETRY ||
+ ctx->type == TGSI_PROCESSOR_TESS_EVAL) {
ctx->shader->output[i].spi_sid = r600_spi_sid(&ctx->shader->output[i]);
switch (d->Semantic.Name) {
case TGSI_SEMANTIC_CLIPDIST:
@@ -758,6 +1002,73 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
break;
else if (d->Semantic.Name == TGSI_SEMANTIC_INVOCATIONID)
break;
+ else if (d->Semantic.Name == TGSI_SEMANTIC_TESSINNER ||
+ d->Semantic.Name == TGSI_SEMANTIC_TESSOUTER) {
+ int param = r600_get_lds_unique_index(d->Semantic.Name, 0);
+ int dreg = d->Semantic.Name == TGSI_SEMANTIC_TESSINNER ? 3 : 2;
+ unsigned temp_reg = r600_get_temp(ctx);
+
+ r = get_lds_offset0(ctx, 2, temp_reg, true);
+ if (r)
+ return r;
+
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ temp_reg, 0,
+ temp_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, param * 16);
+ if (r)
+ return r;
+
+ do_lds_fetch_values(ctx, temp_reg, dreg);
+ }
+ else if (d->Semantic.Name == TGSI_SEMANTIC_TESSCOORD) {
+ /* MOV r1.x, r0.x;
+ MOV r1.y, r0.y;
+ */
+ for (i = 0; i < 2; i++) {
+ struct r600_bytecode_alu alu;
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP1_MOV;
+ alu.src[0].sel = 0;
+ alu.src[0].chan = 0 + i;
+ alu.dst.sel = 1;
+ alu.dst.chan = 0 + i;
+ alu.dst.write = 1;
+ alu.last = (i == 1) ? 1 : 0;
+ if ((r = r600_bytecode_add_alu(ctx->bc, &alu)))
+ return r;
+ }
+ /* ADD r1.z, 1.0f, -r0.x */
+ struct r600_bytecode_alu alu;
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP2_ADD;
+ alu.src[0].sel = V_SQ_ALU_SRC_1;
+ alu.src[1].sel = 1;
+ alu.src[1].chan = 0;
+ alu.src[1].neg = 1;
+ alu.dst.sel = 1;
+ alu.dst.chan = 2;
+ alu.dst.write = 1;
+ alu.last = 1;
+ if ((r = r600_bytecode_add_alu(ctx->bc, &alu)))
+ return r;
+
+ /* ADD r1.z, r1.z, -r1.y */
+ alu.op = ALU_OP2_ADD;
+ alu.src[0].sel = 1;
+ alu.src[0].chan = 2;
+ alu.src[1].sel = 1;
+ alu.src[1].chan = 1;
+ alu.src[1].neg = 1;
+ alu.dst.sel = 1;
+ alu.dst.chan = 2;
+ alu.dst.write = 1;
+ alu.last = 1;
+ if ((r = r600_bytecode_add_alu(ctx->bc, &alu)))
+ return r;
+ break;
+ }
+ break;
default:
R600_ERR("unsupported file %d declaration\n", d->Declaration.File);
return -EINVAL;
@@ -765,11 +1076,6 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
return 0;
}
-static int r600_get_temp(struct r600_shader_ctx *ctx)
-{
- return ctx->temp_reg + ctx->max_driver_temp_used++;
-}
-
static int allocate_system_value_inputs(struct r600_shader_ctx *ctx, int gpr_offset)
{
struct tgsi_parse_context parse;
@@ -1042,12 +1348,50 @@ static void tgsi_src(struct r600_shader_ctx *ctx,
r600_src->swizzle[2] = 0;
r600_src->swizzle[3] = 0;
r600_src->sel = 0;
- } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_INVOCATIONID) {
+ } else if (ctx->type != TGSI_PROCESSOR_TESS_CTRL && ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_INVOCATIONID) {
r600_src->swizzle[0] = 3;
r600_src->swizzle[1] = 3;
r600_src->swizzle[2] = 3;
r600_src->swizzle[3] = 3;
r600_src->sel = 1;
+ } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_INVOCATIONID) {
+ r600_src->swizzle[0] = 2;
+ r600_src->swizzle[1] = 2;
+ r600_src->swizzle[2] = 2;
+ r600_src->swizzle[3] = 2;
+ r600_src->sel = 0;
+ } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_TESSCOORD) {
+ r600_src->sel = 1;
+ } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_TESSINNER) {
+ r600_src->sel = 3;
+ } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_TESSOUTER) {
+ r600_src->sel = 2;
+ } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_VERTICESIN) {
+ if (ctx->type == TGSI_PROCESSOR_TESS_CTRL) {
+ r600_src->sel = ctx->tess_input_info;
+ r600_src->swizzle[0] = 2;
+ r600_src->swizzle[1] = 2;
+ r600_src->swizzle[2] = 2;
+ r600_src->swizzle[3] = 2;
+ } else {
+ r600_src->sel = ctx->tess_input_info;
+ r600_src->swizzle[0] = 3;
+ r600_src->swizzle[1] = 3;
+ r600_src->swizzle[2] = 3;
+ r600_src->swizzle[3] = 3;
+ }
+ } else if (ctx->type == TGSI_PROCESSOR_TESS_CTRL && ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_PRIMID) {
+ r600_src->sel = 0;
+ r600_src->swizzle[0] = 0;
+ r600_src->swizzle[1] = 0;
+ r600_src->swizzle[2] = 0;
+ r600_src->swizzle[3] = 0;
+ } else if (ctx->type == TGSI_PROCESSOR_TESS_EVAL && ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_PRIMID) {
+ r600_src->sel = 0;
+ r600_src->swizzle[0] = 3;
+ r600_src->swizzle[1] = 3;
+ r600_src->swizzle[2] = 3;
+ r600_src->swizzle[3] = 3;
}
} else {
if (tgsi_src->Register.Indirect)
@@ -1129,6 +1473,7 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi
unsigned vtx_id = src->Dimension.Index;
int offset_reg = vtx_id / 3;
int offset_chan = vtx_id % 3;
+ int t2 = 0;
/* offsets of per-vertex data in ESGS ring are passed to GS in R0.x, R0.y,
* R0.w, R1.x, R1.y, R1.z (it seems R0.z is used for PrimitiveID) */
@@ -1136,13 +1481,24 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi
if (offset_reg == 0 && offset_chan == 2)
offset_chan = 3;
+ if (src->Dimension.Indirect || src->Register.Indirect)
+ t2 = r600_get_temp(ctx);
+
if (src->Dimension.Indirect) {
int treg[3];
- int t2;
struct r600_bytecode_alu alu;
int r, i;
-
- /* you have got to be shitting me -
+ unsigned addr_reg;
+ addr_reg = get_address_file_reg(ctx, src->DimIndirect.Index);
+ if (src->DimIndirect.Index > 0) {
+ r = single_alu_op2(ctx, ALU_OP1_MOV,
+ ctx->bc->ar_reg, 0,
+ addr_reg, 0,
+ 0, 0);
+ if (r)
+ return r;
+ }
+ /*
we have to put the R0.x/y/w into Rt.x Rt+1.x Rt+2.x then index reg from Rt.
at least this is what fglrx seems to do. */
for (i = 0; i < 3; i++) {
@@ -1150,7 +1506,6 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi
}
r600_add_gpr_array(ctx->shader, treg[0], 3, 0x0F);
- t2 = r600_get_temp(ctx);
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = ALU_OP1_MOV;
@@ -1175,8 +1530,33 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi
if (r)
return r;
offset_reg = t2;
+ offset_chan = 0;
}
+ if (src->Register.Indirect) {
+ int addr_reg;
+ unsigned first = ctx->info.input_array_first[src->Indirect.ArrayID];
+
+ addr_reg = get_address_file_reg(ctx, src->Indirect.Index);
+
+ /* pull the value from index_reg */
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ t2, 1,
+ addr_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, first);
+ if (r)
+ return r;
+ r = single_alu_op3(ctx, ALU_OP3_MULADD_UINT24,
+ t2, 0,
+ t2, 1,
+ V_SQ_ALU_SRC_LITERAL, 4,
+ offset_reg, offset_chan);
+ if (r)
+ return r;
+ offset_reg = t2;
+ offset_chan = 0;
+ index = src->Register.Index - first;
+ }
memset(&vtx, 0, sizeof(vtx));
vtx.buffer_id = R600_GS_RING_CONST_BUFFER;
@@ -1222,6 +1602,278 @@ static int tgsi_split_gs_inputs(struct r600_shader_ctx *ctx)
fetch_gs_input(ctx, src, treg);
ctx->src[i].sel = treg;
+ ctx->src[i].rel = 0;
+ }
+ }
+ return 0;
+}
+
+
+/* Tessellation shaders pass outputs to the next shader using LDS.
+ *
+ * LS outputs = TCS(HS) inputs
+ * TCS(HS) outputs = TES(DS) inputs
+ *
+ * The LDS layout is:
+ * - TCS inputs for patch 0
+ * - TCS inputs for patch 1
+ * - TCS inputs for patch 2 = get_tcs_in_current_patch_offset (if RelPatchID==2)
+ * - ...
+ * - TCS outputs for patch 0 = get_tcs_out_patch0_offset
+ * - Per-patch TCS outputs for patch 0 = get_tcs_out_patch0_patch_data_offset
+ * - TCS outputs for patch 1
+ * - Per-patch TCS outputs for patch 1
+ * - TCS outputs for patch 2 = get_tcs_out_current_patch_offset (if RelPatchID==2)
+ * - Per-patch TCS outputs for patch 2 = get_tcs_out_current_patch_data_offset (if RelPatchID==2)
+ * - ...
+ *
+ * All three shaders VS(LS), TCS, TES share the same LDS space.
+ */
+/* this will return with the dw address in temp_reg.x */
+static int r600_get_byte_address(struct r600_shader_ctx *ctx, int temp_reg,
+ const struct tgsi_full_dst_register *dst,
+ const struct tgsi_full_src_register *src,
+ int stride_bytes_reg, int stride_bytes_chan)
+{
+ struct tgsi_full_dst_register reg;
+ ubyte *name, *index, *array_first;
+ int r;
+ int param;
+ struct tgsi_shader_info *info = &ctx->info;
+ /* Set the register description. The address computation is the same
+ * for sources and destinations. */
+ if (src) {
+ reg.Register.File = src->Register.File;
+ reg.Register.Index = src->Register.Index;
+ reg.Register.Indirect = src->Register.Indirect;
+ reg.Register.Dimension = src->Register.Dimension;
+ reg.Indirect = src->Indirect;
+ reg.Dimension = src->Dimension;
+ reg.DimIndirect = src->DimIndirect;
+ } else
+ reg = *dst;
+
+ /* If the register is 2-dimensional (e.g. an array of vertices
+ * in a primitive), calculate the base address of the vertex. */
+ if (reg.Register.Dimension) {
+ int sel, chan;
+ if (reg.Dimension.Indirect) {
+ unsigned addr_reg;
+ assert (reg.DimIndirect.File == TGSI_FILE_ADDRESS);
+
+ addr_reg = get_address_file_reg(ctx, reg.DimIndirect.Index);
+ /* pull the value from index_reg */
+ sel = addr_reg;
+ chan = 0;
+ } else {
+ sel = V_SQ_ALU_SRC_LITERAL;
+ chan = reg.Dimension.Index;
+ }
+
+ r = single_alu_op3(ctx, ALU_OP3_MULADD_UINT24,
+ temp_reg, 0,
+ stride_bytes_reg, stride_bytes_chan,
+ sel, chan,
+ temp_reg, 0);
+ if (r)
+ return r;
+ }
+
+ if (reg.Register.File == TGSI_FILE_INPUT) {
+ name = info->input_semantic_name;
+ index = info->input_semantic_index;
+ array_first = info->input_array_first;
+ } else if (reg.Register.File == TGSI_FILE_OUTPUT) {
+ name = info->output_semantic_name;
+ index = info->output_semantic_index;
+ array_first = info->output_array_first;
+ } else {
+ assert(0);
+ return -1;
+ }
+ if (reg.Register.Indirect) {
+ int addr_reg;
+ int first;
+ /* Add the relative address of the element. */
+ if (reg.Indirect.ArrayID)
+ first = array_first[reg.Indirect.ArrayID];
+ else
+ first = reg.Register.Index;
+
+ addr_reg = get_address_file_reg(ctx, reg.Indirect.Index);
+
+ /* pull the value from index_reg */
+ r = single_alu_op3(ctx, ALU_OP3_MULADD_UINT24,
+ temp_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, 16,
+ addr_reg, 0,
+ temp_reg, 0);
+ if (r)
+ return r;
+
+ param = r600_get_lds_unique_index(name[first],
+ index[first]);
+
+ } else {
+ param = r600_get_lds_unique_index(name[reg.Register.Index],
+ index[reg.Register.Index]);
+ }
+
+ /* add to base_addr - passed in temp_reg.x */
+ if (param) {
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ temp_reg, 0,
+ temp_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, param * 16);
+ if (r)
+ return r;
+
+ }
+ return 0;
+}
+
+static int do_lds_fetch_values(struct r600_shader_ctx *ctx, unsigned temp_reg,
+ unsigned dst_reg)
+{
+ struct r600_bytecode_alu alu;
+ int r, i;
+
+ if ((ctx->bc->cf_last->ndw>>1) >= 0x60)
+ ctx->bc->force_add_cf = 1;
+ for (i = 1; i < 4; i++) {
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ temp_reg, i,
+ temp_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, 4 * i);
+ }
+ for (i = 0; i < 4; i++) {
+ /* emit an LDS_READ_RET */
+ memset(&alu, 0, sizeof(alu));
+ alu.op = LDS_OP1_LDS_READ_RET;
+ alu.src[0].sel = temp_reg;
+ alu.src[0].chan = i;
+ alu.src[1].sel = V_SQ_ALU_SRC_0;
+ alu.src[2].sel = V_SQ_ALU_SRC_0;
+ alu.dst.chan = 0;
+ alu.is_lds_idx_op = true;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ for (i = 0; i < 4; i++) {
+ /* then read from LDS_OQ_A_POP */
+ memset(&alu, 0, sizeof(alu));
+
+ alu.op = ALU_OP1_MOV;
+ alu.src[0].sel = EG_V_SQ_ALU_SRC_LDS_OQ_A_POP;
+ alu.src[0].chan = 0;
+ alu.dst.sel = dst_reg;
+ alu.dst.chan = i;
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+static int fetch_tes_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_register *src, unsigned int dst_reg)
+{
+ int r;
+ unsigned temp_reg = r600_get_temp(ctx);
+
+ r = get_lds_offset0(ctx, 2, temp_reg,
+ src->Register.Dimension ? false : true);
+ if (r)
+ return r;
+
+ /* the base address is now in temp.x */
+ r = r600_get_byte_address(ctx, temp_reg,
+ NULL, src, ctx->tess_output_info, 1);
+ if (r)
+ return r;
+
+ r = do_lds_fetch_values(ctx, temp_reg, dst_reg);
+ if (r)
+ return r;
+ return 0;
+}
+
+static int fetch_tcs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_register *src, unsigned int dst_reg)
+{
+ int r;
+ unsigned temp_reg = r600_get_temp(ctx);
+
+ /* t.x = ips * r0.y */
+ r = single_alu_op2(ctx, ALU_OP2_MUL_UINT24,
+ temp_reg, 0,
+ ctx->tess_input_info, 0,
+ 0, 1);
+
+ if (r)
+ return r;
+
+ /* the base address is now in temp.x */
+ r = r600_get_byte_address(ctx, temp_reg,
+ NULL, src, ctx->tess_input_info, 1);
+ if (r)
+ return r;
+
+ r = do_lds_fetch_values(ctx, temp_reg, dst_reg);
+ if (r)
+ return r;
+ return 0;
+}
+
+static int fetch_tcs_output(struct r600_shader_ctx *ctx, struct tgsi_full_src_register *src, unsigned int dst_reg)
+{
+ int r;
+ unsigned temp_reg = r600_get_temp(ctx);
+
+ r = get_lds_offset0(ctx, 1, temp_reg,
+ src->Register.Dimension ? false : true);
+ if (r)
+ return r;
+ /* the base address is now in temp.x */
+ r = r600_get_byte_address(ctx, temp_reg,
+ NULL, src,
+ ctx->tess_output_info, 1);
+ if (r)
+ return r;
+
+ r = do_lds_fetch_values(ctx, temp_reg, dst_reg);
+ if (r)
+ return r;
+ return 0;
+}
+
+static int tgsi_split_lds_inputs(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ int i;
+
+ for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
+ struct tgsi_full_src_register *src = &inst->Src[i];
+
+ if (ctx->type == TGSI_PROCESSOR_TESS_EVAL && src->Register.File == TGSI_FILE_INPUT) {
+ int treg = r600_get_temp(ctx);
+ fetch_tes_input(ctx, src, treg);
+ ctx->src[i].sel = treg;
+ ctx->src[i].rel = 0;
+ }
+ if (ctx->type == TGSI_PROCESSOR_TESS_CTRL && src->Register.File == TGSI_FILE_INPUT) {
+ int treg = r600_get_temp(ctx);
+ fetch_tcs_input(ctx, src, treg);
+ ctx->src[i].sel = treg;
+ ctx->src[i].rel = 0;
+ }
+ if (ctx->type == TGSI_PROCESSOR_TESS_CTRL && src->Register.File == TGSI_FILE_OUTPUT) {
+ int treg = r600_get_temp(ctx);
+ fetch_tcs_output(ctx, src, treg);
+ ctx->src[i].sel = treg;
+ ctx->src[i].rel = 0;
}
}
return 0;
@@ -1498,7 +2150,7 @@ static int generate_gs_copy_shader(struct r600_context *rctx,
*last_exp_pos = NULL, *last_exp_param = NULL;
int i, j, next_clip_pos = 61, next_param = 0;
int ring;
-
+ bool only_ring_0 = true;
cshader = calloc(1, sizeof(struct r600_pipe_shader));
if (!cshader)
return 0;
@@ -1549,6 +2201,7 @@ static int generate_gs_copy_shader(struct r600_context *rctx,
vtx.op = FETCH_OP_VFETCH;
vtx.buffer_id = R600_GS_RING_CONST_BUFFER;
vtx.fetch_type = SQ_VTX_FETCH_NO_INDEX_OFFSET;
+ vtx.mega_fetch_count = 16;
vtx.offset = out->ring_offset;
vtx.dst_gpr = out->gpr;
vtx.src_gpr = 0;
@@ -1570,6 +2223,8 @@ static int generate_gs_copy_shader(struct r600_context *rctx,
for (i = 0; i < so->num_outputs; i++) {
if (so->output[i].stream == ring) {
enabled = true;
+ if (ring > 0)
+ only_ring_0 = false;
break;
}
}
@@ -1604,10 +2259,20 @@ static int generate_gs_copy_shader(struct r600_context *rctx,
cf_jump = ctx.bc->cf_last;
if (enabled)
- emit_streamout(&ctx, so, ring, &cshader->shader.ring_item_sizes[ring]);
+ emit_streamout(&ctx, so, only_ring_0 ? -1 : ring, &cshader->shader.ring_item_sizes[ring]);
cshader->shader.ring_item_sizes[ring] = ocnt * 16;
}
+ /* bc adds nops - copy it */
+ if (ctx.bc->chip_class == R600) {
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP0_NOP;
+ alu.last = 1;
+ r600_bytecode_add_alu(ctx.bc, &alu);
+
+ r600_bytecode_add_cfinst(ctx.bc, CF_OP_NOP);
+ }
+
/* export vertex data */
/* XXX factor out common code with r600_shader_from_tgsi ? */
for (i = 0; i < ocnt; ++i) {
@@ -1778,6 +2443,27 @@ static int generate_gs_copy_shader(struct r600_context *rctx,
return r600_bytecode_build(ctx.bc);
}
+static int emit_inc_ring_offset(struct r600_shader_ctx *ctx, int idx, bool ind)
+{
+ if (ind) {
+ struct r600_bytecode_alu alu;
+ int r;
+
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP2_ADD_INT;
+ alu.src[0].sel = ctx->gs_export_gpr_tregs[idx];
+ alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
+ alu.src[1].value = ctx->gs_out_ring_offset >> 4;
+ alu.dst.sel = ctx->gs_export_gpr_tregs[idx];
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
static int emit_gs_ring_writes(struct r600_shader_ctx *ctx, const struct pipe_stream_output_info *so, int stream, bool ind)
{
struct r600_bytecode_output output;
@@ -1844,24 +2530,390 @@ static int emit_gs_ring_writes(struct r600_shader_ctx *ctx, const struct pipe_st
r600_bytecode_add_output(ctx->bc, &output);
}
- if (ind) {
- /* get a temp and add the ring offset to the next vertex base in the shader */
- struct r600_bytecode_alu alu;
- int r;
+ ++ctx->gs_next_vertex;
+ return 0;
+}
+
+static int r600_fetch_tess_io_info(struct r600_shader_ctx *ctx)
+{
+ int r;
+ struct r600_bytecode_vtx vtx;
+ int temp_val = ctx->temp_reg;
+ /* need to store the TCS output somewhere */
+ r = single_alu_op2(ctx, ALU_OP1_MOV,
+ temp_val, 0,
+ V_SQ_ALU_SRC_LITERAL, 0,
+ 0, 0);
+ if (r)
+ return r;
+
+ /* used by VS/TCS */
+ if (ctx->tess_input_info) {
+ /* fetch tcs input values into resv space */
+ memset(&vtx, 0, sizeof(struct r600_bytecode_vtx));
+ vtx.op = FETCH_OP_VFETCH;
+ vtx.buffer_id = R600_LDS_INFO_CONST_BUFFER;
+ vtx.fetch_type = SQ_VTX_FETCH_NO_INDEX_OFFSET;
+ vtx.mega_fetch_count = 16;
+ vtx.data_format = FMT_32_32_32_32;
+ vtx.num_format_all = 2;
+ vtx.format_comp_all = 1;
+ vtx.use_const_fields = 0;
+ vtx.endian = r600_endian_swap(32);
+ vtx.srf_mode_all = 1;
+ vtx.offset = 0;
+ vtx.dst_gpr = ctx->tess_input_info;
+ vtx.dst_sel_x = 0;
+ vtx.dst_sel_y = 1;
+ vtx.dst_sel_z = 2;
+ vtx.dst_sel_w = 3;
+ vtx.src_gpr = temp_val;
+ vtx.src_sel_x = 0;
+
+ r = r600_bytecode_add_vtx(ctx->bc, &vtx);
+ if (r)
+ return r;
+ }
+
+ /* used by TCS/TES */
+ if (ctx->tess_output_info) {
+ /* fetch tcs output values into resv space */
+ memset(&vtx, 0, sizeof(struct r600_bytecode_vtx));
+ vtx.op = FETCH_OP_VFETCH;
+ vtx.buffer_id = R600_LDS_INFO_CONST_BUFFER;
+ vtx.fetch_type = SQ_VTX_FETCH_NO_INDEX_OFFSET;
+ vtx.mega_fetch_count = 16;
+ vtx.data_format = FMT_32_32_32_32;
+ vtx.num_format_all = 2;
+ vtx.format_comp_all = 1;
+ vtx.use_const_fields = 0;
+ vtx.endian = r600_endian_swap(32);
+ vtx.srf_mode_all = 1;
+ vtx.offset = 16;
+ vtx.dst_gpr = ctx->tess_output_info;
+ vtx.dst_sel_x = 0;
+ vtx.dst_sel_y = 1;
+ vtx.dst_sel_z = 2;
+ vtx.dst_sel_w = 3;
+ vtx.src_gpr = temp_val;
+ vtx.src_sel_x = 0;
+
+ r = r600_bytecode_add_vtx(ctx->bc, &vtx);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+static int emit_lds_vs_writes(struct r600_shader_ctx *ctx)
+{
+ int i, j, r;
+ int temp_reg;
+
+ /* fetch tcs input values into input_vals */
+ ctx->tess_input_info = r600_get_temp(ctx);
+ ctx->tess_output_info = 0;
+ r = r600_fetch_tess_io_info(ctx);
+ if (r)
+ return r;
+
+ temp_reg = r600_get_temp(ctx);
+ /* dst reg contains LDS address stride * idx */
+ /* MUL vertexID, vertex_dw_stride */
+ r = single_alu_op2(ctx, ALU_OP2_MUL_UINT24,
+ temp_reg, 0,
+ ctx->tess_input_info, 1,
+ 0, 1); /* rel id in r0.y? */
+ if (r)
+ return r;
+
+ for (i = 0; i < ctx->shader->noutput; i++) {
+ struct r600_bytecode_alu alu;
+ int param = r600_get_lds_unique_index(ctx->shader->output[i].name, ctx->shader->output[i].sid);
+
+ if (param) {
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ temp_reg, 1,
+ temp_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, param * 16);
+ if (r)
+ return r;
+ }
+
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ temp_reg, 2,
+ temp_reg, param ? 1 : 0,
+ V_SQ_ALU_SRC_LITERAL, 8);
+ if (r)
+ return r;
+
+
+ for (j = 0; j < 2; j++) {
+ int chan = (j == 1) ? 2 : (param ? 1 : 0);
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = LDS_OP3_LDS_WRITE_REL;
+ alu.src[0].sel = temp_reg;
+ alu.src[0].chan = chan;
+ alu.src[1].sel = ctx->shader->output[i].gpr;
+ alu.src[1].chan = j * 2;
+ alu.src[2].sel = ctx->shader->output[i].gpr;
+ alu.src[2].chan = (j * 2) + 1;
+ alu.last = 1;
+ alu.dst.chan = 0;
+ alu.lds_idx = 1;
+ alu.is_lds_idx_op = true;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ }
+ return 0;
+}
+
+static int r600_store_tcs_output(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ const struct tgsi_full_dst_register *dst = &inst->Dst[0];
+ int i, r, lasti;
+ int temp_reg = r600_get_temp(ctx);
+ struct r600_bytecode_alu alu;
+ unsigned write_mask = dst->Register.WriteMask;
+
+ if (inst->Dst[0].Register.File != TGSI_FILE_OUTPUT)
+ return 0;
+
+ r = get_lds_offset0(ctx, 1, temp_reg, dst->Register.Dimension ? false : true);
+ if (r)
+ return r;
+
+ /* the base address is now in temp.x */
+ r = r600_get_byte_address(ctx, temp_reg,
+ &inst->Dst[0], NULL, ctx->tess_output_info, 1);
+ if (r)
+ return r;
+
+ /* LDS write */
+ lasti = tgsi_last_instruction(write_mask);
+ for (i = 1; i <= lasti; i++) {
+
+ if (!(write_mask & (1 << i)))
+ continue;
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ temp_reg, i,
+ temp_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, 4 * i);
+ if (r)
+ return r;
+ }
+
+ for (i = 0; i <= lasti; i++) {
+ if (!(write_mask & (1 << i)))
+ continue;
+
+ if ((i == 0 && ((write_mask & 3) == 3)) ||
+ (i == 2 && ((write_mask & 0xc) == 0xc))) {
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = LDS_OP3_LDS_WRITE_REL;
+ alu.src[0].sel = temp_reg;
+ alu.src[0].chan = i;
+
+ alu.src[1].sel = dst->Register.Index;
+ alu.src[1].sel += ctx->file_offset[dst->Register.File];
+ alu.src[1].chan = i;
+
+ alu.src[2].sel = dst->Register.Index;
+ alu.src[2].sel += ctx->file_offset[dst->Register.File];
+ alu.src[2].chan = i + 1;
+ alu.lds_idx = 1;
+ alu.dst.chan = 0;
+ alu.last = 1;
+ alu.is_lds_idx_op = true;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ i += 1;
+ continue;
+ }
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
- alu.op = ALU_OP2_ADD_INT;
- alu.src[0].sel = ctx->gs_export_gpr_tregs[effective_stream];
- alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
- alu.src[1].value = ctx->gs_out_ring_offset >> 4;
- alu.dst.sel = ctx->gs_export_gpr_tregs[effective_stream];
- alu.dst.write = 1;
+ alu.op = LDS_OP2_LDS_WRITE;
+ alu.src[0].sel = temp_reg;
+ alu.src[0].chan = i;
+
+ alu.src[1].sel = dst->Register.Index;
+ alu.src[1].sel += ctx->file_offset[dst->Register.File];
+ alu.src[1].chan = i;
+
+ alu.src[2].sel = V_SQ_ALU_SRC_0;
+ alu.dst.chan = 0;
alu.last = 1;
+ alu.is_lds_idx_op = true;
r = r600_bytecode_add_alu(ctx->bc, &alu);
if (r)
return r;
}
- ++ctx->gs_next_vertex;
+ return 0;
+}
+
+static int r600_tess_factor_read(struct r600_shader_ctx *ctx,
+ int output_idx)
+{
+ int param;
+ unsigned temp_reg = r600_get_temp(ctx);
+ unsigned name = ctx->shader->output[output_idx].name;
+ int dreg = ctx->shader->output[output_idx].gpr;
+ int r;
+
+ param = r600_get_lds_unique_index(name, 0);
+ r = get_lds_offset0(ctx, 1, temp_reg, true);
+ if (r)
+ return r;
+
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ temp_reg, 0,
+ temp_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, param * 16);
+ if (r)
+ return r;
+
+ do_lds_fetch_values(ctx, temp_reg, dreg);
+ return 0;
+}
+
+static int r600_emit_tess_factor(struct r600_shader_ctx *ctx)
+{
+ int i;
+ int stride, outer_comps, inner_comps;
+ int tessinner_idx = -1, tessouter_idx = -1;
+ int r;
+ int temp_reg = r600_get_temp(ctx);
+ int treg[3] = {-1, -1, -1};
+ struct r600_bytecode_alu alu;
+ struct r600_bytecode_cf *cf_jump, *cf_pop;
+
+ /* only execute factor emission for invocation 0 */
+ /* PRED_SETE_INT __, R0.x, 0 */
+ memset(&alu, 0, sizeof(alu));
+ alu.op = ALU_OP2_PRED_SETE_INT;
+ alu.src[0].chan = 2;
+ alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
+ alu.execute_mask = 1;
+ alu.update_pred = 1;
+ alu.last = 1;
+ r600_bytecode_add_alu_type(ctx->bc, &alu, CF_OP_ALU_PUSH_BEFORE);
+
+ r600_bytecode_add_cfinst(ctx->bc, CF_OP_JUMP);
+ cf_jump = ctx->bc->cf_last;
+
+ treg[0] = r600_get_temp(ctx);
+ switch (ctx->shader->tcs_prim_mode) {
+ case PIPE_PRIM_LINES:
+ stride = 8; /* 2 dwords, 1 vec2 store */
+ outer_comps = 2;
+ inner_comps = 0;
+ break;
+ case PIPE_PRIM_TRIANGLES:
+ stride = 16; /* 4 dwords, 1 vec4 store */
+ outer_comps = 3;
+ inner_comps = 1;
+ treg[1] = r600_get_temp(ctx);
+ break;
+ case PIPE_PRIM_QUADS:
+ stride = 24; /* 6 dwords, 2 stores (vec4 + vec2) */
+ outer_comps = 4;
+ inner_comps = 2;
+ treg[1] = r600_get_temp(ctx);
+ treg[2] = r600_get_temp(ctx);
+ break;
+ default:
+ assert(0);
+ return -1;
+ }
+
+ /* R0 is InvocationID, RelPatchID, PatchID, tf_base */
+ /* TF_WRITE takes index in R.x, value in R.y */
+ for (i = 0; i < ctx->shader->noutput; i++) {
+ if (ctx->shader->output[i].name == TGSI_SEMANTIC_TESSINNER)
+ tessinner_idx = i;
+ if (ctx->shader->output[i].name == TGSI_SEMANTIC_TESSOUTER)
+ tessouter_idx = i;
+ }
+
+ if (tessouter_idx == -1)
+ return -1;
+
+ if (tessinner_idx == -1 && inner_comps)
+ return -1;
+
+ if (tessouter_idx != -1) {
+ r = r600_tess_factor_read(ctx, tessouter_idx);
+ if (r)
+ return r;
+ }
+
+ if (tessinner_idx != -1) {
+ r = r600_tess_factor_read(ctx, tessinner_idx);
+ if (r)
+ return r;
+ }
+
+ /* r.x = tf_base(r0.w) + relpatchid(r0.y) * tf_stride */
+ /* r.x = relpatchid(r0.y) * tf_stride */
+
+ /* multiply incoming r0.y * stride - t.x = r0.y * stride */
+ /* add incoming r0.w to it: t.x = t.x + r0.w */
+ r = single_alu_op3(ctx, ALU_OP3_MULADD_UINT24,
+ temp_reg, 0,
+ 0, 1,
+ V_SQ_ALU_SRC_LITERAL, stride,
+ 0, 3);
+ if (r)
+ return r;
+
+ for (i = 0; i < outer_comps + inner_comps; i++) {
+ int out_idx = i >= outer_comps ? tessinner_idx : tessouter_idx;
+ int out_comp = i >= outer_comps ? i - outer_comps : i;
+
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ treg[i / 2], (2 * (i % 2)),
+ temp_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, 4 * i);
+ if (r)
+ return r;
+ r = single_alu_op2(ctx, ALU_OP1_MOV,
+ treg[i / 2], 1 + (2 * (i%2)),
+ ctx->shader->output[out_idx].gpr, out_comp,
+ 0, 0);
+ if (r)
+ return r;
+ }
+ for (i = 0; i < outer_comps + inner_comps; i++) {
+ struct r600_bytecode_gds gds;
+
+ memset(&gds, 0, sizeof(struct r600_bytecode_gds));
+ gds.src_gpr = treg[i / 2];
+ gds.src_sel_x = 2 * (i % 2);
+ gds.src_sel_y = 1 + (2 * (i % 2));
+ gds.src_sel_z = 4;
+ gds.dst_sel_x = 7;
+ gds.dst_sel_y = 7;
+ gds.dst_sel_z = 7;
+ gds.dst_sel_w = 7;
+ gds.op = FETCH_OP_TF_WRITE;
+ r = r600_bytecode_add_gds(ctx->bc, &gds);
+ if (r)
+ return r;
+ }
+
+ // Patch up jump label
+ r600_bytecode_add_cfinst(ctx->bc, CF_OP_POP);
+ cf_pop = ctx->bc->cf_last;
+
+ cf_jump->cf_addr = cf_pop->id + 2;
+ cf_jump->pop_count = 1;
+ cf_pop->cf_addr = cf_pop->id + 2;
+ cf_pop->pop_count = 1;
+
return 0;
}
@@ -1885,6 +2937,8 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
bool use_llvm = false;
bool indirect_gprs;
bool ring_outputs = false;
+ bool lds_outputs = false;
+ bool lds_inputs = false;
bool pos_emitted = false;
#ifdef R600_USE_LLVM
@@ -1909,14 +2963,38 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
shader->processor_type = ctx.type;
ctx.bc->type = shader->processor_type;
- if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+ switch (ctx.type) {
+ case TGSI_PROCESSOR_VERTEX:
shader->vs_as_gs_a = key.vs.as_gs_a;
shader->vs_as_es = key.vs.as_es;
+ shader->vs_as_ls = key.vs.as_ls;
+ if (shader->vs_as_es)
+ ring_outputs = true;
+ if (shader->vs_as_ls)
+ lds_outputs = true;
+ break;
+ case TGSI_PROCESSOR_GEOMETRY:
+ ring_outputs = true;
+ break;
+ case TGSI_PROCESSOR_TESS_CTRL:
+ shader->tcs_prim_mode = key.tcs.prim_mode;
+ lds_outputs = true;
+ lds_inputs = true;
+ break;
+ case TGSI_PROCESSOR_TESS_EVAL:
+ shader->tes_as_es = key.tes.as_es;
+ lds_inputs = true;
+ if (shader->tes_as_es)
+ ring_outputs = true;
+ break;
+ case TGSI_PROCESSOR_FRAGMENT:
+ shader->two_side = key.ps.color_two_side;
+ break;
+ default:
+ break;
}
- ring_outputs = shader->vs_as_es || ctx.type == TGSI_PROCESSOR_GEOMETRY;
-
- if (shader->vs_as_es) {
+ if (shader->vs_as_es || shader->tes_as_es) {
ctx.gs_for_vs = &rctx->gs_shader->current->shader;
} else {
ctx.gs_for_vs = NULL;
@@ -1936,8 +3014,6 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
shader->nr_ps_color_exports = 0;
shader->nr_ps_max_color_exports = 0;
- if (ctx.type == TGSI_PROCESSOR_FRAGMENT)
- shader->two_side = key.ps.color_two_side;
/* register allocations */
/* Values [0,127] correspond to GPR[0..127].
@@ -1988,6 +3064,24 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
/* FIXME 1 would be enough in some cases (3 or less input vertices) */
ctx.file_offset[TGSI_FILE_INPUT] = 2;
}
+ if (ctx.type == TGSI_PROCESSOR_TESS_CTRL)
+ ctx.file_offset[TGSI_FILE_INPUT] = 1;
+ if (ctx.type == TGSI_PROCESSOR_TESS_EVAL) {
+ bool add_tesscoord = false, add_tess_inout = false;
+ ctx.file_offset[TGSI_FILE_INPUT] = 1;
+ for (i = 0; i < PIPE_MAX_SHADER_INPUTS; i++) {
+ /* if we have tesscoord save one reg */
+ if (ctx.info.system_value_semantic_name[i] == TGSI_SEMANTIC_TESSCOORD)
+ add_tesscoord = true;
+ if (ctx.info.system_value_semantic_name[i] == TGSI_SEMANTIC_TESSINNER ||
+ ctx.info.system_value_semantic_name[i] == TGSI_SEMANTIC_TESSOUTER)
+ add_tess_inout = true;
+ }
+ if (add_tesscoord || add_tess_inout)
+ ctx.file_offset[TGSI_FILE_INPUT]++;
+ if (add_tess_inout)
+ ctx.file_offset[TGSI_FILE_INPUT]+=2;
+ }
ctx.use_llvm = use_llvm;
if (use_llvm) {
@@ -2011,7 +3105,15 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
ctx.bc->index_reg[0] = ctx.bc->ar_reg + 1;
ctx.bc->index_reg[1] = ctx.bc->ar_reg + 2;
- if (ctx.type == TGSI_PROCESSOR_GEOMETRY) {
+ if (ctx.type == TGSI_PROCESSOR_TESS_CTRL) {
+ ctx.tess_input_info = ctx.bc->ar_reg + 3;
+ ctx.tess_output_info = ctx.bc->ar_reg + 4;
+ ctx.temp_reg = ctx.bc->ar_reg + 5;
+ } else if (ctx.type == TGSI_PROCESSOR_TESS_EVAL) {
+ ctx.tess_input_info = 0;
+ ctx.tess_output_info = ctx.bc->ar_reg + 3;
+ ctx.temp_reg = ctx.bc->ar_reg + 4;
+ } else if (ctx.type == TGSI_PROCESSOR_GEOMETRY) {
ctx.gs_export_gpr_tregs[0] = ctx.bc->ar_reg + 3;
ctx.gs_export_gpr_tregs[1] = ctx.bc->ar_reg + 4;
ctx.gs_export_gpr_tregs[2] = ctx.bc->ar_reg + 5;
@@ -2049,6 +3151,9 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
if (shader->vs_as_gs_a)
vs_add_primid_output(&ctx, key.vs.prim_id_out);
+ if (ctx.type == TGSI_PROCESSOR_TESS_EVAL)
+ r600_fetch_tess_io_info(&ctx);
+
while (!tgsi_parse_end_of_tokens(&ctx.parse)) {
tgsi_parse_token(&ctx.parse);
switch (ctx.parse.FullToken.Token.Type) {
@@ -2206,6 +3311,11 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
if (ctx.type == TGSI_PROCESSOR_GEOMETRY) {
struct r600_bytecode_alu alu;
int r;
+
+ /* GS thread with no output workaround - emit a cut at start of GS */
+ if (ctx.bc->chip_class == R600)
+ r600_bytecode_add_cfinst(ctx.bc, CF_OP_CUT_VERTEX);
+
for (j = 0; j < 4; j++) {
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = ALU_OP1_MOV;
@@ -2219,6 +3329,10 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
return r;
}
}
+
+ if (ctx.type == TGSI_PROCESSOR_TESS_CTRL)
+ r600_fetch_tess_io_info(&ctx);
+
if (shader->two_side && ctx.colors_used) {
if ((r = process_twoside_color_inputs(&ctx)))
return r;
@@ -2241,9 +3355,13 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
goto out_err;
if ((r = tgsi_split_literal_constant(&ctx)))
goto out_err;
- if (ctx.type == TGSI_PROCESSOR_GEOMETRY)
+ if (ctx.type == TGSI_PROCESSOR_GEOMETRY) {
if ((r = tgsi_split_gs_inputs(&ctx)))
goto out_err;
+ } else if (lds_inputs) {
+ if ((r = tgsi_split_lds_inputs(&ctx)))
+ goto out_err;
+ }
if (ctx.bc->chip_class == CAYMAN)
ctx.inst_info = &cm_shader_tgsi_instruction[opcode];
else if (ctx.bc->chip_class >= EVERGREEN)
@@ -2253,6 +3371,12 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
r = ctx.inst_info->process(&ctx);
if (r)
goto out_err;
+
+ if (ctx.type == TGSI_PROCESSOR_TESS_CTRL) {
+ r = r600_store_tcs_output(&ctx);
+ if (r)
+ goto out_err;
+ }
break;
default:
break;
@@ -2316,15 +3440,28 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
}
/* Add stream outputs. */
- if (!ring_outputs && ctx.type == TGSI_PROCESSOR_VERTEX &&
- so.num_outputs && !use_llvm)
- emit_streamout(&ctx, &so, -1, NULL);
-
+ if (!use_llvm && so.num_outputs) {
+ bool emit = false;
+ if (!lds_outputs && !ring_outputs && ctx.type == TGSI_PROCESSOR_VERTEX)
+ emit = true;
+ if (!ring_outputs && ctx.type == TGSI_PROCESSOR_TESS_EVAL)
+ emit = true;
+ if (emit)
+ emit_streamout(&ctx, &so, -1, NULL);
+ }
pipeshader->enabled_stream_buffers_mask = ctx.enabled_stream_buffers_mask;
convert_edgeflag_to_int(&ctx);
- if (ring_outputs) {
- if (shader->vs_as_es) {
+ if (ctx.type == TGSI_PROCESSOR_TESS_CTRL)
+ r600_emit_tess_factor(&ctx);
+
+ if (lds_outputs) {
+ if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+ if (ctx.shader->noutput)
+ emit_lds_vs_writes(&ctx);
+ }
+ } else if (ring_outputs) {
+ if (shader->vs_as_es || shader->tes_as_es) {
ctx.gs_export_gpr_tregs[0] = r600_get_temp(&ctx);
ctx.gs_export_gpr_tregs[1] = -1;
ctx.gs_export_gpr_tregs[2] = -1;
@@ -2349,6 +3486,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
output[j].op = CF_OP_EXPORT;
switch (ctx.type) {
case TGSI_PROCESSOR_VERTEX:
+ case TGSI_PROCESSOR_TESS_EVAL:
switch (shader->output[i].name) {
case TGSI_SEMANTIC_POSITION:
output[j].array_base = 60;
@@ -2492,6 +3630,8 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
goto out_err;
}
break;
+ case TGSI_PROCESSOR_TESS_CTRL:
+ break;
default:
R600_ERR("unsupported processor type %d\n", ctx.type);
r = -EINVAL;
@@ -2505,7 +3645,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
}
/* add fake position export */
- if (ctx.type == TGSI_PROCESSOR_VERTEX && pos_emitted == false) {
+ if ((ctx.type == TGSI_PROCESSOR_VERTEX || ctx.type == TGSI_PROCESSOR_TESS_EVAL) && pos_emitted == false) {
memset(&output[j], 0, sizeof(struct r600_bytecode_output));
output[j].gpr = 0;
output[j].elem_size = 3;
@@ -2521,7 +3661,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
}
/* add fake param output for vertex shader if no param is exported */
- if (ctx.type == TGSI_PROCESSOR_VERTEX && next_param_base == 0) {
+ if ((ctx.type == TGSI_PROCESSOR_VERTEX || ctx.type == TGSI_PROCESSOR_TESS_EVAL) && next_param_base == 0) {
memset(&output[j], 0, sizeof(struct r600_bytecode_output));
output[j].gpr = 0;
output[j].elem_size = 3;
@@ -2583,7 +3723,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
last = r600_isa_cf(ctx.bc->cf_last->op);
/* alu clause instructions don't have EOP bit, so add NOP */
- if (!last || last->flags & CF_ALU || ctx.bc->cf_last->op == CF_OP_LOOP_END || ctx.bc->cf_last->op == CF_OP_CALL_FS)
+ if (!last || last->flags & CF_ALU || ctx.bc->cf_last->op == CF_OP_LOOP_END || ctx.bc->cf_last->op == CF_OP_CALL_FS || ctx.bc->cf_last->op == CF_OP_POP || ctx.bc->cf_last->op == CF_OP_GDS)
r600_bytecode_add_cfinst(ctx.bc, CF_OP_NOP);
ctx.bc->cf_last->end_of_program = 1;
@@ -2662,27 +3802,19 @@ static void tgsi_dst(struct r600_shader_ctx *ctx,
r600_dst->sel += ctx->file_offset[tgsi_dst->Register.File];
r600_dst->chan = swizzle;
r600_dst->write = 1;
- if (tgsi_dst->Register.Indirect)
- r600_dst->rel = V_SQ_REL_RELATIVE;
if (inst->Instruction.Saturate) {
r600_dst->clamp = 1;
}
-}
-
-static int tgsi_last_instruction(unsigned writemask)
-{
- int i, lasti = 0;
-
- for (i = 0; i < 4; i++) {
- if (writemask & (1 << i)) {
- lasti = i;
+ if (ctx->type == TGSI_PROCESSOR_TESS_CTRL) {
+ if (tgsi_dst->Register.File == TGSI_FILE_OUTPUT) {
+ return;
}
}
- return lasti;
+ if (tgsi_dst->Register.Indirect)
+ r600_dst->rel = V_SQ_REL_RELATIVE;
+
}
-
-
static int tgsi_op2_64_params(struct r600_shader_ctx *ctx, bool singledest, bool swap)
{
struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
@@ -7180,7 +8312,7 @@ static int tgsi_eg_arl(struct r600_shader_ctx *ctx)
struct r600_bytecode_alu alu;
int r;
int i, lasti = tgsi_last_instruction(inst->Dst[0].Register.WriteMask);
- unsigned reg = inst->Dst[0].Register.Index > 0 ? ctx->bc->index_reg[inst->Dst[0].Register.Index - 1] : ctx->bc->ar_reg;
+ unsigned reg = get_address_file_reg(ctx, inst->Dst[0].Register.Index);
assert(inst->Dst[0].Register.Index < 3);
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
@@ -7744,8 +8876,11 @@ static int tgsi_gs_emit(struct r600_shader_ctx *ctx)
emit_gs_ring_writes(ctx, ctx->gs_stream_output_info, stream, TRUE);
r = r600_bytecode_add_cfinst(ctx->bc, ctx->inst_info->op);
- if (!r)
+ if (!r) {
ctx->bc->cf_last->count = stream; // Count field for CUT/EMIT_VERTEX indicates which stream
+ if (ctx->inst_info->op == CF_OP_EMIT_VERTEX)
+ return emit_inc_ring_offset(ctx, stream, TRUE);
+ }
return r;
}
@@ -8193,7 +9328,7 @@ static const struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] =
[TGSI_OPCODE_MFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_LFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_SFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
- [TGSI_OPCODE_BARRIER] = { ALU_OP0_NOP, tgsi_unsupported},
+ [TGSI_OPCODE_BARRIER] = { ALU_OP0_GROUP_BARRIER, tgsi_barrier},
[TGSI_OPCODE_ATOMUADD] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_ATOMXCHG] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_ATOMCAS] = { ALU_OP0_NOP, tgsi_unsupported},
@@ -8415,7 +9550,7 @@ static const struct r600_shader_tgsi_instruction cm_shader_tgsi_instruction[] =
[TGSI_OPCODE_MFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_LFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_SFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
- [TGSI_OPCODE_BARRIER] = { ALU_OP0_NOP, tgsi_unsupported},
+ [TGSI_OPCODE_BARRIER] = { ALU_OP0_GROUP_BARRIER, tgsi_barrier},
[TGSI_OPCODE_ATOMUADD] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_ATOMXCHG] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_ATOMCAS] = { ALU_OP0_NOP, tgsi_unsupported},
diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
index 2040f732bf5..cfdb0200333 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -30,6 +30,16 @@
extern "C" {
#endif
+/* Valid shader configurations:
+ *
+ * API shaders VS | TCS | TES | GS |pass| PS
+ * are compiled as: | | | |thru|
+ * | | | | |
+ * Only VS & PS: VS | -- | -- | -- | -- | PS
+ * With GS: ES | -- | -- | GS | VS | PS
+ * With Tessel.: LS | HS | VS | -- | -- | PS
+ * With both: LS | HS | ES | GS | VS | PS
+ */
struct r600_shader_io {
unsigned name;
@@ -52,8 +62,8 @@ struct r600_shader {
unsigned ninput;
unsigned noutput;
unsigned nlds;
- struct r600_shader_io input[40];
- struct r600_shader_io output[40];
+ struct r600_shader_io input[64];
+ struct r600_shader_io output[64];
boolean uses_kill;
boolean fs_write_all;
boolean two_side;
@@ -86,7 +96,10 @@ struct r600_shader {
unsigned max_arrays;
unsigned num_arrays;
unsigned vs_as_es;
+ unsigned vs_as_ls;
unsigned vs_as_gs_a;
+ unsigned tes_as_es;
+ unsigned tcs_prim_mode;
unsigned ps_prim_id_input;
struct r600_shader_array * arrays;
@@ -102,8 +115,15 @@ union r600_shader_key {
struct {
unsigned prim_id_out:8;
unsigned as_es:1; /* export shader */
+ unsigned as_ls:1; /* local shader */
unsigned as_gs_a:1;
} vs;
+ struct {
+ unsigned as_es:1;
+ } tes;
+ struct {
+ unsigned prim_mode:3;
+ } tcs;
};
struct r600_shader_array {
@@ -134,6 +154,7 @@ struct r600_pipe_shader {
TGSI_INTERPOLATE_LOC_CENTER/SAMPLE/COUNT. Other input values return -1. */
int eg_get_interpolator_index(unsigned interpolate, unsigned location);
+int r600_get_lds_unique_index(unsigned semantic_name, unsigned index);
#ifdef __cplusplus
} // extern "C"
diff --git a/src/gallium/drivers/r600/r600_sq.h b/src/gallium/drivers/r600/r600_sq.h
index 1545cf1b521..37b6d5832f7 100644
--- a/src/gallium/drivers/r600/r600_sq.h
+++ b/src/gallium/drivers/r600/r600_sq.h
@@ -189,6 +189,14 @@
* 255 SQ_ALU_SRC_PS: previous scalar result.
* 448 EG - INTERP SRC BASE
*/
+/* LDS are Evergreen/Cayman only */
+#define EG_V_SQ_ALU_SRC_LDS_OQ_A 0x000000DB
+#define EG_V_SQ_ALU_SRC_LDS_OQ_B 0x000000DC
+#define EG_V_SQ_ALU_SRC_LDS_OQ_A_POP 0x000000DD
+#define EG_V_SQ_ALU_SRC_LDS_OQ_B_POP 0x000000DE
+#define EG_V_SQ_ALU_SRC_LDS_DIRECT_A 0x000000DF
+#define EG_V_SQ_ALU_SRC_LDS_DIRECT_B 0x000000E0
+
#define V_SQ_ALU_SRC_0 0x000000F8
#define V_SQ_ALU_SRC_1 0x000000F9
#define V_SQ_ALU_SRC_1_INT 0x000000FA
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index c2d4abc5ea1..e7ffe0dab1c 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -390,7 +390,7 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
unsigned db_depth_control, alpha_test_control, alpha_ref;
struct r600_dsa_state *dsa = CALLOC_STRUCT(r600_dsa_state);
- if (dsa == NULL) {
+ if (!dsa) {
return NULL;
}
@@ -446,7 +446,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
float psize_min, psize_max;
struct r600_rasterizer_state *rs = CALLOC_STRUCT(r600_rasterizer_state);
- if (rs == NULL) {
+ if (!rs) {
return NULL;
}
@@ -559,7 +559,7 @@ static void *r600_create_sampler_state(struct pipe_context *ctx,
struct r600_pipe_sampler_state *ss = CALLOC_STRUCT(r600_pipe_sampler_state);
unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 4 : 0;
- if (ss == NULL) {
+ if (!ss) {
return NULL;
}
@@ -642,7 +642,7 @@ r600_create_sampler_view_custom(struct pipe_context *ctx,
unsigned char swizzle[4], array_mode = 0;
unsigned width, height, depth, offset_level, last_level;
- if (view == NULL)
+ if (!view)
return NULL;
/* initialize base object */
@@ -2044,57 +2044,62 @@ static void r600_emit_gs_rings(struct r600_context *rctx, struct r600_atom *a)
/* Adjust GPR allocation on R6xx/R7xx */
bool r600_adjust_gprs(struct r600_context *rctx)
{
- unsigned num_ps_gprs = rctx->ps_shader->current->shader.bc.ngpr;
- unsigned num_vs_gprs, num_es_gprs, num_gs_gprs;
- unsigned new_num_ps_gprs = num_ps_gprs;
- unsigned new_num_vs_gprs, new_num_es_gprs, new_num_gs_gprs;
- unsigned cur_num_ps_gprs = G_008C04_NUM_PS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_1);
- unsigned cur_num_vs_gprs = G_008C04_NUM_VS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_1);
- unsigned cur_num_gs_gprs = G_008C08_NUM_GS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_2);
- unsigned cur_num_es_gprs = G_008C08_NUM_ES_GPRS(rctx->config_state.sq_gpr_resource_mgmt_2);
- unsigned def_num_ps_gprs = rctx->default_ps_gprs;
- unsigned def_num_vs_gprs = rctx->default_vs_gprs;
- unsigned def_num_gs_gprs = 0;
- unsigned def_num_es_gprs = 0;
+ unsigned num_gprs[R600_NUM_HW_STAGES];
+ unsigned new_gprs[R600_NUM_HW_STAGES];
+ unsigned cur_gprs[R600_NUM_HW_STAGES];
+ unsigned def_gprs[R600_NUM_HW_STAGES];
unsigned def_num_clause_temp_gprs = rctx->r6xx_num_clause_temp_gprs;
- /* hardware will reserve twice num_clause_temp_gprs */
- unsigned max_gprs = def_num_gs_gprs + def_num_es_gprs + def_num_ps_gprs + def_num_vs_gprs + def_num_clause_temp_gprs * 2;
+ unsigned max_gprs;
unsigned tmp, tmp2;
+ unsigned i;
+ bool need_recalc = false, use_default = true;
- if (rctx->gs_shader) {
- num_es_gprs = rctx->vs_shader->current->shader.bc.ngpr;
- num_gs_gprs = rctx->gs_shader->current->shader.bc.ngpr;
- num_vs_gprs = rctx->gs_shader->current->gs_copy_shader->shader.bc.ngpr;
- } else {
- num_es_gprs = 0;
- num_gs_gprs = 0;
- num_vs_gprs = rctx->vs_shader->current->shader.bc.ngpr;
+ /* hardware will reserve twice num_clause_temp_gprs */
+ max_gprs = def_num_clause_temp_gprs * 2;
+ for (i = 0; i < R600_NUM_HW_STAGES; i++) {
+ def_gprs[i] = rctx->default_gprs[i];
+ max_gprs += def_gprs[i];
+ }
+
+ cur_gprs[R600_HW_STAGE_PS] = G_008C04_NUM_PS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_1);
+ cur_gprs[R600_HW_STAGE_VS] = G_008C04_NUM_VS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_1);
+ cur_gprs[R600_HW_STAGE_GS] = G_008C08_NUM_GS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_2);
+ cur_gprs[R600_HW_STAGE_ES] = G_008C08_NUM_ES_GPRS(rctx->config_state.sq_gpr_resource_mgmt_2);
+
+ num_gprs[R600_HW_STAGE_PS] = rctx->ps_shader->current->shader.bc.ngpr;
+ if (rctx->gs_shader) {
+ num_gprs[R600_HW_STAGE_ES] = rctx->vs_shader->current->shader.bc.ngpr;
+ num_gprs[R600_HW_STAGE_GS] = rctx->gs_shader->current->shader.bc.ngpr;
+ num_gprs[R600_HW_STAGE_VS] = rctx->gs_shader->current->gs_copy_shader->shader.bc.ngpr;
+ } else {
+ num_gprs[R600_HW_STAGE_ES] = 0;
+ num_gprs[R600_HW_STAGE_GS] = 0;
+ num_gprs[R600_HW_STAGE_VS] = rctx->vs_shader->current->shader.bc.ngpr;
+ }
+
+ for (i = 0; i < R600_NUM_HW_STAGES; i++) {
+ new_gprs[i] = num_gprs[i];
+ if (new_gprs[i] > cur_gprs[i])
+ need_recalc = true;
+ if (new_gprs[i] > def_gprs[i])
+ use_default = false;
}
- new_num_vs_gprs = num_vs_gprs;
- new_num_es_gprs = num_es_gprs;
- new_num_gs_gprs = num_gs_gprs;
/* the sum of all SQ_GPR_RESOURCE_MGMT*.NUM_*_GPRS must <= to max_gprs */
- if (new_num_ps_gprs > cur_num_ps_gprs || new_num_vs_gprs > cur_num_vs_gprs ||
- new_num_es_gprs > cur_num_es_gprs || new_num_gs_gprs > cur_num_gs_gprs) {
- /* try to use switch back to default */
- if (new_num_ps_gprs > def_num_ps_gprs || new_num_vs_gprs > def_num_vs_gprs ||
- new_num_gs_gprs > def_num_gs_gprs || new_num_es_gprs > def_num_es_gprs) {
- /* always privilege vs stage so that at worst we have the
- * pixel stage producing wrong output (not the vertex
- * stage) */
- new_num_ps_gprs = max_gprs - ((new_num_vs_gprs + new_num_es_gprs + new_num_gs_gprs) + def_num_clause_temp_gprs * 2);
- new_num_vs_gprs = num_vs_gprs;
- new_num_gs_gprs = num_gs_gprs;
- new_num_es_gprs = num_es_gprs;
- } else {
- new_num_ps_gprs = def_num_ps_gprs;
- new_num_vs_gprs = def_num_vs_gprs;
- new_num_es_gprs = def_num_es_gprs;
- new_num_gs_gprs = def_num_gs_gprs;
- }
- } else {
+ if (!need_recalc)
return true;
+
+ /* try to use switch back to default */
+ if (!use_default) {
+ /* always privilege vs stage so that at worst we have the
+ * pixel stage producing wrong output (not the vertex
+ * stage) */
+ new_gprs[R600_HW_STAGE_PS] = max_gprs - def_num_clause_temp_gprs * 2;
+ for (i = R600_HW_STAGE_VS; i < R600_NUM_HW_STAGES; i++)
+ new_gprs[R600_HW_STAGE_PS] -= new_gprs[i];
+ } else {
+ for (i = 0; i < R600_NUM_HW_STAGES; i++)
+ new_gprs[i] = def_gprs[i];
}
/* SQ_PGM_RESOURCES_*.NUM_GPRS must always be program to a value <=
@@ -2103,21 +2108,22 @@ bool r600_adjust_gprs(struct r600_context *rctx)
* it will lockup. So in this case just discard the draw command
* and don't change the current gprs repartitions.
*/
- if (num_ps_gprs > new_num_ps_gprs || num_vs_gprs > new_num_vs_gprs ||
- num_gs_gprs > new_num_gs_gprs || num_es_gprs > new_num_es_gprs) {
- R600_ERR("shaders require too many register (%d + %d + %d + %d) "
- "for a combined maximum of %d\n",
- num_ps_gprs, num_vs_gprs, num_es_gprs, num_gs_gprs, max_gprs);
- return false;
+ for (i = 0; i < R600_NUM_HW_STAGES; i++) {
+ if (num_gprs[i] > new_gprs[i]) {
+ R600_ERR("shaders require too many register (%d + %d + %d + %d) "
+ "for a combined maximum of %d\n",
+ num_gprs[R600_HW_STAGE_PS], num_gprs[R600_HW_STAGE_VS], num_gprs[R600_HW_STAGE_ES], num_gprs[R600_HW_STAGE_GS], max_gprs);
+ return false;
+ }
}
/* in some case we endup recomputing the current value */
- tmp = S_008C04_NUM_PS_GPRS(new_num_ps_gprs) |
- S_008C04_NUM_VS_GPRS(new_num_vs_gprs) |
+ tmp = S_008C04_NUM_PS_GPRS(new_gprs[R600_HW_STAGE_PS]) |
+ S_008C04_NUM_VS_GPRS(new_gprs[R600_HW_STAGE_VS]) |
S_008C04_NUM_CLAUSE_TEMP_GPRS(def_num_clause_temp_gprs);
- tmp2 = S_008C08_NUM_ES_GPRS(new_num_es_gprs) |
- S_008C08_NUM_GS_GPRS(new_num_gs_gprs);
+ tmp2 = S_008C08_NUM_ES_GPRS(new_gprs[R600_HW_STAGE_ES]) |
+ S_008C08_NUM_GS_GPRS(new_gprs[R600_HW_STAGE_GS]);
if (rctx->config_state.sq_gpr_resource_mgmt_1 != tmp || rctx->config_state.sq_gpr_resource_mgmt_2 != tmp2) {
rctx->config_state.sq_gpr_resource_mgmt_1 = tmp;
rctx->config_state.sq_gpr_resource_mgmt_2 = tmp2;
@@ -2213,10 +2219,11 @@ void r600_init_atom_start_cs(struct r600_context *rctx)
num_temp_gprs = 4;
num_gs_gprs = 0;
num_es_gprs = 0;
- num_ps_threads = 136;
- num_vs_threads = 48;
- num_gs_threads = 4;
- num_es_threads = 4;
+ /* use limits 40 VS and at least 16 ES/GS */
+ num_ps_threads = 120;
+ num_vs_threads = 40;
+ num_gs_threads = 16;
+ num_es_threads = 16;
num_ps_stack_entries = 40;
num_vs_stack_entries = 40;
num_gs_stack_entries = 32;
@@ -2285,8 +2292,11 @@ void r600_init_atom_start_cs(struct r600_context *rctx)
break;
}
- rctx->default_ps_gprs = num_ps_gprs;
- rctx->default_vs_gprs = num_vs_gprs;
+ rctx->default_gprs[R600_HW_STAGE_PS] = num_ps_gprs;
+ rctx->default_gprs[R600_HW_STAGE_VS] = num_vs_gprs;
+ rctx->default_gprs[R600_HW_STAGE_GS] = 0;
+ rctx->default_gprs[R600_HW_STAGE_ES] = 0;
+
rctx->r6xx_num_clause_temp_gprs = num_temp_gprs;
/* SQ_CONFIG */
@@ -2675,6 +2685,9 @@ void r600_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
S_02881C_USE_VTX_VIEWPORT_INDX(rshader->vs_out_viewport);
}
+#define RV610_GSVS_ALIGN 32
+#define R600_GSVS_ALIGN 16
+
void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
{
struct r600_context *rctx = (struct r600_context *)ctx;
@@ -2684,6 +2697,23 @@ void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
unsigned gsvs_itemsize =
(cp_shader->ring_item_sizes[0] * shader->selector->gs_max_out_vertices) >> 2;
+ /* some r600s needs gsvs itemsize aligned to cacheline size
+ this was fixed in rs780 and above. */
+ switch (rctx->b.family) {
+ case CHIP_RV610:
+ gsvs_itemsize = align(gsvs_itemsize, RV610_GSVS_ALIGN);
+ break;
+ case CHIP_R600:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ gsvs_itemsize = align(gsvs_itemsize, R600_GSVS_ALIGN);
+ break;
+ default:
+ break;
+ }
+
r600_init_command_buffer(cb, 64);
/* VGT_GS_MODE is written by r600_emit_shader_stages */
@@ -3054,7 +3084,7 @@ fallback:
void r600_init_state_functions(struct r600_context *rctx)
{
unsigned id = 1;
-
+ unsigned i;
/* !!!
* To avoid GPU lockup registers must be emited in a specific order
* (no kidding ...). The order below is important and have been
@@ -3109,10 +3139,8 @@ void r600_init_state_functions(struct r600_context *rctx)
r600_add_atom(rctx, &rctx->b.render_cond_atom, id++);
r600_add_atom(rctx, &rctx->b.streamout.begin_atom, id++);
r600_add_atom(rctx, &rctx->b.streamout.enable_atom, id++);
- r600_init_atom(rctx, &rctx->vertex_shader.atom, id++, r600_emit_shader, 23);
- r600_init_atom(rctx, &rctx->pixel_shader.atom, id++, r600_emit_shader, 0);
- r600_init_atom(rctx, &rctx->geometry_shader.atom, id++, r600_emit_shader, 0);
- r600_init_atom(rctx, &rctx->export_shader.atom, id++, r600_emit_shader, 0);
+ for (i = 0; i < R600_NUM_HW_STAGES; i++)
+ r600_init_atom(rctx, &rctx->hw_shader_stages[i].atom, id++, r600_emit_shader, 0);
r600_init_atom(rctx, &rctx->shader_stages.atom, id++, r600_emit_shader_stages, 0);
r600_init_atom(rctx, &rctx->gs_rings.atom, id++, r600_emit_gs_rings, 0);
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index d629194ca6e..6a666343b06 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -35,6 +35,7 @@
#include "util/u_math.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_scan.h"
+#include "tgsi/tgsi_ureg.h"
void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw)
{
@@ -117,6 +118,7 @@ static unsigned r600_conv_pipe_prim(unsigned prim)
[PIPE_PRIM_LINE_STRIP_ADJACENCY] = V_008958_DI_PT_LINESTRIP_ADJ,
[PIPE_PRIM_TRIANGLES_ADJACENCY] = V_008958_DI_PT_TRILIST_ADJ,
[PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY] = V_008958_DI_PT_TRISTRIP_ADJ,
+ [PIPE_PRIM_PATCHES] = V_008958_DI_PT_PATCH,
[R600_PRIM_RECTANGLE_LIST] = V_008958_DI_PT_RECTLIST
};
assert(prim < Elements(prim_conv));
@@ -192,7 +194,7 @@ static void r600_bind_blend_state(struct pipe_context *ctx, void *state)
struct r600_context *rctx = (struct r600_context *)ctx;
struct r600_blend_state *blend = (struct r600_blend_state *)state;
- if (blend == NULL) {
+ if (!blend) {
r600_set_cso_state_with_cb(rctx, &rctx->blend_state, NULL, NULL);
return;
}
@@ -299,7 +301,7 @@ static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
struct r600_dsa_state *dsa = state;
struct r600_stencil_ref ref;
- if (state == NULL) {
+ if (!state) {
r600_set_cso_state_with_cb(rctx, &rctx->dsa_state, NULL, NULL);
return;
}
@@ -339,7 +341,7 @@ static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
struct r600_rasterizer_state *rs = (struct r600_rasterizer_state *)state;
struct r600_context *rctx = (struct r600_context *)ctx;
- if (state == NULL)
+ if (!state)
return;
rctx->rasterizer = rs;
@@ -742,7 +744,10 @@ static inline union r600_shader_key r600_shader_selector_key(struct pipe_context
switch (sel->type) {
case PIPE_SHADER_VERTEX: {
- key.vs.as_es = (rctx->gs_shader != NULL);
+ key.vs.as_ls = (rctx->tes_shader != NULL);
+ if (!key.vs.as_ls)
+ key.vs.as_es = (rctx->gs_shader != NULL);
+
if (rctx->ps_shader->current->shader.gs_prim_id_input && !rctx->gs_shader) {
key.vs.as_gs_a = true;
key.vs.prim_id_out = rctx->ps_shader->current->shader.input[rctx->ps_shader->current->shader.ps_prim_id_input].spi_sid;
@@ -762,6 +767,12 @@ static inline union r600_shader_key r600_shader_selector_key(struct pipe_context
key.ps.nr_cbufs = 2;
break;
}
+ case PIPE_SHADER_TESS_EVAL:
+ key.tes.as_es = (rctx->gs_shader != NULL);
+ break;
+ case PIPE_SHADER_TESS_CTRL:
+ key.tcs.prim_mode = rctx->tes_shader->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
+ break;
default:
assert(0);
}
@@ -845,6 +856,7 @@ static void *r600_create_shader_state(struct pipe_context *ctx,
unsigned pipe_shader_type)
{
struct r600_pipe_shader_selector *sel = CALLOC_STRUCT(r600_pipe_shader_selector);
+ int i;
sel->type = pipe_shader_type;
sel->tokens = tgsi_dup_tokens(state->tokens);
@@ -860,6 +872,30 @@ static void *r600_create_shader_state(struct pipe_context *ctx,
sel->gs_num_invocations =
sel->info.properties[TGSI_PROPERTY_GS_INVOCATIONS];
break;
+ case PIPE_SHADER_VERTEX:
+ case PIPE_SHADER_TESS_CTRL:
+ sel->lds_patch_outputs_written_mask = 0;
+ sel->lds_outputs_written_mask = 0;
+
+ for (i = 0; i < sel->info.num_outputs; i++) {
+ unsigned name = sel->info.output_semantic_name[i];
+ unsigned index = sel->info.output_semantic_index[i];
+
+ switch (name) {
+ case TGSI_SEMANTIC_TESSINNER:
+ case TGSI_SEMANTIC_TESSOUTER:
+ case TGSI_SEMANTIC_PATCH:
+ sel->lds_patch_outputs_written_mask |=
+ 1llu << r600_get_lds_unique_index(name, index);
+ break;
+ default:
+ sel->lds_outputs_written_mask |=
+ 1llu << r600_get_lds_unique_index(name, index);
+ }
+ }
+ break;
+ default:
+ break;
}
return sel;
@@ -883,6 +919,18 @@ static void *r600_create_gs_state(struct pipe_context *ctx,
return r600_create_shader_state(ctx, state, PIPE_SHADER_GEOMETRY);
}
+static void *r600_create_tcs_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *state)
+{
+ return r600_create_shader_state(ctx, state, PIPE_SHADER_TESS_CTRL);
+}
+
+static void *r600_create_tes_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *state)
+{
+ return r600_create_shader_state(ctx, state, PIPE_SHADER_TESS_EVAL);
+}
+
static void r600_bind_ps_state(struct pipe_context *ctx, void *state)
{
struct r600_context *rctx = (struct r600_context *)ctx;
@@ -915,6 +963,24 @@ static void r600_bind_gs_state(struct pipe_context *ctx, void *state)
rctx->b.streamout.stride_in_dw = rctx->gs_shader->so.stride;
}
+static void r600_bind_tcs_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+
+ rctx->tcs_shader = (struct r600_pipe_shader_selector *)state;
+}
+
+static void r600_bind_tes_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+
+ rctx->tes_shader = (struct r600_pipe_shader_selector *)state;
+
+ if (!state)
+ return;
+ rctx->b.streamout.stride_in_dw = rctx->tes_shader->so.stride;
+}
+
static void r600_delete_shader_selector(struct pipe_context *ctx,
struct r600_pipe_shader_selector *sel)
{
@@ -968,6 +1034,29 @@ static void r600_delete_gs_state(struct pipe_context *ctx, void *state)
r600_delete_shader_selector(ctx, sel);
}
+static void r600_delete_tcs_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+ struct r600_pipe_shader_selector *sel = (struct r600_pipe_shader_selector *)state;
+
+ if (rctx->tcs_shader == sel) {
+ rctx->tcs_shader = NULL;
+ }
+
+ r600_delete_shader_selector(ctx, sel);
+}
+
+static void r600_delete_tes_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+ struct r600_pipe_shader_selector *sel = (struct r600_pipe_shader_selector *)state;
+
+ if (rctx->tes_shader == sel) {
+ rctx->tes_shader = NULL;
+ }
+
+ r600_delete_shader_selector(ctx, sel);
+}
void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf_state *state)
{
@@ -1265,23 +1354,105 @@ static void update_gs_block_state(struct r600_context *rctx, unsigned enable)
if (enable) {
r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_GEOMETRY,
R600_GS_RING_CONST_BUFFER, &rctx->gs_rings.esgs_ring);
- r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_VERTEX,
- R600_GS_RING_CONST_BUFFER, &rctx->gs_rings.gsvs_ring);
+ if (rctx->tes_shader) {
+ r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_EVAL,
+ R600_GS_RING_CONST_BUFFER, &rctx->gs_rings.gsvs_ring);
+ } else {
+ r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_VERTEX,
+ R600_GS_RING_CONST_BUFFER, &rctx->gs_rings.gsvs_ring);
+ }
} else {
r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_GEOMETRY,
R600_GS_RING_CONST_BUFFER, NULL);
r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_VERTEX,
R600_GS_RING_CONST_BUFFER, NULL);
+ r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_EVAL,
+ R600_GS_RING_CONST_BUFFER, NULL);
}
}
}
+static void r600_update_clip_state(struct r600_context *rctx,
+ struct r600_pipe_shader *current)
+{
+ if (current->pa_cl_vs_out_cntl != rctx->clip_misc_state.pa_cl_vs_out_cntl ||
+ current->shader.clip_dist_write != rctx->clip_misc_state.clip_dist_write ||
+ current->shader.vs_position_window_space != rctx->clip_misc_state.clip_disable) {
+ rctx->clip_misc_state.pa_cl_vs_out_cntl = current->pa_cl_vs_out_cntl;
+ rctx->clip_misc_state.clip_dist_write = current->shader.clip_dist_write;
+ rctx->clip_misc_state.clip_disable = current->shader.vs_position_window_space;
+ r600_mark_atom_dirty(rctx, &rctx->clip_misc_state.atom);
+ }
+}
+
+static void r600_generate_fixed_func_tcs(struct r600_context *rctx)
+{
+ struct ureg_src const0, const1;
+ struct ureg_dst tessouter, tessinner;
+ struct ureg_program *ureg = ureg_create(TGSI_PROCESSOR_TESS_CTRL);
+
+ if (!ureg)
+ return; /* if we get here, we're screwed */
+
+ assert(!rctx->fixed_func_tcs_shader);
+
+ ureg_DECL_constant2D(ureg, 0, 3, R600_LDS_INFO_CONST_BUFFER);
+ const0 = ureg_src_dimension(ureg_src_register(TGSI_FILE_CONSTANT, 2),
+ R600_LDS_INFO_CONST_BUFFER);
+ const1 = ureg_src_dimension(ureg_src_register(TGSI_FILE_CONSTANT, 3),
+ R600_LDS_INFO_CONST_BUFFER);
+
+ tessouter = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSOUTER, 0);
+ tessinner = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSINNER, 0);
+
+ ureg_MOV(ureg, tessouter, const0);
+ ureg_MOV(ureg, tessinner, const1);
+ ureg_END(ureg);
+
+ rctx->fixed_func_tcs_shader =
+ ureg_create_shader_and_destroy(ureg, &rctx->b.b);
+}
+
+#define SELECT_SHADER_OR_FAIL(x) do { \
+ r600_shader_select(ctx, rctx->x##_shader, &x##_dirty); \
+ if (unlikely(!rctx->x##_shader->current)) \
+ return false; \
+ } while(0)
+
+#define UPDATE_SHADER(hw, sw) do { \
+ if (sw##_dirty || (rctx->hw_shader_stages[(hw)].shader != rctx->sw##_shader->current)) \
+ update_shader_atom(ctx, &rctx->hw_shader_stages[(hw)], rctx->sw##_shader->current); \
+ } while(0)
+
+#define UPDATE_SHADER_CLIP(hw, sw) do { \
+ if (sw##_dirty || (rctx->hw_shader_stages[(hw)].shader != rctx->sw##_shader->current)) { \
+ update_shader_atom(ctx, &rctx->hw_shader_stages[(hw)], rctx->sw##_shader->current); \
+ clip_so_current = rctx->sw##_shader->current; \
+ } \
+ } while(0)
+
+#define UPDATE_SHADER_GS(hw, hw2, sw) do { \
+ if (sw##_dirty || (rctx->hw_shader_stages[(hw)].shader != rctx->sw##_shader->current)) { \
+ update_shader_atom(ctx, &rctx->hw_shader_stages[(hw)], rctx->sw##_shader->current); \
+ update_shader_atom(ctx, &rctx->hw_shader_stages[(hw2)], rctx->sw##_shader->current->gs_copy_shader); \
+ clip_so_current = rctx->sw##_shader->current->gs_copy_shader; \
+ } \
+ } while(0)
+
+#define SET_NULL_SHADER(hw) do { \
+ if (rctx->hw_shader_stages[(hw)].shader) \
+ update_shader_atom(ctx, &rctx->hw_shader_stages[(hw)], NULL); \
+ } while (0)
+
static bool r600_update_derived_state(struct r600_context *rctx)
{
struct pipe_context * ctx = (struct pipe_context*)rctx;
bool ps_dirty = false, vs_dirty = false, gs_dirty = false;
+ bool tcs_dirty = false, tes_dirty = false, fixed_func_tcs_dirty = false;
bool blend_disable;
bool need_buf_const;
+ struct r600_pipe_shader *clip_so_current = NULL;
+
if (!rctx->blitter->running) {
unsigned i;
@@ -1297,76 +1468,84 @@ static bool r600_update_derived_state(struct r600_context *rctx)
}
}
- r600_shader_select(ctx, rctx->ps_shader, &ps_dirty);
- if (unlikely(!rctx->ps_shader->current))
- return false;
+ SELECT_SHADER_OR_FAIL(ps);
+
+ r600_mark_atom_dirty(rctx, &rctx->shader_stages.atom);
update_gs_block_state(rctx, rctx->gs_shader != NULL);
- if (rctx->gs_shader) {
- r600_shader_select(ctx, rctx->gs_shader, &gs_dirty);
- if (unlikely(!rctx->gs_shader->current))
- return false;
+ if (rctx->gs_shader)
+ SELECT_SHADER_OR_FAIL(gs);
+ /* Hull Shader */
+ if (rctx->tcs_shader) {
+ SELECT_SHADER_OR_FAIL(tcs);
+
+ UPDATE_SHADER(EG_HW_STAGE_HS, tcs);
+ } else if (rctx->tes_shader) {
+ if (!rctx->fixed_func_tcs_shader) {
+ r600_generate_fixed_func_tcs(rctx);
+ if (!rctx->fixed_func_tcs_shader)
+ return false;
+
+ }
+ SELECT_SHADER_OR_FAIL(fixed_func_tcs);
+
+ UPDATE_SHADER(EG_HW_STAGE_HS, fixed_func_tcs);
+ } else
+ SET_NULL_SHADER(EG_HW_STAGE_HS);
+
+ if (rctx->tes_shader) {
+ SELECT_SHADER_OR_FAIL(tes);
+ }
+
+ SELECT_SHADER_OR_FAIL(vs);
+
+ if (rctx->gs_shader) {
if (!rctx->shader_stages.geom_enable) {
rctx->shader_stages.geom_enable = true;
r600_mark_atom_dirty(rctx, &rctx->shader_stages.atom);
}
/* gs_shader provides GS and VS (copy shader) */
- if (unlikely(rctx->geometry_shader.shader != rctx->gs_shader->current)) {
- update_shader_atom(ctx, &rctx->geometry_shader, rctx->gs_shader->current);
- update_shader_atom(ctx, &rctx->vertex_shader, rctx->gs_shader->current->gs_copy_shader);
- /* Update clip misc state. */
- if (rctx->gs_shader->current->gs_copy_shader->pa_cl_vs_out_cntl != rctx->clip_misc_state.pa_cl_vs_out_cntl ||
- rctx->gs_shader->current->gs_copy_shader->shader.clip_dist_write != rctx->clip_misc_state.clip_dist_write ||
- rctx->clip_misc_state.clip_disable != rctx->gs_shader->current->shader.vs_position_window_space) {
- rctx->clip_misc_state.pa_cl_vs_out_cntl = rctx->gs_shader->current->gs_copy_shader->pa_cl_vs_out_cntl;
- rctx->clip_misc_state.clip_dist_write = rctx->gs_shader->current->gs_copy_shader->shader.clip_dist_write;
- rctx->clip_misc_state.clip_disable = rctx->gs_shader->current->shader.vs_position_window_space;
- r600_mark_atom_dirty(rctx, &rctx->clip_misc_state.atom);
- }
- rctx->b.streamout.enabled_stream_buffers_mask = rctx->gs_shader->current->gs_copy_shader->enabled_stream_buffers_mask;
- }
-
- r600_shader_select(ctx, rctx->vs_shader, &vs_dirty);
- if (unlikely(!rctx->vs_shader->current))
- return false;
+ UPDATE_SHADER_GS(R600_HW_STAGE_GS, R600_HW_STAGE_VS, gs);
/* vs_shader is used as ES */
- if (unlikely(vs_dirty || rctx->export_shader.shader != rctx->vs_shader->current)) {
- update_shader_atom(ctx, &rctx->export_shader, rctx->vs_shader->current);
+
+ if (rctx->tes_shader) {
+ /* VS goes to LS, TES goes to ES */
+ UPDATE_SHADER(R600_HW_STAGE_ES, tes);
+ UPDATE_SHADER(EG_HW_STAGE_LS, vs);
+ } else {
+ /* vs_shader is used as ES */
+ UPDATE_SHADER(R600_HW_STAGE_ES, vs);
+ SET_NULL_SHADER(EG_HW_STAGE_LS);
}
} else {
- if (unlikely(rctx->geometry_shader.shader)) {
- update_shader_atom(ctx, &rctx->geometry_shader, NULL);
- update_shader_atom(ctx, &rctx->export_shader, NULL);
+ if (unlikely(rctx->hw_shader_stages[R600_HW_STAGE_GS].shader)) {
+ SET_NULL_SHADER(R600_HW_STAGE_GS);
+ SET_NULL_SHADER(R600_HW_STAGE_ES);
rctx->shader_stages.geom_enable = false;
r600_mark_atom_dirty(rctx, &rctx->shader_stages.atom);
}
- r600_shader_select(ctx, rctx->vs_shader, &vs_dirty);
- if (unlikely(!rctx->vs_shader->current))
- return false;
-
- if (unlikely(vs_dirty || rctx->vertex_shader.shader != rctx->vs_shader->current)) {
- update_shader_atom(ctx, &rctx->vertex_shader, rctx->vs_shader->current);
-
- /* Update clip misc state. */
- if (rctx->vs_shader->current->pa_cl_vs_out_cntl != rctx->clip_misc_state.pa_cl_vs_out_cntl ||
- rctx->vs_shader->current->shader.clip_dist_write != rctx->clip_misc_state.clip_dist_write ||
- rctx->clip_misc_state.clip_disable != rctx->vs_shader->current->shader.vs_position_window_space) {
- rctx->clip_misc_state.pa_cl_vs_out_cntl = rctx->vs_shader->current->pa_cl_vs_out_cntl;
- rctx->clip_misc_state.clip_dist_write = rctx->vs_shader->current->shader.clip_dist_write;
- rctx->clip_misc_state.clip_disable = rctx->vs_shader->current->shader.vs_position_window_space;
- r600_mark_atom_dirty(rctx, &rctx->clip_misc_state.atom);
- }
- rctx->b.streamout.enabled_stream_buffers_mask = rctx->vs_shader->current->enabled_stream_buffers_mask;
+ if (rctx->tes_shader) {
+ /* if TES is loaded and no geometry, TES runs on hw VS, VS runs on hw LS */
+ UPDATE_SHADER_CLIP(R600_HW_STAGE_VS, tes);
+ UPDATE_SHADER(EG_HW_STAGE_LS, vs);
+ } else {
+ SET_NULL_SHADER(EG_HW_STAGE_LS);
+ UPDATE_SHADER_CLIP(R600_HW_STAGE_VS, vs);
}
}
+ /* Update clip misc state. */
+ if (clip_so_current) {
+ r600_update_clip_state(rctx, clip_so_current);
+ rctx->b.streamout.enabled_stream_buffers_mask = clip_so_current->enabled_stream_buffers_mask;
+ }
- if (unlikely(ps_dirty || rctx->pixel_shader.shader != rctx->ps_shader->current ||
+ if (unlikely(ps_dirty || rctx->hw_shader_stages[R600_HW_STAGE_PS].shader != rctx->ps_shader->current ||
rctx->rasterizer->sprite_coord_enable != rctx->ps_shader->current->sprite_coord_enable ||
rctx->rasterizer->flatshade != rctx->ps_shader->current->flatshade)) {
@@ -1395,8 +1574,8 @@ static bool r600_update_derived_state(struct r600_context *rctx)
}
r600_mark_atom_dirty(rctx, &rctx->shader_stages.atom);
- update_shader_atom(ctx, &rctx->pixel_shader, rctx->ps_shader->current);
}
+ UPDATE_SHADER(R600_HW_STAGE_PS, ps);
if (rctx->b.chip_class >= EVERGREEN) {
evergreen_update_db_shader_control(rctx);
@@ -1445,6 +1624,13 @@ static bool r600_update_derived_state(struct r600_context *rctx)
}
}
+ if (rctx->b.chip_class == EVERGREEN) {
+ if (!evergreen_adjust_gprs(rctx)) {
+ /* discard rendering */
+ return false;
+ }
+ }
+
blend_disable = (rctx->dual_src_blend &&
rctx->ps_shader->current->nr_ps_color_outputs < 2);
@@ -1480,6 +1666,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
bool render_cond_bit = rctx->b.render_cond && !rctx->b.render_cond_force_off;
uint64_t mask;
+ unsigned num_patches;
if (!info.indirect && !info.count && (info.indexed || !info.count_from_stream_output)) {
return;
@@ -1585,6 +1772,9 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom);
}
+ if (rctx->b.chip_class >= EVERGREEN)
+ evergreen_setup_tess_constants(rctx, &info, &num_patches);
+
/* Emit states. */
r600_need_cs_space(rctx, ib.user_buffer ? 5 : 0, TRUE);
r600_flush_emit(rctx);
@@ -1618,6 +1808,14 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
S_028AA8_PRIMGROUP_SIZE(primgroup_size - 1));
}
+ if (rctx->b.chip_class >= EVERGREEN) {
+ uint32_t ls_hs_config = evergreen_get_ls_hs_config(rctx, &info,
+ num_patches);
+
+ evergreen_set_ls_hs_config(rctx, cs, ls_hs_config);
+ evergreen_set_lds_alloc(rctx, cs, rctx->lds_alloc);
+ }
+
/* On R6xx, CULL_FRONT=1 culls all points, lines, and rectangles,
* even though it should have no effect on those. */
if (rctx->b.chip_class == R600 && rctx->rasterizer) {
@@ -1770,6 +1968,24 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
(info.count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0);
}
+ /* SMX returns CONTEXT_DONE too early workaround */
+ if (rctx->b.family == CHIP_R600 ||
+ rctx->b.family == CHIP_RV610 ||
+ rctx->b.family == CHIP_RV630 ||
+ rctx->b.family == CHIP_RV635) {
+ /* if we have gs shader or streamout
+ we need to do a wait idle after every draw */
+ if (rctx->gs_shader || rctx->b.streamout.streamout_enabled) {
+ radeon_set_config_reg(cs, R_008040_WAIT_UNTIL, S_008040_WAIT_3D_IDLE(1));
+ }
+ }
+
+ /* ES ring rolling over at EOP - workaround */
+ if (rctx->b.chip_class == R600) {
+ cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
+ cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SQ_NON_EVENT);
+ }
+
if (rctx->screen->b.trace_bo) {
r600_trace_emit(rctx);
}
@@ -2632,6 +2848,8 @@ void r600_init_common_state_functions(struct r600_context *rctx)
rctx->b.b.create_fs_state = r600_create_ps_state;
rctx->b.b.create_vs_state = r600_create_vs_state;
rctx->b.b.create_gs_state = r600_create_gs_state;
+ rctx->b.b.create_tcs_state = r600_create_tcs_state;
+ rctx->b.b.create_tes_state = r600_create_tes_state;
rctx->b.b.create_vertex_elements_state = r600_create_vertex_fetch_shader;
rctx->b.b.bind_blend_state = r600_bind_blend_state;
rctx->b.b.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
@@ -2641,6 +2859,8 @@ void r600_init_common_state_functions(struct r600_context *rctx)
rctx->b.b.bind_vertex_elements_state = r600_bind_vertex_elements;
rctx->b.b.bind_vs_state = r600_bind_vs_state;
rctx->b.b.bind_gs_state = r600_bind_gs_state;
+ rctx->b.b.bind_tcs_state = r600_bind_tcs_state;
+ rctx->b.b.bind_tes_state = r600_bind_tes_state;
rctx->b.b.delete_blend_state = r600_delete_blend_state;
rctx->b.b.delete_depth_stencil_alpha_state = r600_delete_dsa_state;
rctx->b.b.delete_fs_state = r600_delete_ps_state;
@@ -2649,6 +2869,8 @@ void r600_init_common_state_functions(struct r600_context *rctx)
rctx->b.b.delete_vertex_elements_state = r600_delete_vertex_elements;
rctx->b.b.delete_vs_state = r600_delete_vs_state;
rctx->b.b.delete_gs_state = r600_delete_gs_state;
+ rctx->b.b.delete_tcs_state = r600_delete_tcs_state;
+ rctx->b.b.delete_tes_state = r600_delete_tes_state;
rctx->b.b.set_blend_color = r600_set_blend_color;
rctx->b.b.set_clip_state = r600_set_clip_state;
rctx->b.b.set_constant_buffer = r600_set_constant_buffer;
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index 53f5ad6db6a..3d223edb5f4 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -130,6 +130,7 @@
#define EVENT_TYPE_SAMPLE_STREAMOUTSTATS 0x20
#define EVENT_TYPE_FLUSH_AND_INV_DB_META 0x2c /* supported on r700+ */
#define EVENT_TYPE_VGT_FLUSH 0x24
+#define EVENT_TYPE_SQ_NON_EVENT 0x26
#define EVENT_TYPE_FLUSH_AND_INV_CB_META 46 /* supported on r700+ */
#define EVENT_TYPE(x) ((x) << 0)
#define EVENT_INDEX(x) ((x) << 8)
@@ -1367,7 +1368,7 @@
#define V_008958_DI_PT_TRISTRIP 0x00000006
#define V_008958_DI_PT_UNUSED_0 0x00000007
#define V_008958_DI_PT_UNUSED_1 0x00000008
-#define V_008958_DI_PT_UNUSED_2 0x00000009
+#define V_008958_DI_PT_PATCH 0x00000009
#define V_008958_DI_PT_LINELIST_ADJ 0x0000000A
#define V_008958_DI_PT_LINESTRIP_ADJ 0x0000000B
#define V_008958_DI_PT_TRILIST_ADJ 0x0000000C
diff --git a/src/gallium/drivers/r600/sb/sb_bc.h b/src/gallium/drivers/r600/sb/sb_bc.h
index 9c2a9170436..696160098b5 100644
--- a/src/gallium/drivers/r600/sb/sb_bc.h
+++ b/src/gallium/drivers/r600/sb/sb_bc.h
@@ -174,6 +174,8 @@ enum shader_target
TARGET_GS_COPY,
TARGET_COMPUTE,
TARGET_FETCH,
+ TARGET_HS,
+ TARGET_LS,
TARGET_NUM
};
@@ -518,6 +520,8 @@ struct bc_alu {
unsigned slot:3;
+ unsigned lds_idx_offset:6;
+
alu_op_flags slot_flags;
void set_op(unsigned op) {
@@ -536,10 +540,12 @@ struct bc_fetch {
unsigned src_gpr:7;
unsigned src_rel:1;
+ unsigned src_rel_global:1; /* for GDS ops */
unsigned src_sel[4];
unsigned dst_gpr:7;
unsigned dst_rel:1;
+ unsigned dst_rel_global:1; /* for GDS ops */
unsigned dst_sel[4];
unsigned alt_const:1;
@@ -573,6 +579,7 @@ struct bc_fetch {
unsigned endian_swap:2;
unsigned mega_fetch:1;
+ unsigned src2_gpr:7; /* for GDS */
void set_op(unsigned op) { this->op = op; op_ptr = r600_isa_fetch(op); }
};
@@ -739,6 +746,7 @@ private:
int decode_cf_mem(unsigned &i, bc_cf &bc);
int decode_fetch_vtx(unsigned &i, bc_fetch &bc);
+ int decode_fetch_gds(unsigned &i, bc_fetch &bc);
};
// bytecode format definition
diff --git a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp
index 55e2a8508ec..5dec169bac9 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp
@@ -371,6 +371,37 @@ int bc_builder::build_alu(alu_node* n) {
const bc_alu &bc = n->bc;
const alu_op_info *aop = bc.op_ptr;
+ if (n->bc.op_ptr->flags & AF_LDS) {
+ assert(ctx.is_egcm());
+ bb << ALU_WORD0_LDS_IDX_OP_EGCM()
+ .SRC0_SEL(bc.src[0].sel)
+ .SRC0_REL(bc.src[0].rel)
+ .SRC0_CHAN(bc.src[0].chan)
+ .IDX_OFFSET_4((bc.lds_idx_offset >> 4) & 1)
+ .SRC1_SEL(bc.src[1].sel)
+ .SRC1_REL(bc.src[1].rel)
+ .SRC1_CHAN(bc.src[1].chan)
+ .IDX_OFFSET_5((bc.lds_idx_offset >> 5) & 1)
+ .INDEX_MODE(bc.index_mode)
+ .PRED_SEL(bc.pred_sel)
+ .LAST(bc.last);
+
+ bb << ALU_WORD1_LDS_IDX_OP_EGCM()
+ .SRC2_SEL(bc.src[2].sel)
+ .SRC2_REL(bc.src[2].rel)
+ .SRC2_CHAN(bc.src[2].chan)
+ .IDX_OFFSET_1((bc.lds_idx_offset >> 1) & 1)
+ .ALU_INST(ctx.alu_opcode(ALU_OP3_LDS_IDX_OP))
+ .BANK_SWIZZLE(bc.bank_swizzle)
+ .LDS_OP((bc.op_ptr->opcode[1] >> 8) & 0xff)
+ .IDX_OFFSET_0((bc.lds_idx_offset >> 0) & 1)
+ .IDX_OFFSET_2((bc.lds_idx_offset >> 2) & 1)
+ .DST_CHAN(bc.dst_chan)
+ .IDX_OFFSET_3((bc.lds_idx_offset >> 3) & 1);
+
+ return 0;
+ }
+
bb << ALU_WORD0_ALL()
.INDEX_MODE(bc.index_mode)
.LAST(bc.last)
diff --git a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
index 5fe8f50aa4c..1832e2d3e6a 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
@@ -310,16 +310,53 @@ int bc_decoder::decode_alu(unsigned & i, bc_alu& bc) {
ALU_WORD1_OP3_ALL w1(dw1);
bc.set_op(r600_isa_alu_by_opcode(ctx.isa, w1.get_ALU_INST(), 1));
- bc.bank_swizzle = w1.get_BANK_SWIZZLE();
- bc.clamp = w1.get_CLAMP();
- bc.dst_chan = w1.get_DST_CHAN();
- bc.dst_gpr = w1.get_DST_GPR();
- bc.dst_rel = w1.get_DST_REL();
+ if (bc.op == ALU_OP3_LDS_IDX_OP) {
+ ALU_WORD0_LDS_IDX_OP_EGCM iw0(dw0);
+ ALU_WORD1_LDS_IDX_OP_EGCM iw1(dw1);
+ bc.index_mode = iw0.get_INDEX_MODE();
+ bc.last = iw0.get_LAST();
+ bc.pred_sel = iw0.get_PRED_SEL();
+ bc.src[0].chan = iw0.get_SRC0_CHAN();
+ bc.src[0].sel = iw0.get_SRC0_SEL();
+ bc.src[0].rel = iw0.get_SRC0_REL();
- bc.src[2].chan = w1.get_SRC2_CHAN();
- bc.src[2].sel = w1.get_SRC2_SEL();
- bc.src[2].neg = w1.get_SRC2_NEG();
- bc.src[2].rel = w1.get_SRC2_REL();
+ bc.src[1].chan = iw0.get_SRC1_CHAN();
+ bc.src[1].sel = iw0.get_SRC1_SEL();
+ bc.src[1].rel = iw0.get_SRC1_REL();
+
+ bc.bank_swizzle = iw1.get_BANK_SWIZZLE();
+ bc.src[2].chan = iw1.get_SRC2_CHAN();
+ bc.src[2].sel = iw1.get_SRC2_SEL();
+ bc.src[2].rel = iw1.get_SRC2_REL();
+ bc.dst_chan = iw1.get_DST_CHAN();
+ // TODO: clean up
+ for (size_t k = 0; k < sizeof(alu_op_table) / sizeof(alu_op_table[0]); k++) {
+ if (((alu_op_table[k].opcode[1] >> 8) & 0xff) == iw1.get_LDS_OP()) {
+ bc.op_ptr = &alu_op_table[k];
+ bc.op = k;
+ break;
+ }
+ }
+ bc.lds_idx_offset =
+ (iw0.get_IDX_OFFSET_4() << 4) |
+ (iw0.get_IDX_OFFSET_5() << 5) |
+ (iw1.get_IDX_OFFSET_1() << 1) |
+ (iw1.get_IDX_OFFSET_0() << 0) |
+ (iw1.get_IDX_OFFSET_2() << 2) |
+ (iw1.get_IDX_OFFSET_3() << 3);
+ }
+ else {
+ bc.bank_swizzle = w1.get_BANK_SWIZZLE();
+ bc.clamp = w1.get_CLAMP();
+ bc.dst_chan = w1.get_DST_CHAN();
+ bc.dst_gpr = w1.get_DST_GPR();
+ bc.dst_rel = w1.get_DST_REL();
+
+ bc.src[2].chan = w1.get_SRC2_CHAN();
+ bc.src[2].sel = w1.get_SRC2_SEL();
+ bc.src[2].neg = w1.get_SRC2_NEG();
+ bc.src[2].rel = w1.get_SRC2_REL();
+ }
} else { // op2
if (ctx.is_r600()) {
@@ -373,7 +410,20 @@ int bc_decoder::decode_fetch(unsigned & i, bc_fetch& bc) {
unsigned fetch_opcode = dw0 & 0x1F;
- bc.set_op(r600_isa_fetch_by_opcode(ctx.isa, fetch_opcode));
+ if (fetch_opcode == 2) { // MEM_INST_MEM
+ unsigned mem_op = (dw0 >> 8) & 0x7;
+ unsigned gds_op;
+ if (mem_op == 4) {
+ gds_op = (dw1 >> 9) & 0x1f;
+ fetch_opcode = FETCH_OP_GDS_ADD + gds_op;
+ } else if (mem_op == 5)
+ fetch_opcode = FETCH_OP_TF_WRITE;
+ bc.set_op(fetch_opcode);
+ } else
+ bc.set_op(r600_isa_fetch_by_opcode(ctx.isa, fetch_opcode));
+
+ if (bc.op_ptr->flags & FF_GDS)
+ return decode_fetch_gds(i, bc);
if (bc.op_ptr->flags & FF_VTX)
return decode_fetch_vtx(i, bc);
@@ -439,6 +489,38 @@ int bc_decoder::decode_fetch(unsigned & i, bc_fetch& bc) {
return r;
}
+int bc_decoder::decode_fetch_gds(unsigned & i, bc_fetch& bc) {
+ int r = 0;
+ uint32_t dw0 = dw[i];
+ uint32_t dw1 = dw[i+1];
+ uint32_t dw2 = dw[i+2];
+ uint32_t tmp;
+ /* GDS instructions align to 4 words boundaries */
+ i+= 4;
+ assert(i <= ndw);
+
+ MEM_GDS_WORD0_EGCM w0(dw0);
+ bc.src_gpr = w0.get_SRC_GPR();
+ tmp = w0.get_SRC_REL_MODE();
+ bc.src_rel_global = (tmp == 2);
+ bc.src_sel[0] = w0.get_SRC_SEL_X();
+ bc.src_sel[1] = w0.get_SRC_SEL_Y();
+ bc.src_sel[2] = w0.get_SRC_SEL_Z();
+
+ MEM_GDS_WORD1_EGCM w1(dw1);
+ bc.dst_gpr = w1.get_DST_GPR();
+ tmp = w1.get_DST_REL_MODE();
+ bc.dst_rel_global = (tmp == 2);
+ bc.src2_gpr = w1.get_SRC_GPR();
+
+ MEM_GDS_WORD2_EGCM w2(dw2);
+ bc.dst_sel[0] = w2.get_DST_SEL_X();
+ bc.dst_sel[1] = w2.get_DST_SEL_Y();
+ bc.dst_sel[2] = w2.get_DST_SEL_Z();
+ bc.dst_sel[3] = w2.get_DST_SEL_W();
+ return r;
+}
+
int bc_decoder::decode_fetch_vtx(unsigned & i, bc_fetch& bc) {
int r = 0;
uint32_t dw0 = dw[i];
diff --git a/src/gallium/drivers/r600/sb/sb_bc_dump.cpp b/src/gallium/drivers/r600/sb/sb_bc_dump.cpp
index 3c70ea7cd3d..788450b3c9c 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_dump.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_dump.cpp
@@ -280,6 +280,28 @@ static void print_src(sb_ostream &s, bc_alu &alu, unsigned idx)
need_sel = 0;
need_chan = 0;
switch (sel) {
+ case ALU_SRC_LDS_OQ_A:
+ s << "LDS_OQ_A";
+ need_chan = 1;
+ break;
+ case ALU_SRC_LDS_OQ_B:
+ s << "LDS_OQ_B";
+ need_chan = 1;
+ break;
+ case ALU_SRC_LDS_OQ_A_POP:
+ s << "LDS_OQ_A_POP";
+ need_chan = 1;
+ break;
+ case ALU_SRC_LDS_OQ_B_POP:
+ s << "LDS_OQ_B_POP";
+ need_chan = 1;
+ break;
+ case ALU_SRC_LDS_DIRECT_A:
+ s << "LDS_A["; s.print_zw_hex(src->value.u, 8); s << "]";
+ break;
+ case ALU_SRC_LDS_DIRECT_B:
+ s << "LDS_B["; s.print_zw_hex(src->value.u, 8); s << "]";
+ break;
case ALU_SRC_PS:
s << "PS";
break;
@@ -363,6 +385,10 @@ void bc_dump::dump(alu_node& n) {
}
}
+ if (n.bc.lds_idx_offset) {
+ s << " IDX_OFFSET:" << n.bc.lds_idx_offset;
+ }
+
sblog << s.str() << "\n";
}
@@ -425,23 +451,26 @@ bc_dump::bc_dump(shader& s, bytecode* bc) :
void bc_dump::dump(fetch_node& n) {
sb_ostringstream s;
static const char * fetch_type[] = {"VERTEX", "INSTANCE", ""};
+ unsigned gds = n.bc.op_ptr->flags & FF_GDS;
s << n.bc.op_ptr->name;
fill_to(s, 20);
- s << "R";
- print_sel(s, n.bc.dst_gpr, n.bc.dst_rel, INDEX_LOOP, 0);
- s << ".";
- for (int k = 0; k < 4; ++k)
- s << chans[n.bc.dst_sel[k]];
- s << ", ";
+ if (!gds) {
+ s << "R";
+ print_sel(s, n.bc.dst_gpr, n.bc.dst_rel, INDEX_LOOP, 0);
+ s << ".";
+ for (int k = 0; k < 4; ++k)
+ s << chans[n.bc.dst_sel[k]];
+ s << ", ";
+ }
s << "R";
print_sel(s, n.bc.src_gpr, n.bc.src_rel, INDEX_LOOP, 0);
s << ".";
unsigned vtx = n.bc.op_ptr->flags & FF_VTX;
- unsigned num_src_comp = vtx ? ctx.is_cayman() ? 2 : 1 : 4;
+ unsigned num_src_comp = gds ? 3 : vtx ? ctx.is_cayman() ? 2 : 1 : 4;
for (unsigned k = 0; k < num_src_comp; ++k)
s << chans[n.bc.src_sel[k]];
@@ -450,9 +479,12 @@ void bc_dump::dump(fetch_node& n) {
s << " + " << n.bc.offset[0] << "b ";
}
- s << ", RID:" << n.bc.resource_id;
+ if (!gds)
+ s << ", RID:" << n.bc.resource_id;
- if (vtx) {
+ if (gds) {
+
+ } else if (vtx) {
s << " " << fetch_type[n.bc.fetch_type];
if (!ctx.is_cayman() && n.bc.mega_fetch_count)
s << " MFC:" << n.bc.mega_fetch_count;
diff --git a/src/gallium/drivers/r600/sb/sb_bc_fmt_def.inc b/src/gallium/drivers/r600/sb/sb_bc_fmt_def.inc
index 50f73d7df3b..b30baf09bc5 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_fmt_def.inc
+++ b/src/gallium/drivers/r600/sb/sb_bc_fmt_def.inc
@@ -541,3 +541,31 @@ BC_FIELD(TEX_WORD2, SRC_SEL_Y, SSY, 25, 23)
BC_FIELD(TEX_WORD2, SRC_SEL_Z, SSZ, 28, 26)
BC_FIELD(TEX_WORD2, SRC_SEL_W, SSW, 31, 29)
BC_FORMAT_END(TEX_WORD2)
+
+BC_FORMAT_BEGIN_HW(MEM_GDS_WORD0, EGCM)
+BC_FIELD(MEM_GDS_WORD0, MEM_INST, M_INST, 4, 0)
+BC_FIELD(MEM_GDS_WORD0, MEM_OP, M_OP, 10, 8)
+BC_FIELD(MEM_GDS_WORD0, SRC_GPR, S_GPR, 17, 11)
+BC_FIELD(MEM_GDS_WORD0, SRC_REL_MODE, SRM, 19, 18)
+BC_FIELD(MEM_GDS_WORD0, SRC_SEL_X, SSX, 22, 20)
+BC_FIELD(MEM_GDS_WORD0, SRC_SEL_Y, SSY, 25, 23)
+BC_FIELD(MEM_GDS_WORD0, SRC_SEL_Z, SSZ, 28, 26)
+BC_FORMAT_END(MEM_GDS_WORD0)
+
+BC_FORMAT_BEGIN_HW(MEM_GDS_WORD1, EGCM)
+BC_FIELD(MEM_GDS_WORD1, DST_GPR, D_GPR, 6, 0)
+BC_FIELD(MEM_GDS_WORD1, DST_REL_MODE, DRM, 8, 7)
+BC_FIELD(MEM_GDS_WORD1, GDS_OP, G_OP, 14, 9)
+BC_FIELD(MEM_GDS_WORD1, SRC_GPR, S_GPR, 22, 16)
+BC_FIELD(MEM_GDS_WORD1, UAV_INDEX_MODE, U_IM, 25, 24)
+BC_FIELD(MEM_GDS_WORD1, UAV_ID, U_ID, 29, 26)
+BC_FIELD(MEM_GDS_WORD1, ALLOC_CONSUME, AC, 30, 30)
+BC_FIELD(MEM_GDS_WORD1, BCARD_FIRST_REQ, BFR, 31, 31)
+BC_FORMAT_END(MEM_GDS_WORD1)
+
+BC_FORMAT_BEGIN_HW(MEM_GDS_WORD2, EGCM)
+BC_FIELD(MEM_GDS_WORD2, DST_SEL_X, DSX, 2, 0)
+BC_FIELD(MEM_GDS_WORD2, DST_SEL_Y, DSY, 5, 3)
+BC_FIELD(MEM_GDS_WORD2, DST_SEL_Z, DSZ, 8, 6)
+BC_FIELD(MEM_GDS_WORD2, DST_SEL_W, DSW, 11, 9)
+BC_FORMAT_END(MEM_GDS_WORD2)
\ No newline at end of file
diff --git a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
index 28ebfa2ce62..65aa801fb79 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
@@ -58,10 +58,12 @@ int bc_parser::decode() {
switch (bc->type) {
case TGSI_PROCESSOR_FRAGMENT: t = TARGET_PS; break;
case TGSI_PROCESSOR_VERTEX:
- t = pshader->vs_as_es ? TARGET_ES : TARGET_VS;
+ t = pshader->vs_as_ls ? TARGET_LS : (pshader->vs_as_es ? TARGET_ES : TARGET_VS);
break;
case TGSI_PROCESSOR_GEOMETRY: t = TARGET_GS; break;
case TGSI_PROCESSOR_COMPUTE: t = TARGET_COMPUTE; break;
+ case TGSI_PROCESSOR_TESS_CTRL: t = TARGET_HS; break;
+ case TGSI_PROCESSOR_TESS_EVAL: t = pshader->tes_as_es ? TARGET_ES : TARGET_VS; break;
default: assert(!"unknown shader target"); return -1; break;
}
} else {
@@ -146,7 +148,7 @@ int bc_parser::parse_decls() {
}
}
- if (sh->target == TARGET_VS || sh->target == TARGET_ES)
+ if (sh->target == TARGET_VS || sh->target == TARGET_ES || sh->target == TARGET_HS)
sh->add_input(0, 1, 0x0F);
else if (sh->target == TARGET_GS) {
sh->add_input(0, 1, 0x0F);
diff --git a/src/gallium/drivers/r600/sb/sb_shader.cpp b/src/gallium/drivers/r600/sb/sb_shader.cpp
index 87e28e98157..8c7b39bb03f 100644
--- a/src/gallium/drivers/r600/sb/sb_shader.cpp
+++ b/src/gallium/drivers/r600/sb/sb_shader.cpp
@@ -215,7 +215,7 @@ void shader::init() {
void shader::init_call_fs(cf_node* cf) {
unsigned gpr = 0;
- assert(target == TARGET_VS || target == TARGET_ES);
+ assert(target == TARGET_LS || target == TARGET_VS || target == TARGET_ES);
for(inputs_vec::const_iterator I = inputs.begin(),
E = inputs.end(); I != E; ++I, ++gpr) {
@@ -436,6 +436,8 @@ const char* shader::get_shader_target_name() {
case TARGET_ES: return "ES";
case TARGET_PS: return "PS";
case TARGET_GS: return "GS";
+ case TARGET_HS: return "HS";
+ case TARGET_LS: return "LS";
case TARGET_COMPUTE: return "COMPUTE";
case TARGET_FETCH: return "FETCH";
default:
diff --git a/src/gallium/drivers/radeon/Makefile.sources b/src/gallium/drivers/radeon/Makefile.sources
index 1dbad2f39e3..eb171f7da5f 100644
--- a/src/gallium/drivers/radeon/Makefile.sources
+++ b/src/gallium/drivers/radeon/Makefile.sources
@@ -4,6 +4,7 @@ C_SOURCES := \
r600_cs.h \
r600d_common.h \
r600_gpu_load.c \
+ r600_perfcounter.c \
r600_pipe_common.c \
r600_pipe_common.h \
r600_query.c \
diff --git a/src/gallium/drivers/radeon/r600_perfcounter.c b/src/gallium/drivers/radeon/r600_perfcounter.c
new file mode 100644
index 00000000000..a835aee993b
--- /dev/null
+++ b/src/gallium/drivers/radeon/r600_perfcounter.c
@@ -0,0 +1,648 @@
+/*
+ * Copyright 2015 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.
+ *
+ * Authors:
+ * Nicolai Hähnle
+ *
+ */
+
+#include "util/u_memory.h"
+#include "r600_query.h"
+#include "r600_pipe_common.h"
+#include "r600d_common.h"
+
+/* Max counters per HW block */
+#define R600_QUERY_MAX_COUNTERS 16
+
+static const char * const r600_pc_shader_suffix[] = {
+ "", "_PS", "_VS", "_GS", "_ES", "_HS", "_LS", "_CS"
+};
+
+static struct r600_perfcounter_block *
+lookup_counter(struct r600_perfcounters *pc, unsigned index,
+ unsigned *base_gid, unsigned *sub_index)
+{
+ struct r600_perfcounter_block *block = pc->blocks;
+ unsigned bid;
+
+ *base_gid = 0;
+ for (bid = 0; bid < pc->num_blocks; ++bid, ++block) {
+ unsigned total = block->num_groups * block->num_selectors;
+
+ if (index < total) {
+ *sub_index = index;
+ return block;
+ }
+
+ index -= total;
+ *base_gid += block->num_groups;
+ }
+
+ return NULL;
+}
+
+static struct r600_perfcounter_block *
+lookup_group(struct r600_perfcounters *pc, unsigned *index)
+{
+ unsigned bid;
+ struct r600_perfcounter_block *block = pc->blocks;
+
+ for (bid = 0; bid < pc->num_blocks; ++bid, ++block) {
+ if (*index < block->num_groups)
+ return block;
+ *index -= block->num_groups;
+ }
+
+ return NULL;
+}
+
+struct r600_pc_group {
+ struct r600_pc_group *next;
+ struct r600_perfcounter_block *block;
+ unsigned sub_gid; /* only used during init */
+ unsigned result_base; /* only used during init */
+ int se;
+ int instance;
+ unsigned num_counters;
+ unsigned selectors[R600_QUERY_MAX_COUNTERS];
+};
+
+struct r600_pc_counter {
+ unsigned base;
+ unsigned dwords;
+ unsigned stride;
+};
+
+struct r600_query_pc {
+ struct r600_query_hw b;
+
+ unsigned shaders;
+ unsigned num_counters;
+ struct r600_pc_counter *counters;
+ struct r600_pc_group *groups;
+};
+
+static void r600_pc_query_destroy(struct r600_common_context *ctx,
+ struct r600_query *rquery)
+{
+ struct r600_query_pc *query = (struct r600_query_pc *)rquery;
+
+ while (query->groups) {
+ struct r600_pc_group *group = query->groups;
+ query->groups = group->next;
+ FREE(group);
+ }
+
+ FREE(query->counters);
+
+ r600_query_hw_destroy(ctx, rquery);
+}
+
+static void r600_pc_query_emit_start(struct r600_common_context *ctx,
+ struct r600_query_hw *hwquery,
+ struct r600_resource *buffer, uint64_t va)
+{
+ struct r600_perfcounters *pc = ctx->screen->perfcounters;
+ struct r600_query_pc *query = (struct r600_query_pc *)hwquery;
+ struct r600_pc_group *group;
+ int current_se = -1;
+ int current_instance = -1;
+
+ if (query->shaders)
+ pc->emit_shaders(ctx, query->shaders);
+
+ for (group = query->groups; group; group = group->next) {
+ struct r600_perfcounter_block *block = group->block;
+
+ if (group->se != current_se || group->instance != current_instance) {
+ current_se = group->se;
+ current_instance = group->instance;
+ pc->emit_instance(ctx, group->se, group->instance);
+ }
+
+ pc->emit_select(ctx, block, group->num_counters, group->selectors);
+ }
+
+ if (current_se != -1 || current_instance != -1)
+ pc->emit_instance(ctx, -1, -1);
+
+ pc->emit_start(ctx, buffer, va);
+}
+
+static void r600_pc_query_emit_stop(struct r600_common_context *ctx,
+ struct r600_query_hw *hwquery,
+ struct r600_resource *buffer, uint64_t va)
+{
+ struct r600_perfcounters *pc = ctx->screen->perfcounters;
+ struct r600_query_pc *query = (struct r600_query_pc *)hwquery;
+ struct r600_pc_group *group;
+
+ pc->emit_stop(ctx, buffer, va);
+
+ for (group = query->groups; group; group = group->next) {
+ struct r600_perfcounter_block *block = group->block;
+ unsigned se = group->se >= 0 ? group->se : 0;
+ unsigned se_end = se + 1;
+
+ if ((block->flags & R600_PC_BLOCK_SE) && (group->se < 0))
+ se_end = ctx->screen->info.max_se;
+
+ do {
+ unsigned instance = group->instance >= 0 ? group->instance : 0;
+
+ do {
+ pc->emit_instance(ctx, se, instance);
+ pc->emit_read(ctx, block,
+ group->num_counters, group->selectors,
+ buffer, va);
+ va += 4 * group->num_counters;
+ } while (group->instance < 0 && ++instance < block->num_instances);
+ } while (++se < se_end);
+ }
+
+ pc->emit_instance(ctx, -1, -1);
+}
+
+static void r600_pc_query_clear_result(struct r600_query_hw *hwquery,
+ union pipe_query_result *result)
+{
+ struct r600_query_pc *query = (struct r600_query_pc *)hwquery;
+
+ memset(result, 0, sizeof(result->batch[0]) * query->num_counters);
+}
+
+static void r600_pc_query_add_result(struct r600_common_context *ctx,
+ struct r600_query_hw *hwquery,
+ void *buffer,
+ union pipe_query_result *result)
+{
+ struct r600_query_pc *query = (struct r600_query_pc *)hwquery;
+ uint32_t *results = buffer;
+ unsigned i, j;
+
+ for (i = 0; i < query->num_counters; ++i) {
+ struct r600_pc_counter *counter = &query->counters[i];
+
+ if (counter->base == ~0)
+ continue;
+
+ for (j = 0; j < counter->dwords; ++j) {
+ uint32_t value = results[counter->base + j * counter->stride];
+ result->batch[i].u32 += value;
+ }
+ }
+}
+
+static struct r600_query_ops batch_query_ops = {
+ .destroy = r600_pc_query_destroy,
+ .begin = r600_query_hw_begin,
+ .end = r600_query_hw_end,
+ .get_result = r600_query_hw_get_result
+};
+
+static struct r600_query_hw_ops batch_query_hw_ops = {
+ .emit_start = r600_pc_query_emit_start,
+ .emit_stop = r600_pc_query_emit_stop,
+ .clear_result = r600_pc_query_clear_result,
+ .add_result = r600_pc_query_add_result,
+};
+
+static struct r600_pc_group *get_group_state(struct r600_common_screen *screen,
+ struct r600_query_pc *query,
+ struct r600_perfcounter_block *block,
+ unsigned sub_gid)
+{
+ struct r600_pc_group *group = query->groups;
+
+ while (group) {
+ if (group->block == block && group->sub_gid == sub_gid)
+ return group;
+ group = group->next;
+ }
+
+ group = CALLOC_STRUCT(r600_pc_group);
+ if (!group)
+ return NULL;
+
+ group->block = block;
+ group->sub_gid = sub_gid;
+
+ if (block->flags & R600_PC_BLOCK_SHADER) {
+ unsigned sub_gids = block->num_instances;
+ unsigned shader_id;
+ unsigned shader_mask;
+ unsigned query_shader_mask;
+
+ if (block->flags & R600_PC_BLOCK_SE_GROUPS)
+ sub_gids = sub_gids * screen->info.max_se;
+ shader_id = sub_gid / sub_gids;
+ sub_gid = sub_gid % sub_gids;
+
+ if (shader_id == 0)
+ shader_mask = R600_PC_SHADER_ALL;
+ else
+ shader_mask = 1 << (shader_id - 1);
+
+ query_shader_mask = query->shaders & R600_PC_SHADER_ALL;
+ if (query_shader_mask && query_shader_mask != shader_mask) {
+ fprintf(stderr, "r600_perfcounter: incompatible shader groups\n");
+ FREE(group);
+ return NULL;
+ }
+ query->shaders |= shader_mask;
+ }
+
+ if (block->flags & R600_PC_BLOCK_SHADER_WINDOWED) {
+ // A non-zero value in query->shaders ensures that the shader
+ // masking is reset unless the user explicitly requests one.
+ query->shaders |= R600_PC_SHADER_WINDOWING;
+ }
+
+ if (block->flags & R600_PC_BLOCK_SE_GROUPS) {
+ group->se = sub_gid / block->num_instances;
+ sub_gid = sub_gid % block->num_instances;
+ } else {
+ group->se = -1;
+ }
+
+ if (block->flags & R600_PC_BLOCK_INSTANCE_GROUPS) {
+ group->instance = sub_gid;
+ } else {
+ group->instance = -1;
+ }
+
+ group->next = query->groups;
+ query->groups = group;
+
+ return group;
+}
+
+struct pipe_query *r600_create_batch_query(struct pipe_context *ctx,
+ unsigned num_queries,
+ unsigned *query_types)
+{
+ struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+ struct r600_common_screen *screen = rctx->screen;
+ struct r600_perfcounters *pc = screen->perfcounters;
+ struct r600_perfcounter_block *block;
+ struct r600_pc_group *group;
+ struct r600_query_pc *query;
+ unsigned base_gid, sub_gid, sub_index;
+ unsigned i, j;
+
+ if (!pc)
+ return NULL;
+
+ query = CALLOC_STRUCT(r600_query_pc);
+ if (!query)
+ return NULL;
+
+ query->b.b.ops = &batch_query_ops;
+ query->b.ops = &batch_query_hw_ops;
+ query->b.flags = R600_QUERY_HW_FLAG_TIMER;
+
+ query->num_counters = num_queries;
+
+ /* Collect selectors per group */
+ for (i = 0; i < num_queries; ++i) {
+ unsigned sub_gid;
+
+ if (query_types[i] < R600_QUERY_FIRST_PERFCOUNTER)
+ goto error;
+
+ block = lookup_counter(pc, query_types[i] - R600_QUERY_FIRST_PERFCOUNTER,
+ &base_gid, &sub_index);
+ if (!block)
+ goto error;
+
+ sub_gid = sub_index / block->num_selectors;
+ sub_index = sub_index % block->num_selectors;
+
+ group = get_group_state(screen, query, block, sub_gid);
+ if (!group)
+ goto error;
+
+ if (group->num_counters >= block->num_counters) {
+ fprintf(stderr,
+ "perfcounter group %s: too many selected\n",
+ block->basename);
+ goto error;
+ }
+ group->selectors[group->num_counters] = sub_index;
+ ++group->num_counters;
+ }
+
+ /* Compute result bases and CS size per group */
+ query->b.num_cs_dw_begin = pc->num_start_cs_dwords;
+ query->b.num_cs_dw_end = pc->num_stop_cs_dwords;
+
+ query->b.num_cs_dw_begin += pc->num_instance_cs_dwords; /* conservative */
+ query->b.num_cs_dw_end += pc->num_instance_cs_dwords;
+
+ i = 0;
+ for (group = query->groups; group; group = group->next) {
+ struct r600_perfcounter_block *block = group->block;
+ unsigned select_dw, read_dw;
+ unsigned instances = 1;
+
+ if ((block->flags & R600_PC_BLOCK_SE) && group->se < 0)
+ instances = rctx->screen->info.max_se;
+ if (group->instance < 0)
+ instances *= block->num_instances;
+
+ group->result_base = i;
+ query->b.result_size += 4 * instances * group->num_counters;
+ i += instances * group->num_counters;
+
+ pc->get_size(block, group->num_counters, group->selectors,
+ &select_dw, &read_dw);
+ query->b.num_cs_dw_begin += select_dw;
+ query->b.num_cs_dw_end += instances * read_dw;
+ query->b.num_cs_dw_begin += pc->num_instance_cs_dwords; /* conservative */
+ query->b.num_cs_dw_end += instances * pc->num_instance_cs_dwords;
+ }
+
+ if (query->shaders) {
+ if ((query->shaders & R600_PC_SHADER_ALL) == 0)
+ query->shaders |= R600_PC_SHADER_ALL;
+ query->b.num_cs_dw_begin += pc->num_shaders_cs_dwords;
+ }
+
+ /* Map user-supplied query array to result indices */
+ query->counters = CALLOC(num_queries, sizeof(*query->counters));
+ for (i = 0; i < num_queries; ++i) {
+ struct r600_pc_counter *counter = &query->counters[i];
+ struct r600_perfcounter_block *block;
+
+ block = lookup_counter(pc, query_types[i] - R600_QUERY_FIRST_PERFCOUNTER,
+ &base_gid, &sub_index);
+
+ sub_gid = sub_index / block->num_selectors;
+ sub_index = sub_index % block->num_selectors;
+
+ group = get_group_state(screen, query, block, sub_gid);
+ assert(group != NULL);
+
+ for (j = 0; j < group->num_counters; ++j) {
+ if (group->selectors[j] == sub_index)
+ break;
+ }
+
+ counter->base = group->result_base + j;
+ counter->stride = group->num_counters;
+
+ counter->dwords = 1;
+ if ((block->flags & R600_PC_BLOCK_SE) && group->se < 0)
+ counter->dwords = screen->info.max_se;
+ if (group->instance < 0)
+ counter->dwords *= block->num_instances;
+ }
+
+ if (!r600_query_hw_init(rctx, &query->b))
+ goto error;
+
+ return (struct pipe_query *)query;
+
+error:
+ r600_pc_query_destroy(rctx, &query->b.b);
+ return NULL;
+}
+
+static boolean r600_init_block_names(struct r600_common_screen *screen,
+ struct r600_perfcounter_block *block)
+{
+ unsigned i, j, k;
+ unsigned groups_shader = 1, groups_se = 1, groups_instance = 1;
+ unsigned namelen;
+ char *groupname;
+ char *p;
+
+ if (block->flags & R600_PC_BLOCK_INSTANCE_GROUPS)
+ groups_instance = block->num_instances;
+ if (block->flags & R600_PC_BLOCK_SE_GROUPS)
+ groups_se = screen->info.max_se;
+ if (block->flags & R600_PC_BLOCK_SHADER)
+ groups_shader = ARRAY_SIZE(r600_pc_shader_suffix);
+
+ namelen = strlen(block->basename);
+ block->group_name_stride = namelen + 1;
+ if (block->flags & R600_PC_BLOCK_SHADER)
+ block->group_name_stride += 3;
+ if (block->flags & R600_PC_BLOCK_SE_GROUPS) {
+ assert(groups_se <= 10);
+ block->group_name_stride += 1;
+
+ if (block->flags & R600_PC_BLOCK_INSTANCE_GROUPS)
+ block->group_name_stride += 1;
+ }
+ if (block->flags & R600_PC_BLOCK_INSTANCE_GROUPS) {
+ assert(groups_instance <= 100);
+ block->group_name_stride += 2;
+ }
+
+ block->group_names = MALLOC(block->num_groups * block->group_name_stride);
+ if (!block->group_names)
+ return FALSE;
+
+ groupname = block->group_names;
+ for (i = 0; i < groups_shader; ++i) {
+ unsigned shaderlen = strlen(r600_pc_shader_suffix[i]);
+ for (j = 0; j < groups_se; ++j) {
+ for (k = 0; k < groups_instance; ++k) {
+ strcpy(groupname, block->basename);
+ p = groupname + namelen;
+
+ if (block->flags & R600_PC_BLOCK_SHADER) {
+ strcpy(p, r600_pc_shader_suffix[i]);
+ p += shaderlen;
+ }
+
+ if (block->flags & R600_PC_BLOCK_SE_GROUPS) {
+ p += sprintf(p, "%d", j);
+ if (block->flags & R600_PC_BLOCK_INSTANCE_GROUPS)
+ *p++ = '_';
+ }
+
+ if (block->flags & R600_PC_BLOCK_INSTANCE_GROUPS)
+ p += sprintf(p, "%d", k);
+
+ groupname += block->group_name_stride;
+ }
+ }
+ }
+
+ assert(block->num_selectors <= 1000);
+ block->selector_name_stride = block->group_name_stride + 4;
+ block->selector_names = MALLOC(block->num_groups * block->num_selectors *
+ block->selector_name_stride);
+ if (!block->selector_names)
+ return FALSE;
+
+ groupname = block->group_names;
+ p = block->selector_names;
+ for (i = 0; i < block->num_groups; ++i) {
+ for (j = 0; j < block->num_selectors; ++j) {
+ sprintf(p, "%s_%03d", groupname, j);
+ p += block->selector_name_stride;
+ }
+ groupname += block->group_name_stride;
+ }
+
+ return TRUE;
+}
+
+int r600_get_perfcounter_info(struct r600_common_screen *screen,
+ unsigned index,
+ struct pipe_driver_query_info *info)
+{
+ struct r600_perfcounters *pc = screen->perfcounters;
+ struct r600_perfcounter_block *block;
+ unsigned base_gid, sub;
+
+ if (!pc)
+ return 0;
+
+ if (!info) {
+ unsigned bid, num_queries = 0;
+
+ for (bid = 0; bid < pc->num_blocks; ++bid) {
+ num_queries += pc->blocks[bid].num_selectors *
+ pc->blocks[bid].num_groups;
+ }
+
+ return num_queries;
+ }
+
+ block = lookup_counter(pc, index, &base_gid, &sub);
+ if (!block)
+ return 0;
+
+ if (!block->selector_names) {
+ if (!r600_init_block_names(screen, block))
+ return 0;
+ }
+ info->name = block->selector_names + sub * block->selector_name_stride;
+ info->query_type = R600_QUERY_FIRST_PERFCOUNTER + index;
+ info->max_value.u64 = 0;
+ info->type = PIPE_DRIVER_QUERY_TYPE_UINT;
+ info->result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_CUMULATIVE;
+ info->group_id = base_gid + sub / block->num_selectors;
+ info->flags = PIPE_DRIVER_QUERY_FLAG_BATCH;
+ if (sub > 0 && sub + 1 < block->num_selectors * block->num_groups)
+ info->flags |= PIPE_DRIVER_QUERY_FLAG_DONT_LIST;
+ return 1;
+}
+
+int r600_get_perfcounter_group_info(struct r600_common_screen *screen,
+ unsigned index,
+ struct pipe_driver_query_group_info *info)
+{
+ struct r600_perfcounters *pc = screen->perfcounters;
+ struct r600_perfcounter_block *block;
+
+ if (!pc)
+ return 0;
+
+ if (!info)
+ return pc->num_groups;
+
+ block = lookup_group(pc, &index);
+ if (!block)
+ return 0;
+
+ if (!block->group_names) {
+ if (!r600_init_block_names(screen, block))
+ return 0;
+ }
+ info->name = block->group_names + index * block->group_name_stride;
+ info->num_queries = block->num_selectors;
+ info->max_active_queries = block->num_counters;
+ return 1;
+}
+
+void r600_perfcounters_destroy(struct r600_common_screen *rscreen)
+{
+ if (rscreen->perfcounters)
+ rscreen->perfcounters->cleanup(rscreen);
+}
+
+boolean r600_perfcounters_init(struct r600_perfcounters *pc,
+ unsigned num_blocks)
+{
+ pc->blocks = CALLOC(num_blocks, sizeof(struct r600_perfcounter_block));
+ if (!pc->blocks)
+ return FALSE;
+
+ pc->separate_se = debug_get_bool_option("RADEON_PC_SEPARATE_SE", FALSE);
+ pc->separate_instance = debug_get_bool_option("RADEON_PC_SEPARATE_INSTANCE", FALSE);
+
+ return TRUE;
+}
+
+void r600_perfcounters_add_block(struct r600_common_screen *rscreen,
+ struct r600_perfcounters *pc,
+ const char *name, unsigned flags,
+ unsigned counters, unsigned selectors,
+ unsigned instances, void *data)
+{
+ struct r600_perfcounter_block *block = &pc->blocks[pc->num_blocks];
+
+ assert(counters <= R600_QUERY_MAX_COUNTERS);
+
+ block->basename = name;
+ block->flags = flags;
+ block->num_counters = counters;
+ block->num_selectors = selectors;
+ block->num_instances = MAX2(instances, 1);
+ block->data = data;
+
+ if (pc->separate_se && (block->flags & R600_PC_BLOCK_SE))
+ block->flags |= R600_PC_BLOCK_SE_GROUPS;
+ if (pc->separate_instance && block->num_instances > 1)
+ block->flags |= R600_PC_BLOCK_INSTANCE_GROUPS;
+
+ if (block->flags & R600_PC_BLOCK_INSTANCE_GROUPS) {
+ block->num_groups = block->num_instances;
+ } else {
+ block->num_groups = 1;
+ }
+
+ if (block->flags & R600_PC_BLOCK_SE_GROUPS)
+ block->num_groups *= rscreen->info.max_se;
+ if (block->flags & R600_PC_BLOCK_SHADER)
+ block->num_groups *= ARRAY_SIZE(r600_pc_shader_suffix);
+
+ ++pc->num_blocks;
+ pc->num_groups += block->num_groups;
+}
+
+void r600_perfcounters_do_destroy(struct r600_perfcounters *pc)
+{
+ unsigned i;
+
+ for (i = 0; i < pc->num_blocks; ++i) {
+ FREE(pc->blocks[i].group_names);
+ FREE(pc->blocks[i].selector_names);
+ }
+ FREE(pc->blocks);
+ FREE(pc);
+}
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index 7464f677398..8899ba4d55b 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -136,8 +136,12 @@ static void r600_memory_barrier(struct pipe_context *ctx, unsigned flags)
void r600_preflush_suspend_features(struct r600_common_context *ctx)
{
/* suspend queries */
- if (!LIST_IS_EMPTY(&ctx->active_nontimer_queries))
+ if (ctx->num_cs_dw_nontimer_queries_suspend) {
+ /* Since non-timer queries are suspended during blits,
+ * we have to guard against double-suspends. */
r600_suspend_nontimer_queries(ctx);
+ ctx->nontimer_queries_suspended_by_flush = true;
+ }
if (!LIST_IS_EMPTY(&ctx->active_timer_queries))
r600_suspend_timer_queries(ctx);
@@ -158,8 +162,10 @@ void r600_postflush_resume_features(struct r600_common_context *ctx)
/* resume queries */
if (!LIST_IS_EMPTY(&ctx->active_timer_queries))
r600_resume_timer_queries(ctx);
- if (!LIST_IS_EMPTY(&ctx->active_nontimer_queries))
+ if (ctx->nontimer_queries_suspended_by_flush) {
+ ctx->nontimer_queries_suspended_by_flush = false;
r600_resume_nontimer_queries(ctx);
+ }
}
static void r600_flush_from_st(struct pipe_context *ctx,
@@ -233,8 +239,8 @@ bool r600_common_context_init(struct r600_common_context *rctx,
rctx->family = rscreen->family;
rctx->chip_class = rscreen->chip_class;
- if (rscreen->family == CHIP_HAWAII)
- rctx->max_db = 16;
+ if (rscreen->chip_class >= CIK)
+ rctx->max_db = MAX2(8, rscreen->info.r600_num_backends);
else if (rscreen->chip_class >= EVERGREEN)
rctx->max_db = 8;
else
@@ -312,7 +318,7 @@ void r600_context_add_resource_size(struct pipe_context *ctx, struct pipe_resour
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
struct r600_resource *rr = (struct r600_resource *)r;
- if (r == NULL) {
+ if (!r) {
return;
}
@@ -338,7 +344,6 @@ void r600_context_add_resource_size(struct pipe_context *ctx, struct pipe_resour
static const struct debug_named_value common_debug_options[] = {
/* logging */
{ "tex", DBG_TEX, "Print texture info" },
- { "texmip", DBG_TEXMIP, "Print texture info (mipmapped only)" },
{ "compute", DBG_COMPUTE, "Print compute info" },
{ "vm", DBG_VM, "Print virtual addresses when creating resources" },
{ "trace_cs", DBG_TRACE_CS, "Trace cs and write rlockup_.c file with faulty cs" },
@@ -550,10 +555,11 @@ const char *r600_get_llvm_processor_name(enum radeon_family family)
case CHIP_TONGA: return "tonga";
case CHIP_ICELAND: return "iceland";
case CHIP_CARRIZO: return "carrizo";
- case CHIP_FIJI: return "fiji";
#if HAVE_LLVM <= 0x0307
+ case CHIP_FIJI: return "tonga";
case CHIP_STONEY: return "carrizo";
#else
+ case CHIP_FIJI: return "fiji";
case CHIP_STONEY: return "stoney";
#endif
default: return "";
@@ -977,6 +983,7 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen,
void r600_destroy_common_screen(struct r600_common_screen *rscreen)
{
+ r600_perfcounters_destroy(rscreen);
r600_gpu_load_kill_thread(rscreen);
pipe_mutex_destroy(rscreen->gpu_load_mutex);
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index fbdc5c410ae..8c6c0c37e50 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -56,7 +56,7 @@
/* Debug flags. */
/* logging */
#define DBG_TEX (1 << 0)
-#define DBG_TEXMIP (1 << 1)
+/* gap - reuse */
#define DBG_COMPUTE (1 << 2)
#define DBG_VM (1 << 3)
#define DBG_TRACE_CS (1 << 4)
@@ -90,6 +90,7 @@
#define R600_MAP_BUFFER_ALIGNMENT 64
struct r600_common_context;
+struct r600_perfcounters;
struct radeon_shader_reloc {
char *name;
@@ -171,7 +172,7 @@ struct r600_fmask_info {
unsigned offset;
unsigned size;
unsigned alignment;
- unsigned pitch;
+ unsigned pitch_in_pixels;
unsigned bank_height;
unsigned slice_tile_max;
unsigned tile_mode_index;
@@ -181,15 +182,25 @@ struct r600_cmask_info {
unsigned offset;
unsigned size;
unsigned alignment;
+ unsigned pitch;
+ unsigned height;
+ unsigned xalign;
+ unsigned yalign;
unsigned slice_tile_max;
unsigned base_address_reg;
};
+struct r600_htile_info {
+ unsigned pitch;
+ unsigned height;
+ unsigned xalign;
+ unsigned yalign;
+};
+
struct r600_texture {
struct r600_resource resource;
unsigned size;
- unsigned pitch_override;
bool is_depth;
unsigned dirty_level_mask; /* each bit says if that mipmap is compressed */
unsigned stencil_dirty_level_mask; /* each bit says if that mipmap is compressed */
@@ -206,6 +217,7 @@ struct r600_texture {
unsigned color_clear_value[2];
/* Depth buffer compression and fast clear. */
+ struct r600_htile_info htile;
struct r600_resource *htile_buffer;
bool depth_cleared; /* if it was cleared at least once */
float depth_clear_value;
@@ -300,6 +312,9 @@ struct r600_common_screen {
volatile unsigned gpu_load_stop_thread; /* bool */
char renderer_string[64];
+
+ /* Performance counters. */
+ struct r600_perfcounters *perfcounters;
};
/* This encapsulates a state or an operation which can emitted into the GPU
@@ -392,6 +407,7 @@ struct r600_common_context {
struct list_head active_nontimer_queries;
struct list_head active_timer_queries;
unsigned num_cs_dw_nontimer_queries_suspend;
+ bool nontimer_queries_suspended_by_flush;
unsigned num_cs_dw_timer_queries_suspend;
/* Additional hardware info. */
unsigned backend_mask;
@@ -508,6 +524,9 @@ void r600_gpu_load_kill_thread(struct r600_common_screen *rscreen);
uint64_t r600_gpu_load_begin(struct r600_common_screen *rscreen);
unsigned r600_gpu_load_end(struct r600_common_screen *rscreen, uint64_t begin);
+/* r600_perfcounters.c */
+void r600_perfcounters_destroy(struct r600_common_screen *rscreen);
+
/* r600_query.c */
void r600_init_screen_query_functions(struct r600_common_screen *rscreen);
void r600_query_init(struct r600_common_context *rctx);
@@ -539,6 +558,7 @@ void r600_texture_get_cmask_info(struct r600_common_screen *rscreen,
bool r600_init_flushed_depth_texture(struct pipe_context *ctx,
struct pipe_resource *texture,
struct r600_texture **staging);
+void r600_print_texture_info(struct r600_texture *rtex, FILE *f);
struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
const struct pipe_resource *templ);
struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/radeon/r600_query.c b/src/gallium/drivers/radeon/r600_query.c
index b1cfb6e462b..06b5e501a50 100644
--- a/src/gallium/drivers/radeon/r600_query.c
+++ b/src/gallium/drivers/radeon/r600_query.c
@@ -202,7 +202,7 @@ static struct pipe_query *r600_query_sw_create(struct pipe_context *ctx,
struct r600_query_sw *query;
query = CALLOC_STRUCT(r600_query_sw);
- if (query == NULL)
+ if (!query)
return NULL;
query->b.type = query_type;
@@ -232,7 +232,7 @@ void r600_query_hw_destroy(struct r600_common_context *rctx,
static struct r600_resource *r600_new_query_buffer(struct r600_common_context *ctx,
struct r600_query_hw *query)
{
- unsigned buf_size = 4096;
+ unsigned buf_size = MAX2(query->result_size, 4096);
/* Queries are normally read by the CPU after
* being written by the gpu, hence staging is probably a good
@@ -1141,11 +1141,15 @@ static int r600_get_driver_query_info(struct pipe_screen *screen,
struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
unsigned num_queries = r600_get_num_queries(rscreen);
- if (!info)
- return num_queries;
+ if (!info) {
+ unsigned num_perfcounters =
+ r600_get_perfcounter_info(rscreen, 0, NULL);
+
+ return num_queries + num_perfcounters;
+ }
if (index >= num_queries)
- return 0;
+ return r600_get_perfcounter_info(rscreen, index - num_queries, info);
*info = r600_driver_query_list[index];
@@ -1166,9 +1170,19 @@ static int r600_get_driver_query_info(struct pipe_screen *screen,
return 1;
}
+static int r600_get_driver_query_group_info(struct pipe_screen *screen,
+ unsigned index,
+ struct pipe_driver_query_group_info *info)
+{
+ struct r600_common_screen *rscreen = (struct r600_common_screen *)screen;
+
+ return r600_get_perfcounter_group_info(rscreen, index, info);
+}
+
void r600_query_init(struct r600_common_context *rctx)
{
rctx->b.create_query = r600_create_query;
+ rctx->b.create_batch_query = r600_create_batch_query;
rctx->b.destroy_query = r600_destroy_query;
rctx->b.begin_query = r600_begin_query;
rctx->b.end_query = r600_end_query;
@@ -1185,4 +1199,5 @@ void r600_query_init(struct r600_common_context *rctx)
void r600_init_screen_query_functions(struct r600_common_screen *rscreen)
{
rscreen->b.get_driver_query_info = r600_get_driver_query_info;
+ rscreen->b.get_driver_query_group_info = r600_get_driver_query_group_info;
}
diff --git a/src/gallium/drivers/radeon/r600_query.h b/src/gallium/drivers/radeon/r600_query.h
index 0ea5707ca45..e5a98bfe5bd 100644
--- a/src/gallium/drivers/radeon/r600_query.h
+++ b/src/gallium/drivers/radeon/r600_query.h
@@ -31,7 +31,11 @@
#include "pipe/p_defines.h"
#include "util/list.h"
+struct pipe_context;
+struct pipe_query;
+
struct r600_common_context;
+struct r600_common_screen;
struct r600_query;
struct r600_query_hw;
struct r600_resource;
@@ -133,4 +137,121 @@ boolean r600_query_hw_get_result(struct r600_common_context *rctx,
boolean wait,
union pipe_query_result *result);
+/* Performance counters */
+enum {
+ /* This block is part of the shader engine */
+ R600_PC_BLOCK_SE = (1 << 0),
+
+ /* Expose per-instance groups instead of summing all instances (within
+ * an SE). */
+ R600_PC_BLOCK_INSTANCE_GROUPS = (1 << 1),
+
+ /* Expose per-SE groups instead of summing instances across SEs. */
+ R600_PC_BLOCK_SE_GROUPS = (1 << 2),
+
+ /* Shader block */
+ R600_PC_BLOCK_SHADER = (1 << 3),
+
+ /* Non-shader block with perfcounters windowed by shaders. */
+ R600_PC_BLOCK_SHADER_WINDOWED = (1 << 4),
+};
+
+/* Shader enable bits. Chosen to coincide with SQ_PERFCOUNTER_CTRL values */
+enum {
+ R600_PC_SHADER_PS = (1 << 0),
+ R600_PC_SHADER_VS = (1 << 1),
+ R600_PC_SHADER_GS = (1 << 2),
+ R600_PC_SHADER_ES = (1 << 3),
+ R600_PC_SHADER_HS = (1 << 4),
+ R600_PC_SHADER_LS = (1 << 5),
+ R600_PC_SHADER_CS = (1 << 6),
+
+ R600_PC_SHADER_ALL = R600_PC_SHADER_PS | R600_PC_SHADER_VS |
+ R600_PC_SHADER_GS | R600_PC_SHADER_ES |
+ R600_PC_SHADER_HS | R600_PC_SHADER_LS |
+ R600_PC_SHADER_CS,
+
+ R600_PC_SHADER_WINDOWING = (1 << 31),
+};
+
+/* Describes a hardware block with performance counters. Multiple instances of
+ * each block, possibly per-SE, may exist on the chip. Depending on the block
+ * and on the user's configuration, we either
+ * (a) expose every instance as a performance counter group,
+ * (b) expose a single performance counter group that reports the sum over all
+ * instances, or
+ * (c) expose one performance counter group per instance, but summed over all
+ * shader engines.
+ */
+struct r600_perfcounter_block {
+ const char *basename;
+ unsigned flags;
+ unsigned num_counters;
+ unsigned num_selectors;
+ unsigned num_instances;
+
+ unsigned num_groups;
+ char *group_names;
+ unsigned group_name_stride;
+
+ char *selector_names;
+ unsigned selector_name_stride;
+
+ void *data;
+};
+
+struct r600_perfcounters {
+ unsigned num_groups;
+ unsigned num_blocks;
+ struct r600_perfcounter_block *blocks;
+
+ unsigned num_start_cs_dwords;
+ unsigned num_stop_cs_dwords;
+ unsigned num_instance_cs_dwords;
+ unsigned num_shaders_cs_dwords;
+
+ void (*get_size)(struct r600_perfcounter_block *,
+ unsigned count, unsigned *selectors,
+ unsigned *num_select_dw, unsigned *num_read_dw);
+
+ void (*emit_instance)(struct r600_common_context *,
+ int se, int instance);
+ void (*emit_shaders)(struct r600_common_context *, unsigned shaders);
+ void (*emit_select)(struct r600_common_context *,
+ struct r600_perfcounter_block *,
+ unsigned count, unsigned *selectors);
+ void (*emit_start)(struct r600_common_context *,
+ struct r600_resource *buffer, uint64_t va);
+ void (*emit_stop)(struct r600_common_context *,
+ struct r600_resource *buffer, uint64_t va);
+ void (*emit_read)(struct r600_common_context *,
+ struct r600_perfcounter_block *,
+ unsigned count, unsigned *selectors,
+ struct r600_resource *buffer, uint64_t va);
+
+ void (*cleanup)(struct r600_common_screen *);
+
+ boolean separate_se;
+ boolean separate_instance;
+};
+
+struct pipe_query *r600_create_batch_query(struct pipe_context *ctx,
+ unsigned num_queries,
+ unsigned *query_types);
+
+int r600_get_perfcounter_info(struct r600_common_screen *,
+ unsigned index,
+ struct pipe_driver_query_info *info);
+int r600_get_perfcounter_group_info(struct r600_common_screen *,
+ unsigned index,
+ struct pipe_driver_query_group_info *info);
+
+boolean r600_perfcounters_init(struct r600_perfcounters *, unsigned num_blocks);
+void r600_perfcounters_add_block(struct r600_common_screen *,
+ struct r600_perfcounters *,
+ const char *name, unsigned flags,
+ unsigned counters, unsigned selectors,
+ unsigned instances, void *data);
+void r600_perfcounters_do_destroy(struct r600_perfcounters *);
+
#endif /* R600_QUERY_H */
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 3126cce8c22..774722f7063 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -336,7 +336,7 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen,
out->slice_tile_max -= 1;
out->tile_mode_index = fmask.tiling_index[0];
- out->pitch = fmask.level[0].nblk_x;
+ out->pitch_in_pixels = fmask.level[0].nblk_x;
out->bank_height = fmask.bankh;
out->alignment = MAX2(256, fmask.bo_alignment);
out->size = fmask.bo_size;
@@ -380,6 +380,10 @@ void r600_texture_get_cmask_info(struct r600_common_screen *rscreen,
assert(macro_tile_width % 128 == 0);
assert(macro_tile_height % 128 == 0);
+ out->pitch = pitch_elements;
+ out->height = height;
+ out->xalign = macro_tile_width;
+ out->yalign = macro_tile_height;
out->slice_tile_max = ((pitch_elements * height) / (128*128)) - 1;
out->alignment = MAX2(256, base_align);
out->size = (util_max_layer(&rtex->resource.b.b, 0) + 1) *
@@ -425,6 +429,10 @@ static void si_texture_get_cmask_info(struct r600_common_screen *rscreen,
/* Each element of CMASK is a nibble. */
unsigned slice_bytes = slice_elements / 2;
+ out->pitch = width;
+ out->height = height;
+ out->xalign = cl_width * 8;
+ out->yalign = cl_height * 8;
out->slice_tile_max = (width * height) / (128*128);
if (out->slice_tile_max)
out->slice_tile_max -= 1;
@@ -489,6 +497,10 @@ static void vi_texture_alloc_dcc_separate(struct r600_common_screen *rscreen,
if (rscreen->debug_flags & DBG_NO_DCC)
return;
+ /* TODO: DCC is broken on Stoney */
+ if (rscreen->family == CHIP_STONEY)
+ return;
+
rtex->dcc_buffer = (struct r600_resource *)
r600_aligned_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
PIPE_USAGE_DEFAULT, rtex->surface.dcc_size, rtex->surface.dcc_alignment);
@@ -560,6 +572,11 @@ static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen,
pipe_interleave_bytes = rscreen->tiling_info.group_bytes;
base_align = num_pipes * pipe_interleave_bytes;
+ rtex->htile.pitch = width;
+ rtex->htile.height = height;
+ rtex->htile.xalign = cl_width * 8;
+ rtex->htile.yalign = cl_height * 8;
+
return (util_max_layer(&rtex->resource.b.b, 0) + 1) *
align(slice_bytes, base_align);
}
@@ -585,6 +602,94 @@ static void r600_texture_allocate_htile(struct r600_common_screen *rscreen,
}
}
+void r600_print_texture_info(struct r600_texture *rtex, FILE *f)
+{
+ int i;
+
+ fprintf(f, " Info: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, "
+ "blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, "
+ "bpe=%u, nsamples=%u, flags=0x%x, %s\n",
+ rtex->surface.npix_x, rtex->surface.npix_y,
+ rtex->surface.npix_z, rtex->surface.blk_w,
+ rtex->surface.blk_h, rtex->surface.blk_d,
+ rtex->surface.array_size, rtex->surface.last_level,
+ rtex->surface.bpe, rtex->surface.nsamples,
+ rtex->surface.flags, util_format_short_name(rtex->resource.b.b.format));
+
+ fprintf(f, " Layout: size=%"PRIu64", alignment=%"PRIu64", bankw=%u, "
+ "bankh=%u, nbanks=%u, mtilea=%u, tilesplit=%u, pipeconfig=%u, scanout=%u\n",
+ rtex->surface.bo_size, rtex->surface.bo_alignment, rtex->surface.bankw,
+ rtex->surface.bankh, rtex->surface.num_banks, rtex->surface.mtilea,
+ rtex->surface.tile_split, rtex->surface.pipe_config,
+ (rtex->surface.flags & RADEON_SURF_SCANOUT) != 0);
+
+ if (rtex->fmask.size)
+ fprintf(f, " FMask: offset=%u, size=%u, alignment=%u, pitch_in_pixels=%u, "
+ "bankh=%u, slice_tile_max=%u, tile_mode_index=%u\n",
+ rtex->fmask.offset, rtex->fmask.size, rtex->fmask.alignment,
+ rtex->fmask.pitch_in_pixels, rtex->fmask.bank_height,
+ rtex->fmask.slice_tile_max, rtex->fmask.tile_mode_index);
+
+ if (rtex->cmask.size)
+ fprintf(f, " CMask: offset=%u, size=%u, alignment=%u, pitch=%u, "
+ "height=%u, xalign=%u, yalign=%u, slice_tile_max=%u\n",
+ rtex->cmask.offset, rtex->cmask.size, rtex->cmask.alignment,
+ rtex->cmask.pitch, rtex->cmask.height, rtex->cmask.xalign,
+ rtex->cmask.yalign, rtex->cmask.slice_tile_max);
+
+ if (rtex->htile_buffer)
+ fprintf(f, " HTile: size=%u, alignment=%u, pitch=%u, height=%u, "
+ "xalign=%u, yalign=%u\n",
+ rtex->htile_buffer->b.b.width0,
+ rtex->htile_buffer->buf->alignment, rtex->htile.pitch,
+ rtex->htile.height, rtex->htile.xalign, rtex->htile.yalign);
+
+ if (rtex->dcc_buffer) {
+ fprintf(f, " DCC: size=%u, alignment=%u\n",
+ rtex->dcc_buffer->b.b.width0,
+ rtex->dcc_buffer->buf->alignment);
+ for (i = 0; i <= rtex->surface.last_level; i++)
+ fprintf(f, " DCCLevel[%i]: offset=%"PRIu64"\n",
+ i, rtex->surface.level[i].dcc_offset);
+ }
+
+ for (i = 0; i <= rtex->surface.last_level; i++)
+ fprintf(f, " Level[%i]: offset=%"PRIu64", slice_size=%"PRIu64", "
+ "npix_x=%u, npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
+ "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
+ i, rtex->surface.level[i].offset,
+ rtex->surface.level[i].slice_size,
+ u_minify(rtex->resource.b.b.width0, i),
+ u_minify(rtex->resource.b.b.height0, i),
+ u_minify(rtex->resource.b.b.depth0, i),
+ rtex->surface.level[i].nblk_x,
+ rtex->surface.level[i].nblk_y,
+ rtex->surface.level[i].nblk_z,
+ rtex->surface.level[i].pitch_bytes,
+ rtex->surface.level[i].mode);
+
+ if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
+ for (i = 0; i <= rtex->surface.last_level; i++) {
+ fprintf(f, " StencilLayout: tilesplit=%u\n",
+ rtex->surface.stencil_tile_split);
+ fprintf(f, " StencilLevel[%i]: offset=%"PRIu64", "
+ "slice_size=%"PRIu64", npix_x=%u, "
+ "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
+ "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
+ i, rtex->surface.stencil_level[i].offset,
+ rtex->surface.stencil_level[i].slice_size,
+ u_minify(rtex->resource.b.b.width0, i),
+ u_minify(rtex->resource.b.b.height0, i),
+ u_minify(rtex->resource.b.b.depth0, i),
+ rtex->surface.stencil_level[i].nblk_x,
+ rtex->surface.stencil_level[i].nblk_y,
+ rtex->surface.stencil_level[i].nblk_z,
+ rtex->surface.stencil_level[i].pitch_bytes,
+ rtex->surface.stencil_level[i].mode);
+ }
+ }
+}
+
/* Common processing for r600_texture_create and r600_texture_from_handle */
static struct r600_texture *
r600_texture_create_object(struct pipe_screen *screen,
@@ -598,7 +703,7 @@ r600_texture_create_object(struct pipe_screen *screen,
struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
rtex = CALLOC_STRUCT(r600_texture);
- if (rtex == NULL)
+ if (!rtex)
return NULL;
resource = &rtex->resource;
@@ -606,7 +711,6 @@ r600_texture_create_object(struct pipe_screen *screen,
resource->b.vtbl = &r600_texture_vtbl;
pipe_reference_init(&resource->b.b.reference, 1);
resource->b.b.screen = screen;
- rtex->pitch_override = pitch_in_bytes_override;
/* don't include stencil-only formats which we don't support for rendering */
rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));
@@ -678,50 +782,11 @@ r600_texture_create_object(struct pipe_screen *screen,
base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format));
}
- if (rscreen->debug_flags & DBG_TEX ||
- (rtex->resource.b.b.last_level > 0 && rscreen->debug_flags & DBG_TEXMIP)) {
- printf("Texture: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, "
- "blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, "
- "bpe=%u, nsamples=%u, flags=0x%x, %s\n",
- rtex->surface.npix_x, rtex->surface.npix_y,
- rtex->surface.npix_z, rtex->surface.blk_w,
- rtex->surface.blk_h, rtex->surface.blk_d,
- rtex->surface.array_size, rtex->surface.last_level,
- rtex->surface.bpe, rtex->surface.nsamples,
- rtex->surface.flags, util_format_short_name(base->format));
- for (int i = 0; i <= rtex->surface.last_level; i++) {
- printf(" L %i: offset=%"PRIu64", slice_size=%"PRIu64", npix_x=%u, "
- "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
- "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
- i, rtex->surface.level[i].offset,
- rtex->surface.level[i].slice_size,
- u_minify(rtex->resource.b.b.width0, i),
- u_minify(rtex->resource.b.b.height0, i),
- u_minify(rtex->resource.b.b.depth0, i),
- rtex->surface.level[i].nblk_x,
- rtex->surface.level[i].nblk_y,
- rtex->surface.level[i].nblk_z,
- rtex->surface.level[i].pitch_bytes,
- rtex->surface.level[i].mode);
- }
- if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
- for (int i = 0; i <= rtex->surface.last_level; i++) {
- printf(" S %i: offset=%"PRIu64", slice_size=%"PRIu64", npix_x=%u, "
- "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
- "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
- i, rtex->surface.stencil_level[i].offset,
- rtex->surface.stencil_level[i].slice_size,
- u_minify(rtex->resource.b.b.width0, i),
- u_minify(rtex->resource.b.b.height0, i),
- u_minify(rtex->resource.b.b.depth0, i),
- rtex->surface.stencil_level[i].nblk_x,
- rtex->surface.stencil_level[i].nblk_y,
- rtex->surface.stencil_level[i].nblk_z,
- rtex->surface.stencil_level[i].pitch_bytes,
- rtex->surface.stencil_level[i].mode);
- }
- }
+ if (rscreen->debug_flags & DBG_TEX) {
+ puts("Texture:");
+ r600_print_texture_info(rtex, stdout);
}
+
return rtex;
}
@@ -978,7 +1043,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
}
trans = CALLOC_STRUCT(r600_transfer);
- if (trans == NULL)
+ if (!trans)
return NULL;
trans->transfer.resource = texture;
trans->transfer.level = level;
@@ -1020,7 +1085,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
r600_copy_region_with_blit(ctx, temp, 0, 0, 0, 0, texture, level, box);
rctx->blit_decompress_depth(ctx, (struct r600_texture*)temp, staging_depth,
0, 0, 0, box->depth, 0, 0);
- pipe_resource_reference((struct pipe_resource**)&temp, NULL);
+ pipe_resource_reference(&temp, NULL);
}
}
else {
@@ -1054,7 +1119,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
/* Create the temporary texture. */
staging = (struct r600_texture*)ctx->screen->resource_create(ctx->screen, &resource);
- if (staging == NULL) {
+ if (!staging) {
R600_ERR("failed to create temporary texture to hold untiled copy\n");
FREE(trans);
return NULL;
@@ -1131,7 +1196,7 @@ struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
{
struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
- if (surface == NULL)
+ if (!surface)
return NULL;
assert(templ->u.tex.first_layer <= util_max_layer(texture, templ->u.tex.level));
diff --git a/src/gallium/drivers/radeon/r600d_common.h b/src/gallium/drivers/radeon/r600d_common.h
index a3d182cd30f..b8e65640528 100644
--- a/src/gallium/drivers/radeon/r600d_common.h
+++ b/src/gallium/drivers/radeon/r600d_common.h
@@ -31,7 +31,7 @@
#define SI_SH_REG_OFFSET 0x0000B000
#define SI_SH_REG_END 0x0000C000
#define CIK_UCONFIG_REG_OFFSET 0x00030000
-#define CIK_UCONFIG_REG_END 0x00031000
+#define CIK_UCONFIG_REG_END 0x00038000
#define PKT_TYPE_S(x) (((x) & 0x3) << 30)
#define PKT_COUNT_S(x) (((x) & 0x3FFF) << 16)
@@ -53,8 +53,16 @@
#define STRMOUT_SELECT_BUFFER(x) (((x) & 0x3) << 8)
#define PKT3_WAIT_REG_MEM 0x3C
#define WAIT_REG_MEM_EQUAL 3
+#define WAIT_REG_MEM_MEM_SPACE(x) (((x) & 0x3) << 4)
#define PKT3_EVENT_WRITE 0x46
#define PKT3_EVENT_WRITE_EOP 0x47
+#define EOP_DATA_SEL(x) ((x) << 29)
+ /* 0 - discard
+ * 1 - send low 32bit data
+ * 2 - send 64bit data
+ * 3 - send 64bit GPU counter value
+ * 4 - send 64bit sys counter value
+ */
#define PKT3_SET_CONFIG_REG 0x68
#define PKT3_SET_CONTEXT_REG 0x69
#define PKT3_STRMOUT_BASE_UPDATE 0x72 /* r700 only */
@@ -73,8 +81,11 @@
#define EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT 0x14
#define EVENT_TYPE_ZPASS_DONE 0x15
#define EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT 0x16
+#define EVENT_TYPE_PERFCOUNTER_START 0x17
+#define EVENT_TYPE_PERFCOUNTER_STOP 0x18
#define EVENT_TYPE_PIPELINESTAT_START 25
#define EVENT_TYPE_PIPELINESTAT_STOP 26
+#define EVENT_TYPE_PERFCOUNTER_SAMPLE 0x1B
#define EVENT_TYPE_SAMPLE_PIPELINESTAT 30
#define EVENT_TYPE_SO_VGTSTREAMOUT_FLUSH 0x1f
#define EVENT_TYPE_SAMPLE_STREAMOUTSTATS 0x20
diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
index ac99e732c94..c94f1093ab7 100644
--- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
+++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
@@ -1539,7 +1539,7 @@ void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
bld_base->op_actions[TGSI_OPCODE_ENDIF].emit = endif_emit;
bld_base->op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit;
bld_base->op_actions[TGSI_OPCODE_EX2].emit = build_tgsi_intrinsic_nomem;
- bld_base->op_actions[TGSI_OPCODE_EX2].intr_name = "llvm.exp2.f32";
+ bld_base->op_actions[TGSI_OPCODE_EX2].intr_name = "llvm.AMDIL.exp.";
bld_base->op_actions[TGSI_OPCODE_FLR].emit = build_tgsi_intrinsic_nomem;
bld_base->op_actions[TGSI_OPCODE_FLR].intr_name = "llvm.floor.f32";
bld_base->op_actions[TGSI_OPCODE_FMA].emit = build_tgsi_intrinsic_nomem;
diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
index 0c643e5cd59..6ea07be72fe 100644
--- a/src/gallium/drivers/radeon/radeon_uvd.c
+++ b/src/gallium/drivers/radeon/radeon_uvd.c
@@ -958,6 +958,8 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder,
dec->msg->body.decode.db_pitch = dec->base.width;
dt = dec->set_dtb(dec->msg, (struct vl_video_buffer *)target);
+ if (((struct r600_common_screen*)dec->screen)->family >= CHIP_STONEY)
+ dec->msg->body.decode.dt_wa_chroma_top_offset = dec->msg->body.decode.dt_pitch / 2;
switch (u_reduce_video_profile(picture->profile)) {
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
diff --git a/src/gallium/drivers/radeon/radeon_uvd.h b/src/gallium/drivers/radeon/radeon_uvd.h
index 9cc0a694c30..88013bd5653 100644
--- a/src/gallium/drivers/radeon/radeon_uvd.h
+++ b/src/gallium/drivers/radeon/radeon_uvd.h
@@ -394,7 +394,10 @@ struct ruvd_msg {
uint32_t dt_chroma_top_offset;
uint32_t dt_chroma_bottom_offset;
uint32_t dt_surf_tile_config;
- uint32_t dt_reserved[3];
+ uint32_t dt_uv_surf_tile_config;
+ // re-use dt_wa_chroma_top_offset as dt_ext_info for UV pitch in stoney
+ uint32_t dt_wa_chroma_top_offset;
+ uint32_t dt_wa_chroma_bottom_offset;
uint32_t reserved[16];
diff --git a/src/gallium/drivers/radeonsi/Makefile.sources b/src/gallium/drivers/radeonsi/Makefile.sources
index 7e997c6d526..53404ab0e58 100644
--- a/src/gallium/drivers/radeonsi/Makefile.sources
+++ b/src/gallium/drivers/radeonsi/Makefile.sources
@@ -12,6 +12,7 @@ C_SOURCES := \
si_pipe.h \
si_pm4.c \
si_pm4.h \
+ si_perfcounter.c \
si_public.h \
si_shader.c \
si_shader.h \
diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c
index 2d551dd0e6b..a871ea0d5b6 100644
--- a/src/gallium/drivers/radeonsi/si_compute.c
+++ b/src/gallium/drivers/radeonsi/si_compute.c
@@ -34,11 +34,6 @@
#define MAX_GLOBAL_BUFFERS 20
-/* XXX: Even though we don't pass the scratch buffer via user sgprs any more
- * LLVM still expects that we specify 4 USER_SGPRS so it can remain compatible
- * with older mesa. */
-#define NUM_USER_SGPRS 4
-
struct si_compute {
struct si_context *ctx;
@@ -81,7 +76,7 @@ static void init_scratch_buffer(struct si_context *sctx, struct si_compute *prog
if (scratch_bytes == 0)
return;
- program->shader.scratch_bo = (struct r600_resource*)
+ program->shader.scratch_bo =
si_resource_create_custom(sctx->b.b.screen,
PIPE_USAGE_DEFAULT,
scratch_bytes * scratch_waves);
@@ -238,7 +233,6 @@ static void si_launch_grid(
uint64_t kernel_args_va;
uint64_t scratch_buffer_va = 0;
uint64_t shader_va;
- unsigned arg_user_sgpr_count = NUM_USER_SGPRS;
unsigned i;
struct si_shader *shader = &program->shader;
unsigned lds_blocks;
@@ -366,20 +360,7 @@ static void si_launch_grid(
si_pm4_set_reg(pm4, R_00B830_COMPUTE_PGM_LO, shader_va >> 8);
si_pm4_set_reg(pm4, R_00B834_COMPUTE_PGM_HI, shader_va >> 40);
- si_pm4_set_reg(pm4, R_00B848_COMPUTE_PGM_RSRC1,
- /* We always use at least 3 VGPRS, these come from
- * TIDIG_COMP_CNT.
- * XXX: The compiler should account for this.
- */
- S_00B848_VGPRS((MAX2(3, shader->num_vgprs) - 1) / 4)
- /* We always use at least 4 + arg_user_sgpr_count. The 4 extra
- * sgprs are from TGID_X_EN, TGID_Y_EN, TGID_Z_EN, TG_SIZE_EN
- * XXX: The compiler should account for this.
- */
- | S_00B848_SGPRS(((MAX2(4 + arg_user_sgpr_count,
- shader->num_sgprs)) - 1) / 8)
- | S_00B028_FLOAT_MODE(shader->float_mode))
- ;
+ si_pm4_set_reg(pm4, R_00B848_COMPUTE_PGM_RSRC1, shader->rsrc1);
lds_blocks = shader->lds_size;
/* XXX: We are over allocating LDS. For SI, the shader reports LDS in
@@ -395,17 +376,10 @@ static void si_launch_grid(
assert(lds_blocks <= 0xFF);
- si_pm4_set_reg(pm4, R_00B84C_COMPUTE_PGM_RSRC2,
- S_00B84C_SCRATCH_EN(shader->scratch_bytes_per_wave > 0)
- | S_00B84C_USER_SGPR(arg_user_sgpr_count)
- | S_00B84C_TGID_X_EN(1)
- | S_00B84C_TGID_Y_EN(1)
- | S_00B84C_TGID_Z_EN(1)
- | S_00B84C_TG_SIZE_EN(1)
- | S_00B84C_TIDIG_COMP_CNT(2)
- | S_00B84C_LDS_SIZE(lds_blocks)
- | S_00B84C_EXCP_EN(0))
- ;
+ shader->rsrc2 &= C_00B84C_LDS_SIZE;
+ shader->rsrc2 |= S_00B84C_LDS_SIZE(lds_blocks);
+
+ si_pm4_set_reg(pm4, R_00B84C_COMPUTE_PGM_RSRC2, shader->rsrc2);
si_pm4_set_reg(pm4, R_00B854_COMPUTE_RESOURCE_LIMITS, 0);
si_pm4_set_reg(pm4, R_00B858_COMPUTE_STATIC_THREAD_MGMT_SE0,
diff --git a/src/gallium/drivers/radeonsi/si_debug.c b/src/gallium/drivers/radeonsi/si_debug.c
index 53062187b88..cce665e85fa 100644
--- a/src/gallium/drivers/radeonsi/si_debug.c
+++ b/src/gallium/drivers/radeonsi/si_debug.c
@@ -312,9 +312,10 @@ static uint32_t *si_parse_packet3(FILE *f, uint32_t *ib, int *num_dw,
* \param trace_id the last trace ID that is known to have been reached
* and executed by the CP, typically read from a buffer
*/
-static void si_parse_ib(FILE *f, uint32_t *ib, int num_dw, int trace_id)
+static void si_parse_ib(FILE *f, uint32_t *ib, int num_dw, int trace_id,
+ const char *name)
{
- fprintf(f, "------------------ IB begin ------------------\n");
+ fprintf(f, "------------------ %s begin ------------------\n", name);
while (num_dw > 0) {
unsigned type = PKT_TYPE_G(ib[0]);
@@ -337,11 +338,12 @@ static void si_parse_ib(FILE *f, uint32_t *ib, int num_dw, int trace_id)
}
}
- fprintf(f, "------------------- IB end -------------------\n");
+ fprintf(f, "------------------- %s end -------------------\n", name);
if (num_dw < 0) {
printf("Packet ends after the end of IB.\n");
exit(0);
}
+ fprintf(f, "\n");
}
static void si_dump_mmapped_reg(struct si_context *sctx, FILE *f,
@@ -413,8 +415,17 @@ static void si_dump_last_ib(struct si_context *sctx, FILE *f)
last_trace_id = *map;
}
+ if (sctx->init_config)
+ si_parse_ib(f, sctx->init_config->pm4, sctx->init_config->ndw,
+ -1, "IB2: Init config");
+
+ if (sctx->init_config_gs_rings)
+ si_parse_ib(f, sctx->init_config_gs_rings->pm4,
+ sctx->init_config_gs_rings->ndw,
+ -1, "IB2: Init GS rings");
+
si_parse_ib(f, sctx->last_ib, sctx->last_ib_dw_size,
- last_trace_id);
+ last_trace_id, "IB");
free(sctx->last_ib); /* dump only once */
sctx->last_ib = NULL;
r600_resource_reference(&sctx->last_trace_buf, NULL);
@@ -528,6 +539,30 @@ static void si_dump_last_bo_list(struct si_context *sctx, FILE *f)
sctx->last_bo_list = NULL;
}
+static void si_dump_framebuffer(struct si_context *sctx, FILE *f)
+{
+ struct pipe_framebuffer_state *state = &sctx->framebuffer.state;
+ struct r600_texture *rtex;
+ int i;
+
+ for (i = 0; i < state->nr_cbufs; i++) {
+ if (!state->cbufs[i])
+ continue;
+
+ rtex = (struct r600_texture*)state->cbufs[i]->texture;
+ fprintf(f, COLOR_YELLOW "Color buffer %i:" COLOR_RESET "\n", i);
+ r600_print_texture_info(rtex, f);
+ fprintf(f, "\n");
+ }
+
+ if (state->zsbuf) {
+ rtex = (struct r600_texture*)state->zsbuf->texture;
+ fprintf(f, COLOR_YELLOW "Depth-stencil buffer:" COLOR_RESET "\n");
+ r600_print_texture_info(rtex, f);
+ fprintf(f, "\n");
+ }
+}
+
static void si_dump_debug_state(struct pipe_context *ctx, FILE *f,
unsigned flags)
{
@@ -536,6 +571,7 @@ static void si_dump_debug_state(struct pipe_context *ctx, FILE *f,
if (flags & PIPE_DEBUG_DEVICE_IS_HUNG)
si_dump_debug_registers(sctx, f);
+ si_dump_framebuffer(sctx, f);
si_dump_shader(&sctx->vs_shader, "Vertex", f);
si_dump_shader(&sctx->tcs_shader, "Tessellation control", f);
si_dump_shader(&sctx->tes_shader, "Tessellation evaluation", f);
@@ -632,7 +668,7 @@ void si_check_vm_faults(struct si_context *sctx)
/* Use conservative timeout 800ms, after which we won't wait any
* longer and assume the GPU is hung.
*/
- screen->fence_finish(screen, sctx->last_gfx_fence, 800*1000*1000);
+ sctx->b.ws->fence_wait(sctx->b.ws, sctx->last_gfx_fence, 800*1000*1000);
if (!si_vm_fault_occured(sctx, &addr))
return;
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 3fa3a9bbd6e..b3719dea252 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -416,7 +416,7 @@ static bool si_upload_vertex_buffer_descriptors(struct si_context *sctx)
vb = &sctx->vertex_buffer[ve->vertex_buffer_index];
rbuffer = (struct r600_resource*)vb->buffer;
- if (rbuffer == NULL) {
+ if (!rbuffer) {
memset(desc, 0, 16);
continue;
}
diff --git a/src/gallium/drivers/radeonsi/si_perfcounter.c b/src/gallium/drivers/radeonsi/si_perfcounter.c
new file mode 100644
index 00000000000..a0ddff6c4e3
--- /dev/null
+++ b/src/gallium/drivers/radeonsi/si_perfcounter.c
@@ -0,0 +1,694 @@
+/*
+ * Copyright 2015 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.
+ *
+ * Authors:
+ * Nicolai Hähnle
+ *
+ */
+
+#include "radeon/r600_cs.h"
+#include "radeon/r600_query.h"
+#include "radeon/r600_pipe_common.h"
+#include "util/u_memory.h"
+
+#include "si_pipe.h"
+#include "sid.h"
+
+enum si_pc_reg_layout {
+ /* All secondary selector dwords follow as one block after the primary
+ * selector dwords for the counters that have secondary selectors.
+ */
+ SI_PC_MULTI_BLOCK = 0,
+
+ /* Each secondary selector dword follows immediately afters the
+ * corresponding primary.
+ */
+ SI_PC_MULTI_ALTERNATE = 1,
+
+ /* All secondary selector dwords follow as one block after all primary
+ * selector dwords.
+ */
+ SI_PC_MULTI_TAIL = 2,
+
+ /* Free-form arrangement of selector registers. */
+ SI_PC_MULTI_CUSTOM = 3,
+
+ SI_PC_MULTI_MASK = 3,
+
+ /* Registers are laid out in decreasing rather than increasing order. */
+ SI_PC_REG_REVERSE = 4,
+};
+
+struct si_pc_block_base {
+ const char *name;
+ unsigned num_counters;
+ unsigned flags;
+
+ unsigned select_or;
+ unsigned select0;
+ unsigned counter0_lo;
+ unsigned *select;
+ unsigned *counters;
+ unsigned num_multi;
+ unsigned num_prelude;
+ unsigned layout;
+};
+
+struct si_pc_block {
+ struct si_pc_block_base *b;
+ unsigned selectors;
+ unsigned instances;
+};
+
+
+static struct si_pc_block_base cik_CB = {
+ .name = "CB",
+ .num_counters = 4,
+ .flags = R600_PC_BLOCK_SE | R600_PC_BLOCK_INSTANCE_GROUPS,
+
+ .select0 = R_037000_CB_PERFCOUNTER_FILTER,
+ .counter0_lo = R_035018_CB_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .num_prelude = 1,
+ .layout = SI_PC_MULTI_ALTERNATE,
+};
+
+static unsigned cik_CPC_select[] = {
+ R_036024_CPC_PERFCOUNTER0_SELECT,
+ R_036010_CPC_PERFCOUNTER0_SELECT1,
+ R_03600C_CPC_PERFCOUNTER1_SELECT,
+};
+static struct si_pc_block_base cik_CPC = {
+ .name = "CPC",
+ .num_counters = 2,
+
+ .select = cik_CPC_select,
+ .counter0_lo = R_034018_CPC_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .layout = SI_PC_MULTI_CUSTOM | SI_PC_REG_REVERSE,
+};
+
+static struct si_pc_block_base cik_CPF = {
+ .name = "CPF",
+ .num_counters = 2,
+
+ .select0 = R_03601C_CPF_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034028_CPF_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .layout = SI_PC_MULTI_ALTERNATE | SI_PC_REG_REVERSE,
+};
+
+static struct si_pc_block_base cik_CPG = {
+ .name = "CPG",
+ .num_counters = 2,
+
+ .select0 = R_036008_CPG_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034008_CPG_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .layout = SI_PC_MULTI_ALTERNATE | SI_PC_REG_REVERSE,
+};
+
+static struct si_pc_block_base cik_DB = {
+ .name = "DB",
+ .num_counters = 4,
+ .flags = R600_PC_BLOCK_SE | R600_PC_BLOCK_INSTANCE_GROUPS,
+
+ .select0 = R_037100_DB_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_035100_DB_PERFCOUNTER0_LO,
+ .num_multi = 3, // really only 2, but there's a gap between registers
+ .layout = SI_PC_MULTI_ALTERNATE,
+};
+
+static struct si_pc_block_base cik_GDS = {
+ .name = "GDS",
+ .num_counters = 4,
+
+ .select0 = R_036A00_GDS_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034A00_GDS_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .layout = SI_PC_MULTI_TAIL,
+};
+
+static unsigned cik_GRBM_counters[] = {
+ R_034100_GRBM_PERFCOUNTER0_LO,
+ R_03410C_GRBM_PERFCOUNTER1_LO,
+};
+static struct si_pc_block_base cik_GRBM = {
+ .name = "GRBM",
+ .num_counters = 2,
+
+ .select0 = R_036100_GRBM_PERFCOUNTER0_SELECT,
+ .counters = cik_GRBM_counters,
+};
+
+static struct si_pc_block_base cik_GRBMSE = {
+ .name = "GRBMSE",
+ .num_counters = 4,
+
+ .select0 = R_036108_GRBM_SE0_PERFCOUNTER_SELECT,
+ .counter0_lo = R_034114_GRBM_SE0_PERFCOUNTER_LO,
+};
+
+static struct si_pc_block_base cik_IA = {
+ .name = "IA",
+ .num_counters = 4,
+
+ .select0 = R_036210_IA_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034220_IA_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .layout = SI_PC_MULTI_TAIL,
+};
+
+static struct si_pc_block_base cik_PA_SC = {
+ .name = "PA_SC",
+ .num_counters = 8,
+ .flags = R600_PC_BLOCK_SE,
+
+ .select0 = R_036500_PA_SC_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034500_PA_SC_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .layout = SI_PC_MULTI_ALTERNATE,
+};
+
+static struct si_pc_block_base cik_PA_SU = {
+ .name = "PA_SU",
+ .num_counters = 4,
+ .flags = R600_PC_BLOCK_SE,
+
+ .select0 = R_036400_PA_SU_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034400_PA_SU_PERFCOUNTER0_LO,
+ .num_multi = 2,
+ .layout = SI_PC_MULTI_ALTERNATE,
+};
+
+static struct si_pc_block_base cik_SPI = {
+ .name = "SPI",
+ .num_counters = 6,
+ .flags = R600_PC_BLOCK_SE,
+
+ .select0 = R_036600_SPI_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034604_SPI_PERFCOUNTER0_LO,
+ .num_multi = 4,
+ .layout = SI_PC_MULTI_BLOCK,
+};
+
+static struct si_pc_block_base cik_SQ = {
+ .name = "SQ",
+ .num_counters = 16,
+ .flags = R600_PC_BLOCK_SE | R600_PC_BLOCK_SHADER,
+
+ .select0 = R_036700_SQ_PERFCOUNTER0_SELECT,
+ .select_or = S_036700_SQC_BANK_MASK(15) |
+ S_036700_SQC_CLIENT_MASK(15) |
+ S_036700_SIMD_MASK(15),
+ .counter0_lo = R_034700_SQ_PERFCOUNTER0_LO,
+};
+
+static struct si_pc_block_base cik_SX = {
+ .name = "SX",
+ .num_counters = 4,
+ .flags = R600_PC_BLOCK_SE,
+
+ .select0 = R_036900_SX_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034900_SX_PERFCOUNTER0_LO,
+ .num_multi = 2,
+ .layout = SI_PC_MULTI_TAIL,
+};
+
+static struct si_pc_block_base cik_TA = {
+ .name = "TA",
+ .num_counters = 2,
+ .flags = R600_PC_BLOCK_SE | R600_PC_BLOCK_INSTANCE_GROUPS | R600_PC_BLOCK_SHADER_WINDOWED,
+
+ .select0 = R_036B00_TA_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034B00_TA_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .layout = SI_PC_MULTI_ALTERNATE,
+};
+
+static struct si_pc_block_base cik_TD = {
+ .name = "TD",
+ .num_counters = 2,
+ .flags = R600_PC_BLOCK_SE | R600_PC_BLOCK_INSTANCE_GROUPS | R600_PC_BLOCK_SHADER_WINDOWED,
+
+ .select0 = R_036C00_TD_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034C00_TD_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .layout = SI_PC_MULTI_ALTERNATE,
+};
+
+static struct si_pc_block_base cik_TCA = {
+ .name = "TCA",
+ .num_counters = 4,
+ .flags = R600_PC_BLOCK_INSTANCE_GROUPS,
+
+ .select0 = R_036E40_TCA_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034E40_TCA_PERFCOUNTER0_LO,
+ .num_multi = 2,
+ .layout = SI_PC_MULTI_ALTERNATE,
+};
+
+static struct si_pc_block_base cik_TCC = {
+ .name = "TCC",
+ .num_counters = 4,
+ .flags = R600_PC_BLOCK_INSTANCE_GROUPS,
+
+ .select0 = R_036E00_TCC_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034E00_TCC_PERFCOUNTER0_LO,
+ .num_multi = 2,
+ .layout = SI_PC_MULTI_ALTERNATE,
+};
+
+static struct si_pc_block_base cik_TCP = {
+ .name = "TCP",
+ .num_counters = 4,
+ .flags = R600_PC_BLOCK_SE | R600_PC_BLOCK_INSTANCE_GROUPS | R600_PC_BLOCK_SHADER_WINDOWED,
+
+ .select0 = R_036D00_TCP_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034D00_TCP_PERFCOUNTER0_LO,
+ .num_multi = 2,
+ .layout = SI_PC_MULTI_ALTERNATE,
+};
+
+static struct si_pc_block_base cik_VGT = {
+ .name = "VGT",
+ .num_counters = 4,
+ .flags = R600_PC_BLOCK_SE,
+
+ .select0 = R_036230_VGT_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034240_VGT_PERFCOUNTER0_LO,
+ .num_multi = 1,
+ .layout = SI_PC_MULTI_TAIL,
+};
+
+static struct si_pc_block_base cik_WD = {
+ .name = "WD",
+ .num_counters = 4,
+
+ .select0 = R_036200_WD_PERFCOUNTER0_SELECT,
+ .counter0_lo = R_034200_WD_PERFCOUNTER0_LO,
+};
+
+/* Both the number of instances and selectors varies between chips of the same
+ * class. We only differentiate by class here and simply expose the maximum
+ * number over all chips in a class.
+ */
+static struct si_pc_block groups_CIK[] = {
+ { &cik_CB, 226, 4 },
+ { &cik_CPC, 22 },
+ { &cik_CPF, 17 },
+ { &cik_CPG, 46 },
+ { &cik_DB, 257, 4 },
+ { &cik_GDS, 121 },
+ { &cik_GRBM, 34 },
+ { &cik_GRBMSE, 15 },
+ { &cik_IA, 22 },
+ { &cik_PA_SC, 395 },
+ { &cik_PA_SU, 153 },
+ { &cik_SPI, 186 },
+ { &cik_SQ, 252 },
+ { &cik_SX, 32 },
+ { &cik_TA, 111, 11 },
+ { &cik_TCA, 39, 2 },
+ { &cik_TCC, 160, 16 },
+ { &cik_TCP, 154, 11 },
+ { &cik_TD, 55, 11 },
+ { &cik_VGT, 140 },
+ { &cik_WD, 22 },
+};
+
+static struct si_pc_block groups_VI[] = {
+ { &cik_CB, 396, 4 },
+ { &cik_CPC, 24 },
+ { &cik_CPF, 19 },
+ { &cik_CPG, 48 },
+ { &cik_DB, 257, 4 },
+ { &cik_GDS, 121 },
+ { &cik_GRBM, 34 },
+ { &cik_GRBMSE, 15 },
+ { &cik_IA, 24 },
+ { &cik_PA_SC, 397 },
+ { &cik_PA_SU, 153 },
+ { &cik_SPI, 197 },
+ { &cik_SQ, 273 },
+ { &cik_SX, 34 },
+ { &cik_TA, 119, 16 },
+ { &cik_TCA, 35, 2 },
+ { &cik_TCC, 192, 16 },
+ { &cik_TCP, 180, 16 },
+ { &cik_TD, 55, 16 },
+ { &cik_VGT, 147 },
+ { &cik_WD, 37 },
+};
+
+static void si_pc_get_size(struct r600_perfcounter_block *group,
+ unsigned count, unsigned *selectors,
+ unsigned *num_select_dw, unsigned *num_read_dw)
+{
+ struct si_pc_block *sigroup = (struct si_pc_block *)group->data;
+ struct si_pc_block_base *regs = sigroup->b;
+ unsigned layout_multi = regs->layout & SI_PC_MULTI_MASK;
+
+ if (layout_multi == SI_PC_MULTI_BLOCK) {
+ if (count < regs->num_multi)
+ *num_select_dw = 2 * (count + 2) + regs->num_prelude;
+ else
+ *num_select_dw = 2 + count + regs->num_multi + regs->num_prelude;
+ } else if (layout_multi == SI_PC_MULTI_TAIL) {
+ *num_select_dw = 4 + count + MIN2(count, regs->num_multi) + regs->num_prelude;
+ } else if (layout_multi == SI_PC_MULTI_CUSTOM) {
+ assert(regs->num_prelude == 0);
+ *num_select_dw = 3 * (count + MIN2(count, regs->num_multi));
+ } else {
+ assert(layout_multi == SI_PC_MULTI_ALTERNATE);
+
+ *num_select_dw = 2 + count + MIN2(count, regs->num_multi) + regs->num_prelude;
+ }
+
+ *num_read_dw = 6 * count;
+}
+
+static void si_pc_emit_instance(struct r600_common_context *ctx,
+ int se, int instance)
+{
+ struct radeon_winsys_cs *cs = ctx->gfx.cs;
+ unsigned value = S_030800_SH_BROADCAST_WRITES(1);
+
+ if (se >= 0) {
+ value |= S_030800_SE_INDEX(se);
+ } else {
+ value |= S_030800_SE_BROADCAST_WRITES(1);
+ }
+
+ if (instance >= 0) {
+ value |= S_030800_INSTANCE_INDEX(instance);
+ } else {
+ value |= S_030800_INSTANCE_BROADCAST_WRITES(1);
+ }
+
+ radeon_set_uconfig_reg(cs, R_030800_GRBM_GFX_INDEX, value);
+}
+
+static void si_pc_emit_shaders(struct r600_common_context *ctx,
+ unsigned shaders)
+{
+ struct radeon_winsys_cs *cs = ctx->gfx.cs;
+
+ radeon_set_uconfig_reg_seq(cs, R_036780_SQ_PERFCOUNTER_CTRL, 2);
+ radeon_emit(cs, shaders & 0x7f);
+ radeon_emit(cs, 0xffffffff);
+}
+
+static void si_pc_emit_select(struct r600_common_context *ctx,
+ struct r600_perfcounter_block *group,
+ unsigned count, unsigned *selectors)
+{
+ struct si_pc_block *sigroup = (struct si_pc_block *)group->data;
+ struct si_pc_block_base *regs = sigroup->b;
+ struct radeon_winsys_cs *cs = ctx->gfx.cs;
+ unsigned idx;
+ unsigned layout_multi = regs->layout & SI_PC_MULTI_MASK;
+ unsigned dw;
+
+ assert(count <= regs->num_counters);
+
+ if (layout_multi == SI_PC_MULTI_BLOCK) {
+ assert(!(regs->layout & SI_PC_REG_REVERSE));
+
+ dw = count + regs->num_prelude;
+ if (count >= regs->num_multi)
+ count += regs->num_multi;
+ radeon_set_uconfig_reg_seq(cs, regs->select0, dw);
+ for (idx = 0; idx < regs->num_prelude; ++idx)
+ radeon_emit(cs, 0);
+ for (idx = 0; idx < MIN2(count, regs->num_multi); ++idx)
+ radeon_emit(cs, selectors[idx] | regs->select_or);
+
+ if (count < regs->num_multi) {
+ unsigned select1 =
+ regs->select0 + 4 * regs->num_multi;
+ radeon_set_uconfig_reg_seq(cs, select1, count);
+ }
+
+ for (idx = 0; idx < MIN2(count, regs->num_multi); ++idx)
+ radeon_emit(cs, 0);
+
+ if (count > regs->num_multi) {
+ for (idx = regs->num_multi; idx < count; ++idx)
+ radeon_emit(cs, selectors[idx] | regs->select_or);
+ }
+ } else if (layout_multi == SI_PC_MULTI_TAIL) {
+ unsigned select1, select1_count;
+
+ assert(!(regs->layout & SI_PC_REG_REVERSE));
+
+ radeon_set_uconfig_reg_seq(cs, regs->select0, count + regs->num_prelude);
+ for (idx = 0; idx < regs->num_prelude; ++idx)
+ radeon_emit(cs, 0);
+ for (idx = 0; idx < count; ++idx)
+ radeon_emit(cs, selectors[idx] | regs->select_or);
+
+ select1 = regs->select0 + 4 * regs->num_counters;
+ select1_count = MIN2(count, regs->num_multi);
+ radeon_set_uconfig_reg_seq(cs, select1, select1_count);
+ for (idx = 0; idx < select1_count; ++idx)
+ radeon_emit(cs, 0);
+ } else if (layout_multi == SI_PC_MULTI_CUSTOM) {
+ unsigned *reg = regs->select;
+ for (idx = 0; idx < count; ++idx) {
+ radeon_set_uconfig_reg(cs, *reg++, selectors[idx] | regs->select_or);
+ if (idx < regs->num_multi)
+ radeon_set_uconfig_reg(cs, *reg++, 0);
+ }
+ } else {
+ assert(layout_multi == SI_PC_MULTI_ALTERNATE);
+
+ unsigned reg_base = regs->select0;
+ unsigned reg_count = count + MIN2(count, regs->num_multi);
+ reg_count += regs->num_prelude;
+
+ if (!(regs->layout & SI_PC_REG_REVERSE)) {
+ radeon_set_uconfig_reg_seq(cs, reg_base, reg_count);
+
+ for (idx = 0; idx < regs->num_prelude; ++idx)
+ radeon_emit(cs, 0);
+ for (idx = 0; idx < count; ++idx) {
+ radeon_emit(cs, selectors[idx] | regs->select_or);
+ if (idx < regs->num_multi)
+ radeon_emit(cs, 0);
+ }
+ } else {
+ reg_base -= (reg_count - 1) * 4;
+ radeon_set_uconfig_reg_seq(cs, reg_base, reg_count);
+
+ for (idx = count; idx > 0; --idx) {
+ if (idx <= regs->num_multi)
+ radeon_emit(cs, 0);
+ radeon_emit(cs, selectors[idx - 1] | regs->select_or);
+ }
+ for (idx = 0; idx < regs->num_prelude; ++idx)
+ radeon_emit(cs, 0);
+ }
+ }
+}
+
+static void si_pc_emit_start(struct r600_common_context *ctx,
+ struct r600_resource *buffer, uint64_t va)
+{
+ struct radeon_winsys_cs *cs = ctx->gfx.cs;
+
+ radeon_add_to_buffer_list(ctx, &ctx->gfx, buffer,
+ RADEON_USAGE_WRITE, RADEON_PRIO_QUERY);
+
+ radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0));
+ radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_IMM) |
+ COPY_DATA_DST_SEL(COPY_DATA_MEM));
+ radeon_emit(cs, 1); /* immediate */
+ radeon_emit(cs, 0); /* unused */
+ radeon_emit(cs, va);
+ radeon_emit(cs, va >> 32);
+
+ radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL,
+ S_036020_PERFMON_STATE(V_036020_DISABLE_AND_RESET));
+ radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
+ radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_PERFCOUNTER_START) | EVENT_INDEX(0));
+ radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL,
+ S_036020_PERFMON_STATE(V_036020_START_COUNTING));
+}
+
+/* Note: The buffer was already added in si_pc_emit_start, so we don't have to
+ * do it again in here. */
+static void si_pc_emit_stop(struct r600_common_context *ctx,
+ struct r600_resource *buffer, uint64_t va)
+{
+ struct radeon_winsys_cs *cs = ctx->gfx.cs;
+
+ if (ctx->screen->chip_class == CIK) {
+ /* Workaround for cache flush problems: send two EOP events. */
+ radeon_emit(cs, PKT3(PKT3_EVENT_WRITE_EOP, 4, 0));
+ radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) |
+ EVENT_INDEX(5));
+ radeon_emit(cs, va);
+ radeon_emit(cs, (va >> 32) | EOP_DATA_SEL(1));
+ radeon_emit(cs, 0); /* immediate data */
+ radeon_emit(cs, 0); /* unused */
+ }
+
+ radeon_emit(cs, PKT3(PKT3_EVENT_WRITE_EOP, 4, 0));
+ radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) |
+ EVENT_INDEX(5));
+ radeon_emit(cs, va);
+ radeon_emit(cs, (va >> 32) | EOP_DATA_SEL(1));
+ radeon_emit(cs, 0); /* immediate data */
+ radeon_emit(cs, 0); /* unused */
+
+ radeon_emit(cs, PKT3(PKT3_WAIT_REG_MEM, 5, 0));
+ radeon_emit(cs, WAIT_REG_MEM_EQUAL | WAIT_REG_MEM_MEM_SPACE(1));
+ radeon_emit(cs, va);
+ radeon_emit(cs, va >> 32);
+ radeon_emit(cs, 0); /* reference value */
+ radeon_emit(cs, 0xffffffff); /* mask */
+ radeon_emit(cs, 4); /* poll interval */
+
+ radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
+ radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_PERFCOUNTER_SAMPLE) | EVENT_INDEX(0));
+ radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
+ radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_PERFCOUNTER_STOP) | EVENT_INDEX(0));
+ radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL,
+ S_036020_PERFMON_STATE(V_036020_STOP_COUNTING) |
+ S_036020_PERFMON_SAMPLE_ENABLE(1));
+}
+
+static void si_pc_emit_read(struct r600_common_context *ctx,
+ struct r600_perfcounter_block *group,
+ unsigned count, unsigned *selectors,
+ struct r600_resource *buffer, uint64_t va)
+{
+ struct si_pc_block *sigroup = (struct si_pc_block *)group->data;
+ struct si_pc_block_base *regs = sigroup->b;
+ struct radeon_winsys_cs *cs = ctx->gfx.cs;
+ unsigned idx;
+ unsigned reg = regs->counter0_lo;
+ unsigned reg_delta = 8;
+
+ if (regs->layout & SI_PC_REG_REVERSE)
+ reg_delta = -reg_delta;
+
+ for (idx = 0; idx < count; ++idx) {
+ if (regs->counters)
+ reg = regs->counters[idx];
+
+ radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0));
+ radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_PERF) |
+ COPY_DATA_DST_SEL(COPY_DATA_MEM));
+ radeon_emit(cs, reg >> 2);
+ radeon_emit(cs, 0); /* unused */
+ radeon_emit(cs, va);
+ radeon_emit(cs, va >> 32);
+ va += 4;
+ reg += reg_delta;
+ }
+}
+
+static void si_pc_cleanup(struct r600_common_screen *rscreen)
+{
+ r600_perfcounters_do_destroy(rscreen->perfcounters);
+ rscreen->perfcounters = NULL;
+}
+
+void si_init_perfcounters(struct si_screen *screen)
+{
+ struct r600_perfcounters *pc;
+ struct si_pc_block *blocks;
+ unsigned num_blocks;
+ unsigned i;
+
+ switch (screen->b.chip_class) {
+ case CIK:
+ blocks = groups_CIK;
+ num_blocks = ARRAY_SIZE(groups_CIK);
+ break;
+ case VI:
+ blocks = groups_VI;
+ num_blocks = ARRAY_SIZE(groups_VI);
+ break;
+ case SI:
+ default:
+ return; /* not implemented */
+ }
+
+ if (screen->b.info.max_sh_per_se != 1) {
+ /* This should not happen on non-SI chips. */
+ fprintf(stderr, "si_init_perfcounters: max_sh_per_se = %d not "
+ "supported (inaccurate performance counters)\n",
+ screen->b.info.max_sh_per_se);
+ }
+
+ pc = CALLOC_STRUCT(r600_perfcounters);
+ if (!pc)
+ return;
+
+ pc->num_start_cs_dwords = 14;
+ pc->num_stop_cs_dwords = 20;
+ pc->num_instance_cs_dwords = 3;
+ pc->num_shaders_cs_dwords = 4;
+
+ if (screen->b.chip_class == CIK) {
+ pc->num_stop_cs_dwords += 6;
+ }
+
+ pc->get_size = si_pc_get_size;
+ pc->emit_instance = si_pc_emit_instance;
+ pc->emit_shaders = si_pc_emit_shaders;
+ pc->emit_select = si_pc_emit_select;
+ pc->emit_start = si_pc_emit_start;
+ pc->emit_stop = si_pc_emit_stop;
+ pc->emit_read = si_pc_emit_read;
+ pc->cleanup = si_pc_cleanup;
+
+ if (!r600_perfcounters_init(pc, num_blocks))
+ goto error;
+
+ for (i = 0; i < num_blocks; ++i) {
+ struct si_pc_block *block = &blocks[i];
+ unsigned instances = block->instances;
+
+ if (!strcmp(block->b->name, "IA")) {
+ if (screen->b.info.max_se > 2)
+ instances = 2;
+ }
+
+ r600_perfcounters_add_block(&screen->b, pc,
+ block->b->name,
+ block->b->flags,
+ block->b->num_counters,
+ block->selectors,
+ instances,
+ block);
+ }
+
+ screen->b.perfcounters = pc;
+ return;
+
+error:
+ r600_perfcounters_do_destroy(pc);
+}
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 9a0fe808ee3..46cb035d74c 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -109,7 +109,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen,
#endif
int shader, i;
- if (sctx == NULL)
+ if (!sctx)
return NULL;
if (sscreen->b.debug_flags & DBG_CHECK_VM)
@@ -520,7 +520,7 @@ static void si_destroy_screen(struct pipe_screen* pscreen)
{
struct si_screen *sscreen = (struct si_screen *)pscreen;
- if (sscreen == NULL)
+ if (!sscreen)
return;
if (!sscreen->b.ws->unref(sscreen->b.ws))
@@ -611,7 +611,7 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
{
struct si_screen *sscreen = CALLOC_STRUCT(si_screen);
- if (sscreen == NULL) {
+ if (!sscreen) {
return NULL;
}
@@ -630,6 +630,9 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
return NULL;
}
+ if (!debug_get_bool_option("RADEON_DISABLE_PERFCOUNTERS", FALSE))
+ si_init_perfcounters(sscreen);
+
sscreen->b.has_cp_dma = true;
sscreen->b.has_streamout = true;
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 05d52fe19dc..834c3587569 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -346,6 +346,9 @@ void si_need_cs_space(struct si_context *ctx);
/* si_compute.c */
void si_init_compute_functions(struct si_context *sctx);
+/* si_perfcounters.c */
+void si_init_perfcounters(struct si_screen *screen);
+
/* si_uvd.c */
struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context,
const struct pipe_video_codec *templ);
diff --git a/src/gallium/drivers/radeonsi/si_pm4.c b/src/gallium/drivers/radeonsi/si_pm4.c
index c4ef2e78c50..c3032fc45b5 100644
--- a/src/gallium/drivers/radeonsi/si_pm4.c
+++ b/src/gallium/drivers/radeonsi/si_pm4.c
@@ -115,7 +115,7 @@ void si_pm4_free_state(struct si_context *sctx,
struct si_pm4_state *state,
unsigned idx)
{
- if (state == NULL)
+ if (!state)
return;
if (idx != ~0 && sctx->emitted.array[idx] == state) {
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 354d0646b99..1baa2eb2178 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -594,6 +594,14 @@ static LLVMValueRef lds_load(struct lp_build_tgsi_context *bld_base,
lp_build_const_int32(gallivm, swizzle));
value = build_indexed_load(si_shader_ctx, si_shader_ctx->lds, dw_addr);
+ if (type == TGSI_TYPE_DOUBLE) {
+ LLVMValueRef value2;
+ dw_addr = lp_build_add(&bld_base->uint_bld, dw_addr,
+ lp_build_const_int32(gallivm, swizzle + 1));
+ value2 = build_indexed_load(si_shader_ctx, si_shader_ctx->lds, dw_addr);
+ return radeon_llvm_emit_fetch_double(bld_base, value, value2);
+ }
+
return LLVMBuildBitCast(gallivm->builder, value,
tgsi2llvmtype(bld_base, type), "");
}
@@ -733,6 +741,7 @@ static LLVMValueRef fetch_input_gs(
unsigned semantic_name = info->input_semantic_name[reg->Register.Index];
unsigned semantic_index = info->input_semantic_index[reg->Register.Index];
unsigned param;
+ LLVMValueRef value;
if (swizzle != ~0 && semantic_name == TGSI_SEMANTIC_PRIMID)
return get_primitive_id(bld_base, swizzle);
@@ -774,11 +783,22 @@ static LLVMValueRef fetch_input_gs(
args[7] = uint->zero; /* SLC */
args[8] = uint->zero; /* TFE */
+ value = lp_build_intrinsic(gallivm->builder,
+ "llvm.SI.buffer.load.dword.i32.i32",
+ i32, args, 9,
+ LLVMReadOnlyAttribute | LLVMNoUnwindAttribute);
+ if (type == TGSI_TYPE_DOUBLE) {
+ LLVMValueRef value2;
+ args[2] = lp_build_const_int32(gallivm, (param * 4 + swizzle + 1) * 256);
+ value2 = lp_build_intrinsic(gallivm->builder,
+ "llvm.SI.buffer.load.dword.i32.i32",
+ i32, args, 9,
+ LLVMReadOnlyAttribute | LLVMNoUnwindAttribute);
+ return radeon_llvm_emit_fetch_double(bld_base,
+ value, value2);
+ }
return LLVMBuildBitCast(gallivm->builder,
- lp_build_intrinsic(gallivm->builder,
- "llvm.SI.buffer.load.dword.i32.i32",
- i32, args, 9,
- LLVMReadOnlyAttribute | LLVMNoUnwindAttribute),
+ value,
tgsi2llvmtype(bld_base, type), "");
}
@@ -3745,12 +3765,14 @@ void si_shader_binary_read_config(const struct si_screen *sscreen,
shader->num_sgprs = MAX2(shader->num_sgprs, (G_00B028_SGPRS(value) + 1) * 8);
shader->num_vgprs = MAX2(shader->num_vgprs, (G_00B028_VGPRS(value) + 1) * 4);
shader->float_mode = G_00B028_FLOAT_MODE(value);
+ shader->rsrc1 = value;
break;
case R_00B02C_SPI_SHADER_PGM_RSRC2_PS:
shader->lds_size = MAX2(shader->lds_size, G_00B02C_EXTRA_LDS_SIZE(value));
break;
case R_00B84C_COMPUTE_PGM_RSRC2:
shader->lds_size = MAX2(shader->lds_size, G_00B84C_LDS_SIZE(value));
+ shader->rsrc2 = value;
break;
case R_0286CC_SPI_PS_INPUT_ENA:
shader->spi_ps_input_ena = value;
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 3400a03d7bb..f089dc73ca1 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -290,8 +290,8 @@ struct si_shader {
bool is_gs_copy_shader;
bool dx10_clamp_mode; /* convert NaNs to 0 */
- unsigned ls_rsrc1;
- unsigned ls_rsrc2;
+ unsigned rsrc1;
+ unsigned rsrc2;
};
static inline struct tgsi_shader_info *si_get_vs_info(struct si_context *sctx)
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 209b940aa11..9f9f3d6610b 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -356,7 +356,7 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
uint32_t color_control = 0;
- if (blend == NULL)
+ if (!blend)
return NULL;
blend->alpha_to_one = state->alpha_to_one;
@@ -681,7 +681,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
unsigned tmp, i;
float psize_min, psize_max;
- if (rs == NULL) {
+ if (!rs) {
return NULL;
}
@@ -803,7 +803,7 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
(struct si_state_rasterizer*)sctx->queued.named.rasterizer;
struct si_state_rasterizer *rs = (struct si_state_rasterizer *)state;
- if (state == NULL)
+ if (!state)
return;
if (sctx->framebuffer.nr_samples > 1 &&
@@ -897,7 +897,7 @@ static void *si_create_dsa_state(struct pipe_context *ctx,
unsigned db_depth_control;
uint32_t db_stencil_control = 0;
- if (dsa == NULL) {
+ if (!dsa) {
return NULL;
}
@@ -953,7 +953,7 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
struct si_context *sctx = (struct si_context *)ctx;
struct si_state_dsa *dsa = state;
- if (state == NULL)
+ if (!state)
return;
si_pm4_bind_state(sctx, dsa, dsa);
@@ -1912,7 +1912,7 @@ static void si_initialize_color_surface(struct si_context *sctx,
color_attrib |= S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
}
if (sctx->b.chip_class >= CIK) {
- color_pitch |= S_028C64_FMASK_TILE_MAX(rtex->fmask.pitch / 8 - 1);
+ color_pitch |= S_028C64_FMASK_TILE_MAX(rtex->fmask.pitch_in_pixels / 8 - 1);
}
}
}
@@ -2419,7 +2419,7 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
uint64_t va;
unsigned last_layer = state->u.tex.last_layer;
- if (view == NULL)
+ if (!view)
return NULL;
/* initialize base object */
@@ -2701,7 +2701,7 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
S_008F1C_TYPE(si_tex_dim(texture->target,
state->target, 0));
view->fmask_state[4] = S_008F20_DEPTH(depth - 1) |
- S_008F20_PITCH(tmp->fmask.pitch - 1);
+ S_008F20_PITCH(tmp->fmask.pitch_in_pixels - 1);
view->fmask_state[5] = S_008F24_BASE_ARRAY(state->u.tex.first_layer) |
S_008F24_LAST_ARRAY(last_layer);
view->fmask_state[6] = 0;
@@ -2762,7 +2762,7 @@ static void *si_create_sampler_state(struct pipe_context *ctx,
unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 2 : 0;
unsigned border_color_type, border_color_index = 0;
- if (rstate == NULL) {
+ if (!rstate) {
return NULL;
}
@@ -3291,7 +3291,7 @@ static void si_init_config(struct si_context *sctx)
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
int i;
- if (pm4 == NULL)
+ if (!pm4)
return;
si_pm4_cmd_begin(pm4, PKT3_CONTEXT_CONTROL);
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index 753abc8c103..771d206b9cc 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -163,7 +163,7 @@ static void si_emit_derived_tess_state(struct si_context *sctx,
perpatch_output_offset = output_patch0_offset + pervertex_output_patch_size;
lds_size = output_patch0_offset + output_patch_size * *num_patches;
- ls_rsrc2 = ls->current->ls_rsrc2;
+ ls_rsrc2 = ls->current->rsrc2;
if (sctx->b.chip_class >= CIK) {
assert(lds_size <= 65536);
@@ -178,7 +178,7 @@ static void si_emit_derived_tess_state(struct si_context *sctx,
if (sctx->b.chip_class == CIK && sctx->b.family != CHIP_HAWAII)
radeon_set_sh_reg(cs, R_00B52C_SPI_SHADER_PGM_RSRC2_LS, ls_rsrc2);
radeon_set_sh_reg_seq(cs, R_00B528_SPI_SHADER_PGM_RSRC1_LS, 2);
- radeon_emit(cs, ls->current->ls_rsrc1);
+ radeon_emit(cs, ls->current->rsrc1);
radeon_emit(cs, ls_rsrc2);
/* Compute userdata SGPRs. */
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 7f6511cf01b..4555ca450b6 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -100,7 +100,7 @@ static void si_shader_ls(struct si_shader *shader)
uint64_t va;
pm4 = shader->pm4 = CALLOC_STRUCT(si_pm4_state);
- if (pm4 == NULL)
+ if (!pm4)
return;
va = shader->bo->gpu_address;
@@ -121,11 +121,11 @@ static void si_shader_ls(struct si_shader *shader)
si_pm4_set_reg(pm4, R_00B520_SPI_SHADER_PGM_LO_LS, va >> 8);
si_pm4_set_reg(pm4, R_00B524_SPI_SHADER_PGM_HI_LS, va >> 40);
- shader->ls_rsrc1 = S_00B528_VGPRS((shader->num_vgprs - 1) / 4) |
+ shader->rsrc1 = S_00B528_VGPRS((shader->num_vgprs - 1) / 4) |
S_00B528_SGPRS((num_sgprs - 1) / 8) |
S_00B528_VGPR_COMP_CNT(vgpr_comp_cnt) |
S_00B528_DX10_CLAMP(shader->dx10_clamp_mode);
- shader->ls_rsrc2 = S_00B52C_USER_SGPR(num_user_sgprs) |
+ shader->rsrc2 = S_00B52C_USER_SGPR(num_user_sgprs) |
S_00B52C_SCRATCH_EN(shader->scratch_bytes_per_wave > 0);
}
@@ -136,7 +136,7 @@ static void si_shader_hs(struct si_shader *shader)
uint64_t va;
pm4 = shader->pm4 = CALLOC_STRUCT(si_pm4_state);
- if (pm4 == NULL)
+ if (!pm4)
return;
va = shader->bo->gpu_address;
@@ -172,7 +172,7 @@ static void si_shader_es(struct si_shader *shader)
pm4 = shader->pm4 = CALLOC_STRUCT(si_pm4_state);
- if (pm4 == NULL)
+ if (!pm4)
return;
va = shader->bo->gpu_address;
@@ -229,7 +229,7 @@ static void si_shader_gs(struct si_shader *shader)
pm4 = shader->pm4 = CALLOC_STRUCT(si_pm4_state);
- if (pm4 == NULL)
+ if (!pm4)
return;
if (gs_max_vert_out <= 128) {
@@ -301,7 +301,7 @@ static void si_shader_vs(struct si_shader *shader)
pm4 = shader->pm4 = CALLOC_STRUCT(si_pm4_state);
- if (pm4 == NULL)
+ if (!pm4)
return;
/* If this is the GS copy shader, the GS state writes this register.
@@ -394,7 +394,7 @@ static void si_shader_ps(struct si_shader *shader)
pm4 = shader->pm4 = CALLOC_STRUCT(si_pm4_state);
- if (pm4 == NULL)
+ if (!pm4)
return;
for (i = 0; i < info->num_inputs; i++) {
diff --git a/src/gallium/drivers/radeonsi/sid.h b/src/gallium/drivers/radeonsi/sid.h
index 0c48340beef..d2648e93c14 100644
--- a/src/gallium/drivers/radeonsi/sid.h
+++ b/src/gallium/drivers/radeonsi/sid.h
@@ -32,7 +32,7 @@
#define SI_CONTEXT_REG_OFFSET 0x00028000
#define SI_CONTEXT_REG_END 0x00029000
#define CIK_UCONFIG_REG_OFFSET 0x00030000
-#define CIK_UCONFIG_REG_END 0x00031000
+#define CIK_UCONFIG_REG_END 0x00038000
#define EVENT_TYPE_CACHE_FLUSH 0x6
#define EVENT_TYPE_PS_PARTIAL_FLUSH 0x10
@@ -127,7 +127,10 @@
#define COPY_DATA_SRC_SEL(x) ((x) & 0xf)
#define COPY_DATA_REG 0
#define COPY_DATA_MEM 1
+#define COPY_DATA_PERF 4
+#define COPY_DATA_IMM 5
#define COPY_DATA_DST_SEL(x) (((x) & 0xf) << 8)
+#define COPY_DATA_COUNT_SEL (1 << 16)
#define COPY_DATA_WR_CONFIRM (1 << 20)
#define PKT3_SURFACE_SYNC 0x43 /* deprecated on CIK, use ACQUIRE_MEM */
#define PKT3_ME_INITIALIZE 0x44 /* not on CIK */
@@ -3727,6 +3730,1019 @@
#define R_00B938_COMPUTE_USER_DATA_14 0x00B938
#define R_00B93C_COMPUTE_USER_DATA_15 0x00B93C
#define R_00B9FC_COMPUTE_NOWHERE 0x00B9FC
+#define R_034000_CPG_PERFCOUNTER1_LO 0x034000
+#define R_034004_CPG_PERFCOUNTER1_HI 0x034004
+#define R_034008_CPG_PERFCOUNTER0_LO 0x034008
+#define R_03400C_CPG_PERFCOUNTER0_HI 0x03400C
+#define R_034010_CPC_PERFCOUNTER1_LO 0x034010
+#define R_034014_CPC_PERFCOUNTER1_HI 0x034014
+#define R_034018_CPC_PERFCOUNTER0_LO 0x034018
+#define R_03401C_CPC_PERFCOUNTER0_HI 0x03401C
+#define R_034020_CPF_PERFCOUNTER1_LO 0x034020
+#define R_034024_CPF_PERFCOUNTER1_HI 0x034024
+#define R_034028_CPF_PERFCOUNTER0_LO 0x034028
+#define R_03402C_CPF_PERFCOUNTER0_HI 0x03402C
+#define R_034100_GRBM_PERFCOUNTER0_LO 0x034100
+#define R_034104_GRBM_PERFCOUNTER0_HI 0x034104
+#define R_03410C_GRBM_PERFCOUNTER1_LO 0x03410C
+#define R_034110_GRBM_PERFCOUNTER1_HI 0x034110
+#define R_034114_GRBM_SE0_PERFCOUNTER_LO 0x034114
+#define R_034118_GRBM_SE0_PERFCOUNTER_HI 0x034118
+#define R_03411C_GRBM_SE1_PERFCOUNTER_LO 0x03411C
+#define R_034120_GRBM_SE1_PERFCOUNTER_HI 0x034120
+#define R_034124_GRBM_SE2_PERFCOUNTER_LO 0x034124
+#define R_034128_GRBM_SE2_PERFCOUNTER_HI 0x034128
+#define R_03412C_GRBM_SE3_PERFCOUNTER_LO 0x03412C
+#define R_034130_GRBM_SE3_PERFCOUNTER_HI 0x034130
+#define R_034200_WD_PERFCOUNTER0_LO 0x034200
+#define R_034204_WD_PERFCOUNTER0_HI 0x034204
+#define R_034208_WD_PERFCOUNTER1_LO 0x034208
+#define R_03420C_WD_PERFCOUNTER1_HI 0x03420C
+#define R_034210_WD_PERFCOUNTER2_LO 0x034210
+#define R_034214_WD_PERFCOUNTER2_HI 0x034214
+#define R_034218_WD_PERFCOUNTER3_LO 0x034218
+#define R_03421C_WD_PERFCOUNTER3_HI 0x03421C
+#define R_034220_IA_PERFCOUNTER0_LO 0x034220
+#define R_034224_IA_PERFCOUNTER0_HI 0x034224
+#define R_034228_IA_PERFCOUNTER1_LO 0x034228
+#define R_03422C_IA_PERFCOUNTER1_HI 0x03422C
+#define R_034230_IA_PERFCOUNTER2_LO 0x034230
+#define R_034234_IA_PERFCOUNTER2_HI 0x034234
+#define R_034238_IA_PERFCOUNTER3_LO 0x034238
+#define R_03423C_IA_PERFCOUNTER3_HI 0x03423C
+#define R_034240_VGT_PERFCOUNTER0_LO 0x034240
+#define R_034244_VGT_PERFCOUNTER0_HI 0x034244
+#define R_034248_VGT_PERFCOUNTER1_LO 0x034248
+#define R_03424C_VGT_PERFCOUNTER1_HI 0x03424C
+#define R_034250_VGT_PERFCOUNTER2_LO 0x034250
+#define R_034254_VGT_PERFCOUNTER2_HI 0x034254
+#define R_034258_VGT_PERFCOUNTER3_LO 0x034258
+#define R_03425C_VGT_PERFCOUNTER3_HI 0x03425C
+#define R_034400_PA_SU_PERFCOUNTER0_LO 0x034400
+#define R_034404_PA_SU_PERFCOUNTER0_HI 0x034404
+#define S_034404_PERFCOUNTER_HI(x) (((x) & 0xFFFF) << 0)
+#define G_034404_PERFCOUNTER_HI(x) (((x) >> 0) & 0xFFFF)
+#define C_034404_PERFCOUNTER_HI 0xFFFF0000
+#define R_034408_PA_SU_PERFCOUNTER1_LO 0x034408
+#define R_03440C_PA_SU_PERFCOUNTER1_HI 0x03440C
+#define R_034410_PA_SU_PERFCOUNTER2_LO 0x034410
+#define R_034414_PA_SU_PERFCOUNTER2_HI 0x034414
+#define R_034418_PA_SU_PERFCOUNTER3_LO 0x034418
+#define R_03441C_PA_SU_PERFCOUNTER3_HI 0x03441C
+#define R_034500_PA_SC_PERFCOUNTER0_LO 0x034500
+#define R_034504_PA_SC_PERFCOUNTER0_HI 0x034504
+#define R_034508_PA_SC_PERFCOUNTER1_LO 0x034508
+#define R_03450C_PA_SC_PERFCOUNTER1_HI 0x03450C
+#define R_034510_PA_SC_PERFCOUNTER2_LO 0x034510
+#define R_034514_PA_SC_PERFCOUNTER2_HI 0x034514
+#define R_034518_PA_SC_PERFCOUNTER3_LO 0x034518
+#define R_03451C_PA_SC_PERFCOUNTER3_HI 0x03451C
+#define R_034520_PA_SC_PERFCOUNTER4_LO 0x034520
+#define R_034524_PA_SC_PERFCOUNTER4_HI 0x034524
+#define R_034528_PA_SC_PERFCOUNTER5_LO 0x034528
+#define R_03452C_PA_SC_PERFCOUNTER5_HI 0x03452C
+#define R_034530_PA_SC_PERFCOUNTER6_LO 0x034530
+#define R_034534_PA_SC_PERFCOUNTER6_HI 0x034534
+#define R_034538_PA_SC_PERFCOUNTER7_LO 0x034538
+#define R_03453C_PA_SC_PERFCOUNTER7_HI 0x03453C
+#define R_034600_SPI_PERFCOUNTER0_HI 0x034600
+#define R_034604_SPI_PERFCOUNTER0_LO 0x034604
+#define R_034608_SPI_PERFCOUNTER1_HI 0x034608
+#define R_03460C_SPI_PERFCOUNTER1_LO 0x03460C
+#define R_034610_SPI_PERFCOUNTER2_HI 0x034610
+#define R_034614_SPI_PERFCOUNTER2_LO 0x034614
+#define R_034618_SPI_PERFCOUNTER3_HI 0x034618
+#define R_03461C_SPI_PERFCOUNTER3_LO 0x03461C
+#define R_034620_SPI_PERFCOUNTER4_HI 0x034620
+#define R_034624_SPI_PERFCOUNTER4_LO 0x034624
+#define R_034628_SPI_PERFCOUNTER5_HI 0x034628
+#define R_03462C_SPI_PERFCOUNTER5_LO 0x03462C
+#define R_034700_SQ_PERFCOUNTER0_LO 0x034700
+#define R_034704_SQ_PERFCOUNTER0_HI 0x034704
+#define R_034708_SQ_PERFCOUNTER1_LO 0x034708
+#define R_03470C_SQ_PERFCOUNTER1_HI 0x03470C
+#define R_034710_SQ_PERFCOUNTER2_LO 0x034710
+#define R_034714_SQ_PERFCOUNTER2_HI 0x034714
+#define R_034718_SQ_PERFCOUNTER3_LO 0x034718
+#define R_03471C_SQ_PERFCOUNTER3_HI 0x03471C
+#define R_034720_SQ_PERFCOUNTER4_LO 0x034720
+#define R_034724_SQ_PERFCOUNTER4_HI 0x034724
+#define R_034728_SQ_PERFCOUNTER5_LO 0x034728
+#define R_03472C_SQ_PERFCOUNTER5_HI 0x03472C
+#define R_034730_SQ_PERFCOUNTER6_LO 0x034730
+#define R_034734_SQ_PERFCOUNTER6_HI 0x034734
+#define R_034738_SQ_PERFCOUNTER7_LO 0x034738
+#define R_03473C_SQ_PERFCOUNTER7_HI 0x03473C
+#define R_034740_SQ_PERFCOUNTER8_LO 0x034740
+#define R_034744_SQ_PERFCOUNTER8_HI 0x034744
+#define R_034748_SQ_PERFCOUNTER9_LO 0x034748
+#define R_03474C_SQ_PERFCOUNTER9_HI 0x03474C
+#define R_034750_SQ_PERFCOUNTER10_LO 0x034750
+#define R_034754_SQ_PERFCOUNTER10_HI 0x034754
+#define R_034758_SQ_PERFCOUNTER11_LO 0x034758
+#define R_03475C_SQ_PERFCOUNTER11_HI 0x03475C
+#define R_034760_SQ_PERFCOUNTER12_LO 0x034760
+#define R_034764_SQ_PERFCOUNTER12_HI 0x034764
+#define R_034768_SQ_PERFCOUNTER13_LO 0x034768
+#define R_03476C_SQ_PERFCOUNTER13_HI 0x03476C
+#define R_034770_SQ_PERFCOUNTER14_LO 0x034770
+#define R_034774_SQ_PERFCOUNTER14_HI 0x034774
+#define R_034778_SQ_PERFCOUNTER15_LO 0x034778
+#define R_03477C_SQ_PERFCOUNTER15_HI 0x03477C
+#define R_034900_SX_PERFCOUNTER0_LO 0x034900
+#define R_034904_SX_PERFCOUNTER0_HI 0x034904
+#define R_034908_SX_PERFCOUNTER1_LO 0x034908
+#define R_03490C_SX_PERFCOUNTER1_HI 0x03490C
+#define R_034910_SX_PERFCOUNTER2_LO 0x034910
+#define R_034914_SX_PERFCOUNTER2_HI 0x034914
+#define R_034918_SX_PERFCOUNTER3_LO 0x034918
+#define R_03491C_SX_PERFCOUNTER3_HI 0x03491C
+#define R_034A00_GDS_PERFCOUNTER0_LO 0x034A00
+#define R_034A04_GDS_PERFCOUNTER0_HI 0x034A04
+#define R_034A08_GDS_PERFCOUNTER1_LO 0x034A08
+#define R_034A0C_GDS_PERFCOUNTER1_HI 0x034A0C
+#define R_034A10_GDS_PERFCOUNTER2_LO 0x034A10
+#define R_034A14_GDS_PERFCOUNTER2_HI 0x034A14
+#define R_034A18_GDS_PERFCOUNTER3_LO 0x034A18
+#define R_034A1C_GDS_PERFCOUNTER3_HI 0x034A1C
+#define R_034B00_TA_PERFCOUNTER0_LO 0x034B00
+#define R_034B04_TA_PERFCOUNTER0_HI 0x034B04
+#define R_034B08_TA_PERFCOUNTER1_LO 0x034B08
+#define R_034B0C_TA_PERFCOUNTER1_HI 0x034B0C
+#define R_034C00_TD_PERFCOUNTER0_LO 0x034C00
+#define R_034C04_TD_PERFCOUNTER0_HI 0x034C04
+#define R_034C08_TD_PERFCOUNTER1_LO 0x034C08
+#define R_034C0C_TD_PERFCOUNTER1_HI 0x034C0C
+#define R_034D00_TCP_PERFCOUNTER0_LO 0x034D00
+#define R_034D04_TCP_PERFCOUNTER0_HI 0x034D04
+#define R_034D08_TCP_PERFCOUNTER1_LO 0x034D08
+#define R_034D0C_TCP_PERFCOUNTER1_HI 0x034D0C
+#define R_034D10_TCP_PERFCOUNTER2_LO 0x034D10
+#define R_034D14_TCP_PERFCOUNTER2_HI 0x034D14
+#define R_034D18_TCP_PERFCOUNTER3_LO 0x034D18
+#define R_034D1C_TCP_PERFCOUNTER3_HI 0x034D1C
+#define R_034E00_TCC_PERFCOUNTER0_LO 0x034E00
+#define R_034E04_TCC_PERFCOUNTER0_HI 0x034E04
+#define R_034E08_TCC_PERFCOUNTER1_LO 0x034E08
+#define R_034E0C_TCC_PERFCOUNTER1_HI 0x034E0C
+#define R_034E10_TCC_PERFCOUNTER2_LO 0x034E10
+#define R_034E14_TCC_PERFCOUNTER2_HI 0x034E14
+#define R_034E18_TCC_PERFCOUNTER3_LO 0x034E18
+#define R_034E1C_TCC_PERFCOUNTER3_HI 0x034E1C
+#define R_034E40_TCA_PERFCOUNTER0_LO 0x034E40
+#define R_034E44_TCA_PERFCOUNTER0_HI 0x034E44
+#define R_034E48_TCA_PERFCOUNTER1_LO 0x034E48
+#define R_034E4C_TCA_PERFCOUNTER1_HI 0x034E4C
+#define R_034E50_TCA_PERFCOUNTER2_LO 0x034E50
+#define R_034E54_TCA_PERFCOUNTER2_HI 0x034E54
+#define R_034E58_TCA_PERFCOUNTER3_LO 0x034E58
+#define R_034E5C_TCA_PERFCOUNTER3_HI 0x034E5C
+#define R_035018_CB_PERFCOUNTER0_LO 0x035018
+#define R_03501C_CB_PERFCOUNTER0_HI 0x03501C
+#define R_035020_CB_PERFCOUNTER1_LO 0x035020
+#define R_035024_CB_PERFCOUNTER1_HI 0x035024
+#define R_035028_CB_PERFCOUNTER2_LO 0x035028
+#define R_03502C_CB_PERFCOUNTER2_HI 0x03502C
+#define R_035030_CB_PERFCOUNTER3_LO 0x035030
+#define R_035034_CB_PERFCOUNTER3_HI 0x035034
+#define R_035100_DB_PERFCOUNTER0_LO 0x035100
+#define R_035104_DB_PERFCOUNTER0_HI 0x035104
+#define R_035108_DB_PERFCOUNTER1_LO 0x035108
+#define R_03510C_DB_PERFCOUNTER1_HI 0x03510C
+#define R_035110_DB_PERFCOUNTER2_LO 0x035110
+#define R_035114_DB_PERFCOUNTER2_HI 0x035114
+#define R_035118_DB_PERFCOUNTER3_LO 0x035118
+#define R_03511C_DB_PERFCOUNTER3_HI 0x03511C
+#define R_035200_RLC_PERFCOUNTER0_LO 0x035200
+#define R_035204_RLC_PERFCOUNTER0_HI 0x035204
+#define R_035208_RLC_PERFCOUNTER1_LO 0x035208
+#define R_03520C_RLC_PERFCOUNTER1_HI 0x03520C
+#define R_036000_CPG_PERFCOUNTER1_SELECT 0x036000
+#define R_036004_CPG_PERFCOUNTER0_SELECT1 0x036004
+#define S_036004_PERF_SEL2(x) (((x) & 0x3F) << 0)
+#define G_036004_PERF_SEL2(x) (((x) >> 0) & 0x3F)
+#define C_036004_PERF_SEL2 0xFFFFFFC0
+#define S_036004_PERF_SEL3(x) (((x) & 0x3F) << 10)
+#define G_036004_PERF_SEL3(x) (((x) >> 10) & 0x3F)
+#define C_036004_PERF_SEL3 0xFFFF03FF
+#define R_036008_CPG_PERFCOUNTER0_SELECT 0x036008
+#define S_036008_PERF_SEL(x) (((x) & 0x3F) << 0)
+#define G_036008_PERF_SEL(x) (((x) >> 0) & 0x3F)
+#define C_036008_PERF_SEL 0xFFFFFFC0
+#define S_036008_PERF_SEL1(x) (((x) & 0x3F) << 10)
+#define G_036008_PERF_SEL1(x) (((x) >> 10) & 0x3F)
+#define C_036008_PERF_SEL1 0xFFFF03FF
+#define S_036008_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036008_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036008_CNTR_MODE 0xFF0FFFFF
+#define R_03600C_CPC_PERFCOUNTER1_SELECT 0x03600C
+#define R_036010_CPC_PERFCOUNTER0_SELECT1 0x036010
+#define S_036010_PERF_SEL2(x) (((x) & 0x3F) << 0)
+#define G_036010_PERF_SEL2(x) (((x) >> 0) & 0x3F)
+#define C_036010_PERF_SEL2 0xFFFFFFC0
+#define S_036010_PERF_SEL3(x) (((x) & 0x3F) << 10)
+#define G_036010_PERF_SEL3(x) (((x) >> 10) & 0x3F)
+#define C_036010_PERF_SEL3 0xFFFF03FF
+#define R_036014_CPF_PERFCOUNTER1_SELECT 0x036014
+#define R_036018_CPF_PERFCOUNTER0_SELECT1 0x036018
+#define S_036018_PERF_SEL2(x) (((x) & 0x3F) << 0)
+#define G_036018_PERF_SEL2(x) (((x) >> 0) & 0x3F)
+#define C_036018_PERF_SEL2 0xFFFFFFC0
+#define S_036018_PERF_SEL3(x) (((x) & 0x3F) << 10)
+#define G_036018_PERF_SEL3(x) (((x) >> 10) & 0x3F)
+#define C_036018_PERF_SEL3 0xFFFF03FF
+#define R_03601C_CPF_PERFCOUNTER0_SELECT 0x03601C
+#define S_03601C_PERF_SEL(x) (((x) & 0x3F) << 0)
+#define G_03601C_PERF_SEL(x) (((x) >> 0) & 0x3F)
+#define C_03601C_PERF_SEL 0xFFFFFFC0
+#define S_03601C_PERF_SEL1(x) (((x) & 0x3F) << 10)
+#define G_03601C_PERF_SEL1(x) (((x) >> 10) & 0x3F)
+#define C_03601C_PERF_SEL1 0xFFFF03FF
+#define S_03601C_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_03601C_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_03601C_CNTR_MODE 0xFF0FFFFF
+#define R_036020_CP_PERFMON_CNTL 0x036020
+#define S_036020_PERFMON_STATE(x) (((x) & 0x0F) << 0)
+#define G_036020_PERFMON_STATE(x) (((x) >> 0) & 0x0F)
+#define C_036020_PERFMON_STATE 0xFFFFFFF0
+#define V_036020_DISABLE_AND_RESET 0x00
+#define V_036020_START_COUNTING 0x01
+#define V_036020_STOP_COUNTING 0x02
+#define S_036020_SPM_PERFMON_STATE(x) (((x) & 0x0F) << 4)
+#define G_036020_SPM_PERFMON_STATE(x) (((x) >> 4) & 0x0F)
+#define C_036020_SPM_PERFMON_STATE 0xFFFFFF0F
+#define S_036020_PERFMON_ENABLE_MODE(x) (((x) & 0x03) << 8)
+#define G_036020_PERFMON_ENABLE_MODE(x) (((x) >> 8) & 0x03)
+#define C_036020_PERFMON_ENABLE_MODE 0xFFFFFCFF
+#define S_036020_PERFMON_SAMPLE_ENABLE(x) (((x) & 0x1) << 10)
+#define G_036020_PERFMON_SAMPLE_ENABLE(x) (((x) >> 10) & 0x1)
+#define C_036020_PERFMON_SAMPLE_ENABLE 0xFFFFFBFF
+#define R_036024_CPC_PERFCOUNTER0_SELECT 0x036024
+#define S_036024_PERF_SEL(x) (((x) & 0x3F) << 0)
+#define G_036024_PERF_SEL(x) (((x) >> 0) & 0x3F)
+#define C_036024_PERF_SEL 0xFFFFFFC0
+#define S_036024_PERF_SEL1(x) (((x) & 0x3F) << 10)
+#define G_036024_PERF_SEL1(x) (((x) >> 10) & 0x3F)
+#define C_036024_PERF_SEL1 0xFFFF03FF
+#define S_036024_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036024_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036024_CNTR_MODE 0xFF0FFFFF
+#define R_036100_GRBM_PERFCOUNTER0_SELECT 0x036100
+#define S_036100_PERF_SEL(x) (((x) & 0x3F) << 0)
+#define G_036100_PERF_SEL(x) (((x) >> 0) & 0x3F)
+#define C_036100_PERF_SEL 0xFFFFFFC0
+#define S_036100_DB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 10)
+#define G_036100_DB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 10) & 0x1)
+#define C_036100_DB_CLEAN_USER_DEFINED_MASK 0xFFFFFBFF
+#define S_036100_CB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 11)
+#define G_036100_CB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 11) & 0x1)
+#define C_036100_CB_CLEAN_USER_DEFINED_MASK 0xFFFFF7FF
+#define S_036100_VGT_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 12)
+#define G_036100_VGT_BUSY_USER_DEFINED_MASK(x) (((x) >> 12) & 0x1)
+#define C_036100_VGT_BUSY_USER_DEFINED_MASK 0xFFFFEFFF
+#define S_036100_TA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 13)
+#define G_036100_TA_BUSY_USER_DEFINED_MASK(x) (((x) >> 13) & 0x1)
+#define C_036100_TA_BUSY_USER_DEFINED_MASK 0xFFFFDFFF
+#define S_036100_SX_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 14)
+#define G_036100_SX_BUSY_USER_DEFINED_MASK(x) (((x) >> 14) & 0x1)
+#define C_036100_SX_BUSY_USER_DEFINED_MASK 0xFFFFBFFF
+#define S_036100_SPI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 16)
+#define G_036100_SPI_BUSY_USER_DEFINED_MASK(x) (((x) >> 16) & 0x1)
+#define C_036100_SPI_BUSY_USER_DEFINED_MASK 0xFFFEFFFF
+#define S_036100_SC_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 17)
+#define G_036100_SC_BUSY_USER_DEFINED_MASK(x) (((x) >> 17) & 0x1)
+#define C_036100_SC_BUSY_USER_DEFINED_MASK 0xFFFDFFFF
+#define S_036100_PA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 18)
+#define G_036100_PA_BUSY_USER_DEFINED_MASK(x) (((x) >> 18) & 0x1)
+#define C_036100_PA_BUSY_USER_DEFINED_MASK 0xFFFBFFFF
+#define S_036100_GRBM_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 19)
+#define G_036100_GRBM_BUSY_USER_DEFINED_MASK(x) (((x) >> 19) & 0x1)
+#define C_036100_GRBM_BUSY_USER_DEFINED_MASK 0xFFF7FFFF
+#define S_036100_DB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 20)
+#define G_036100_DB_BUSY_USER_DEFINED_MASK(x) (((x) >> 20) & 0x1)
+#define C_036100_DB_BUSY_USER_DEFINED_MASK 0xFFEFFFFF
+#define S_036100_CB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 21)
+#define G_036100_CB_BUSY_USER_DEFINED_MASK(x) (((x) >> 21) & 0x1)
+#define C_036100_CB_BUSY_USER_DEFINED_MASK 0xFFDFFFFF
+#define S_036100_CP_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 22)
+#define G_036100_CP_BUSY_USER_DEFINED_MASK(x) (((x) >> 22) & 0x1)
+#define C_036100_CP_BUSY_USER_DEFINED_MASK 0xFFBFFFFF
+#define S_036100_IA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 23)
+#define G_036100_IA_BUSY_USER_DEFINED_MASK(x) (((x) >> 23) & 0x1)
+#define C_036100_IA_BUSY_USER_DEFINED_MASK 0xFF7FFFFF
+#define S_036100_GDS_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 24)
+#define G_036100_GDS_BUSY_USER_DEFINED_MASK(x) (((x) >> 24) & 0x1)
+#define C_036100_GDS_BUSY_USER_DEFINED_MASK 0xFEFFFFFF
+#define S_036100_BCI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 25)
+#define G_036100_BCI_BUSY_USER_DEFINED_MASK(x) (((x) >> 25) & 0x1)
+#define C_036100_BCI_BUSY_USER_DEFINED_MASK 0xFDFFFFFF
+#define S_036100_RLC_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 26)
+#define G_036100_RLC_BUSY_USER_DEFINED_MASK(x) (((x) >> 26) & 0x1)
+#define C_036100_RLC_BUSY_USER_DEFINED_MASK 0xFBFFFFFF
+#define S_036100_TC_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 27)
+#define G_036100_TC_BUSY_USER_DEFINED_MASK(x) (((x) >> 27) & 0x1)
+#define C_036100_TC_BUSY_USER_DEFINED_MASK 0xF7FFFFFF
+#define S_036100_WD_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 28)
+#define G_036100_WD_BUSY_USER_DEFINED_MASK(x) (((x) >> 28) & 0x1)
+#define C_036100_WD_BUSY_USER_DEFINED_MASK 0xEFFFFFFF
+#define R_036104_GRBM_PERFCOUNTER1_SELECT 0x036104
+#define R_036108_GRBM_SE0_PERFCOUNTER_SELECT 0x036108
+#define S_036108_PERF_SEL(x) (((x) & 0x3F) << 0)
+#define G_036108_PERF_SEL(x) (((x) >> 0) & 0x3F)
+#define C_036108_PERF_SEL 0xFFFFFFC0
+#define S_036108_DB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 10)
+#define G_036108_DB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 10) & 0x1)
+#define C_036108_DB_CLEAN_USER_DEFINED_MASK 0xFFFFFBFF
+#define S_036108_CB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 11)
+#define G_036108_CB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 11) & 0x1)
+#define C_036108_CB_CLEAN_USER_DEFINED_MASK 0xFFFFF7FF
+#define S_036108_TA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 12)
+#define G_036108_TA_BUSY_USER_DEFINED_MASK(x) (((x) >> 12) & 0x1)
+#define C_036108_TA_BUSY_USER_DEFINED_MASK 0xFFFFEFFF
+#define S_036108_SX_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 13)
+#define G_036108_SX_BUSY_USER_DEFINED_MASK(x) (((x) >> 13) & 0x1)
+#define C_036108_SX_BUSY_USER_DEFINED_MASK 0xFFFFDFFF
+#define S_036108_SPI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 15)
+#define G_036108_SPI_BUSY_USER_DEFINED_MASK(x) (((x) >> 15) & 0x1)
+#define C_036108_SPI_BUSY_USER_DEFINED_MASK 0xFFFF7FFF
+#define S_036108_SC_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 16)
+#define G_036108_SC_BUSY_USER_DEFINED_MASK(x) (((x) >> 16) & 0x1)
+#define C_036108_SC_BUSY_USER_DEFINED_MASK 0xFFFEFFFF
+#define S_036108_DB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 17)
+#define G_036108_DB_BUSY_USER_DEFINED_MASK(x) (((x) >> 17) & 0x1)
+#define C_036108_DB_BUSY_USER_DEFINED_MASK 0xFFFDFFFF
+#define S_036108_CB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 18)
+#define G_036108_CB_BUSY_USER_DEFINED_MASK(x) (((x) >> 18) & 0x1)
+#define C_036108_CB_BUSY_USER_DEFINED_MASK 0xFFFBFFFF
+#define S_036108_VGT_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 19)
+#define G_036108_VGT_BUSY_USER_DEFINED_MASK(x) (((x) >> 19) & 0x1)
+#define C_036108_VGT_BUSY_USER_DEFINED_MASK 0xFFF7FFFF
+#define S_036108_PA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 20)
+#define G_036108_PA_BUSY_USER_DEFINED_MASK(x) (((x) >> 20) & 0x1)
+#define C_036108_PA_BUSY_USER_DEFINED_MASK 0xFFEFFFFF
+#define S_036108_BCI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 21)
+#define G_036108_BCI_BUSY_USER_DEFINED_MASK(x) (((x) >> 21) & 0x1)
+#define C_036108_BCI_BUSY_USER_DEFINED_MASK 0xFFDFFFFF
+#define R_03610C_GRBM_SE1_PERFCOUNTER_SELECT 0x03610C
+#define S_03610C_PERF_SEL(x) (((x) & 0x3F) << 0)
+#define G_03610C_PERF_SEL(x) (((x) >> 0) & 0x3F)
+#define C_03610C_PERF_SEL 0xFFFFFFC0
+#define S_03610C_DB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 10)
+#define G_03610C_DB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 10) & 0x1)
+#define C_03610C_DB_CLEAN_USER_DEFINED_MASK 0xFFFFFBFF
+#define S_03610C_CB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 11)
+#define G_03610C_CB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 11) & 0x1)
+#define C_03610C_CB_CLEAN_USER_DEFINED_MASK 0xFFFFF7FF
+#define S_03610C_TA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 12)
+#define G_03610C_TA_BUSY_USER_DEFINED_MASK(x) (((x) >> 12) & 0x1)
+#define C_03610C_TA_BUSY_USER_DEFINED_MASK 0xFFFFEFFF
+#define S_03610C_SX_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 13)
+#define G_03610C_SX_BUSY_USER_DEFINED_MASK(x) (((x) >> 13) & 0x1)
+#define C_03610C_SX_BUSY_USER_DEFINED_MASK 0xFFFFDFFF
+#define S_03610C_SPI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 15)
+#define G_03610C_SPI_BUSY_USER_DEFINED_MASK(x) (((x) >> 15) & 0x1)
+#define C_03610C_SPI_BUSY_USER_DEFINED_MASK 0xFFFF7FFF
+#define S_03610C_SC_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 16)
+#define G_03610C_SC_BUSY_USER_DEFINED_MASK(x) (((x) >> 16) & 0x1)
+#define C_03610C_SC_BUSY_USER_DEFINED_MASK 0xFFFEFFFF
+#define S_03610C_DB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 17)
+#define G_03610C_DB_BUSY_USER_DEFINED_MASK(x) (((x) >> 17) & 0x1)
+#define C_03610C_DB_BUSY_USER_DEFINED_MASK 0xFFFDFFFF
+#define S_03610C_CB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 18)
+#define G_03610C_CB_BUSY_USER_DEFINED_MASK(x) (((x) >> 18) & 0x1)
+#define C_03610C_CB_BUSY_USER_DEFINED_MASK 0xFFFBFFFF
+#define S_03610C_VGT_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 19)
+#define G_03610C_VGT_BUSY_USER_DEFINED_MASK(x) (((x) >> 19) & 0x1)
+#define C_03610C_VGT_BUSY_USER_DEFINED_MASK 0xFFF7FFFF
+#define S_03610C_PA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 20)
+#define G_03610C_PA_BUSY_USER_DEFINED_MASK(x) (((x) >> 20) & 0x1)
+#define C_03610C_PA_BUSY_USER_DEFINED_MASK 0xFFEFFFFF
+#define S_03610C_BCI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 21)
+#define G_03610C_BCI_BUSY_USER_DEFINED_MASK(x) (((x) >> 21) & 0x1)
+#define C_03610C_BCI_BUSY_USER_DEFINED_MASK 0xFFDFFFFF
+#define R_036110_GRBM_SE2_PERFCOUNTER_SELECT 0x036110
+#define S_036110_PERF_SEL(x) (((x) & 0x3F) << 0)
+#define G_036110_PERF_SEL(x) (((x) >> 0) & 0x3F)
+#define C_036110_PERF_SEL 0xFFFFFFC0
+#define S_036110_DB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 10)
+#define G_036110_DB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 10) & 0x1)
+#define C_036110_DB_CLEAN_USER_DEFINED_MASK 0xFFFFFBFF
+#define S_036110_CB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 11)
+#define G_036110_CB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 11) & 0x1)
+#define C_036110_CB_CLEAN_USER_DEFINED_MASK 0xFFFFF7FF
+#define S_036110_TA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 12)
+#define G_036110_TA_BUSY_USER_DEFINED_MASK(x) (((x) >> 12) & 0x1)
+#define C_036110_TA_BUSY_USER_DEFINED_MASK 0xFFFFEFFF
+#define S_036110_SX_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 13)
+#define G_036110_SX_BUSY_USER_DEFINED_MASK(x) (((x) >> 13) & 0x1)
+#define C_036110_SX_BUSY_USER_DEFINED_MASK 0xFFFFDFFF
+#define S_036110_SPI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 15)
+#define G_036110_SPI_BUSY_USER_DEFINED_MASK(x) (((x) >> 15) & 0x1)
+#define C_036110_SPI_BUSY_USER_DEFINED_MASK 0xFFFF7FFF
+#define S_036110_SC_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 16)
+#define G_036110_SC_BUSY_USER_DEFINED_MASK(x) (((x) >> 16) & 0x1)
+#define C_036110_SC_BUSY_USER_DEFINED_MASK 0xFFFEFFFF
+#define S_036110_DB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 17)
+#define G_036110_DB_BUSY_USER_DEFINED_MASK(x) (((x) >> 17) & 0x1)
+#define C_036110_DB_BUSY_USER_DEFINED_MASK 0xFFFDFFFF
+#define S_036110_CB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 18)
+#define G_036110_CB_BUSY_USER_DEFINED_MASK(x) (((x) >> 18) & 0x1)
+#define C_036110_CB_BUSY_USER_DEFINED_MASK 0xFFFBFFFF
+#define S_036110_VGT_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 19)
+#define G_036110_VGT_BUSY_USER_DEFINED_MASK(x) (((x) >> 19) & 0x1)
+#define C_036110_VGT_BUSY_USER_DEFINED_MASK 0xFFF7FFFF
+#define S_036110_PA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 20)
+#define G_036110_PA_BUSY_USER_DEFINED_MASK(x) (((x) >> 20) & 0x1)
+#define C_036110_PA_BUSY_USER_DEFINED_MASK 0xFFEFFFFF
+#define S_036110_BCI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 21)
+#define G_036110_BCI_BUSY_USER_DEFINED_MASK(x) (((x) >> 21) & 0x1)
+#define C_036110_BCI_BUSY_USER_DEFINED_MASK 0xFFDFFFFF
+#define R_036114_GRBM_SE3_PERFCOUNTER_SELECT 0x036114
+#define S_036114_PERF_SEL(x) (((x) & 0x3F) << 0)
+#define G_036114_PERF_SEL(x) (((x) >> 0) & 0x3F)
+#define C_036114_PERF_SEL 0xFFFFFFC0
+#define S_036114_DB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 10)
+#define G_036114_DB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 10) & 0x1)
+#define C_036114_DB_CLEAN_USER_DEFINED_MASK 0xFFFFFBFF
+#define S_036114_CB_CLEAN_USER_DEFINED_MASK(x) (((x) & 0x1) << 11)
+#define G_036114_CB_CLEAN_USER_DEFINED_MASK(x) (((x) >> 11) & 0x1)
+#define C_036114_CB_CLEAN_USER_DEFINED_MASK 0xFFFFF7FF
+#define S_036114_TA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 12)
+#define G_036114_TA_BUSY_USER_DEFINED_MASK(x) (((x) >> 12) & 0x1)
+#define C_036114_TA_BUSY_USER_DEFINED_MASK 0xFFFFEFFF
+#define S_036114_SX_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 13)
+#define G_036114_SX_BUSY_USER_DEFINED_MASK(x) (((x) >> 13) & 0x1)
+#define C_036114_SX_BUSY_USER_DEFINED_MASK 0xFFFFDFFF
+#define S_036114_SPI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 15)
+#define G_036114_SPI_BUSY_USER_DEFINED_MASK(x) (((x) >> 15) & 0x1)
+#define C_036114_SPI_BUSY_USER_DEFINED_MASK 0xFFFF7FFF
+#define S_036114_SC_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 16)
+#define G_036114_SC_BUSY_USER_DEFINED_MASK(x) (((x) >> 16) & 0x1)
+#define C_036114_SC_BUSY_USER_DEFINED_MASK 0xFFFEFFFF
+#define S_036114_DB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 17)
+#define G_036114_DB_BUSY_USER_DEFINED_MASK(x) (((x) >> 17) & 0x1)
+#define C_036114_DB_BUSY_USER_DEFINED_MASK 0xFFFDFFFF
+#define S_036114_CB_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 18)
+#define G_036114_CB_BUSY_USER_DEFINED_MASK(x) (((x) >> 18) & 0x1)
+#define C_036114_CB_BUSY_USER_DEFINED_MASK 0xFFFBFFFF
+#define S_036114_VGT_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 19)
+#define G_036114_VGT_BUSY_USER_DEFINED_MASK(x) (((x) >> 19) & 0x1)
+#define C_036114_VGT_BUSY_USER_DEFINED_MASK 0xFFF7FFFF
+#define S_036114_PA_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 20)
+#define G_036114_PA_BUSY_USER_DEFINED_MASK(x) (((x) >> 20) & 0x1)
+#define C_036114_PA_BUSY_USER_DEFINED_MASK 0xFFEFFFFF
+#define S_036114_BCI_BUSY_USER_DEFINED_MASK(x) (((x) & 0x1) << 21)
+#define G_036114_BCI_BUSY_USER_DEFINED_MASK(x) (((x) >> 21) & 0x1)
+#define C_036114_BCI_BUSY_USER_DEFINED_MASK 0xFFDFFFFF
+#define R_036200_WD_PERFCOUNTER0_SELECT 0x036200
+#define S_036200_PERF_SEL(x) (((x) & 0xFF) << 0)
+#define G_036200_PERF_SEL(x) (((x) >> 0) & 0xFF)
+#define C_036200_PERF_SEL 0xFFFFFF00
+#define S_036200_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_036200_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_036200_PERF_MODE 0x0FFFFFFF
+#define R_036204_WD_PERFCOUNTER1_SELECT 0x036204
+#define R_036208_WD_PERFCOUNTER2_SELECT 0x036208
+#define R_03620C_WD_PERFCOUNTER3_SELECT 0x03620C
+#define R_036210_IA_PERFCOUNTER0_SELECT 0x036210
+#define S_036210_PERF_SEL(x) (((x) & 0x3FF) << 0)
+#define G_036210_PERF_SEL(x) (((x) >> 0) & 0x3FF)
+#define C_036210_PERF_SEL 0xFFFFFC00
+#define S_036210_PERF_SEL1(x) (((x) & 0x3FF) << 10)
+#define G_036210_PERF_SEL1(x) (((x) >> 10) & 0x3FF)
+#define C_036210_PERF_SEL1 0xFFF003FF
+#define S_036210_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036210_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036210_CNTR_MODE 0xFF0FFFFF
+#define S_036210_PERF_MODE1(x) (((x) & 0x0F) << 24)
+#define G_036210_PERF_MODE1(x) (((x) >> 24) & 0x0F)
+#define C_036210_PERF_MODE1 0xF0FFFFFF
+#define S_036210_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_036210_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_036210_PERF_MODE 0x0FFFFFFF
+#define R_036214_IA_PERFCOUNTER1_SELECT 0x036214
+#define R_036218_IA_PERFCOUNTER2_SELECT 0x036218
+#define R_03621C_IA_PERFCOUNTER3_SELECT 0x03621C
+#define R_036220_IA_PERFCOUNTER0_SELECT1 0x036220
+#define S_036220_PERF_SEL2(x) (((x) & 0x3FF) << 0)
+#define G_036220_PERF_SEL2(x) (((x) >> 0) & 0x3FF)
+#define C_036220_PERF_SEL2 0xFFFFFC00
+#define S_036220_PERF_SEL3(x) (((x) & 0x3FF) << 10)
+#define G_036220_PERF_SEL3(x) (((x) >> 10) & 0x3FF)
+#define C_036220_PERF_SEL3 0xFFF003FF
+#define S_036220_PERF_MODE3(x) (((x) & 0x0F) << 24)
+#define G_036220_PERF_MODE3(x) (((x) >> 24) & 0x0F)
+#define C_036220_PERF_MODE3 0xF0FFFFFF
+#define S_036220_PERF_MODE2(x) (((x) & 0x0F) << 28)
+#define G_036220_PERF_MODE2(x) (((x) >> 28) & 0x0F)
+#define C_036220_PERF_MODE2 0x0FFFFFFF
+#define R_036230_VGT_PERFCOUNTER0_SELECT 0x036230
+#define S_036230_PERF_SEL(x) (((x) & 0x3FF) << 0)
+#define G_036230_PERF_SEL(x) (((x) >> 0) & 0x3FF)
+#define C_036230_PERF_SEL 0xFFFFFC00
+#define S_036230_PERF_SEL1(x) (((x) & 0x3FF) << 10)
+#define G_036230_PERF_SEL1(x) (((x) >> 10) & 0x3FF)
+#define C_036230_PERF_SEL1 0xFFF003FF
+#define S_036230_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036230_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036230_CNTR_MODE 0xFF0FFFFF
+#define S_036230_PERF_MODE1(x) (((x) & 0x0F) << 24)
+#define G_036230_PERF_MODE1(x) (((x) >> 24) & 0x0F)
+#define C_036230_PERF_MODE1 0xF0FFFFFF
+#define S_036230_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_036230_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_036230_PERF_MODE 0x0FFFFFFF
+#define R_036234_VGT_PERFCOUNTER1_SELECT 0x036234
+#define R_036238_VGT_PERFCOUNTER2_SELECT 0x036238
+#define R_03623C_VGT_PERFCOUNTER3_SELECT 0x03623C
+#define R_036240_VGT_PERFCOUNTER0_SELECT1 0x036240
+#define S_036240_PERF_SEL2(x) (((x) & 0x3FF) << 0)
+#define G_036240_PERF_SEL2(x) (((x) >> 0) & 0x3FF)
+#define C_036240_PERF_SEL2 0xFFFFFC00
+#define S_036240_PERF_SEL3(x) (((x) & 0x3FF) << 10)
+#define G_036240_PERF_SEL3(x) (((x) >> 10) & 0x3FF)
+#define C_036240_PERF_SEL3 0xFFF003FF
+#define S_036240_PERF_MODE3(x) (((x) & 0x0F) << 24)
+#define G_036240_PERF_MODE3(x) (((x) >> 24) & 0x0F)
+#define C_036240_PERF_MODE3 0xF0FFFFFF
+#define S_036240_PERF_MODE2(x) (((x) & 0x0F) << 28)
+#define G_036240_PERF_MODE2(x) (((x) >> 28) & 0x0F)
+#define C_036240_PERF_MODE2 0x0FFFFFFF
+#define R_036244_VGT_PERFCOUNTER1_SELECT1 0x036244
+#define R_036250_VGT_PERFCOUNTER_SEID_MASK 0x036250
+#define S_036250_PERF_SEID_IGNORE_MASK(x) (((x) & 0xFF) << 0)
+#define G_036250_PERF_SEID_IGNORE_MASK(x) (((x) >> 0) & 0xFF)
+#define C_036250_PERF_SEID_IGNORE_MASK 0xFFFFFF00
+#define R_036400_PA_SU_PERFCOUNTER0_SELECT 0x036400
+#define S_036400_PERF_SEL(x) (((x) & 0x3FF) << 0)
+#define G_036400_PERF_SEL(x) (((x) >> 0) & 0x3FF)
+#define C_036400_PERF_SEL 0xFFFFFC00
+#define S_036400_PERF_SEL1(x) (((x) & 0x3FF) << 10)
+#define G_036400_PERF_SEL1(x) (((x) >> 10) & 0x3FF)
+#define C_036400_PERF_SEL1 0xFFF003FF
+#define S_036400_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036400_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036400_CNTR_MODE 0xFF0FFFFF
+#define R_036404_PA_SU_PERFCOUNTER0_SELECT1 0x036404
+#define S_036404_PERF_SEL2(x) (((x) & 0x3FF) << 0)
+#define G_036404_PERF_SEL2(x) (((x) >> 0) & 0x3FF)
+#define C_036404_PERF_SEL2 0xFFFFFC00
+#define S_036404_PERF_SEL3(x) (((x) & 0x3FF) << 10)
+#define G_036404_PERF_SEL3(x) (((x) >> 10) & 0x3FF)
+#define C_036404_PERF_SEL3 0xFFF003FF
+#define R_036408_PA_SU_PERFCOUNTER1_SELECT 0x036408
+#define R_03640C_PA_SU_PERFCOUNTER1_SELECT1 0x03640C
+#define R_036410_PA_SU_PERFCOUNTER2_SELECT 0x036410
+#define R_036414_PA_SU_PERFCOUNTER3_SELECT 0x036414
+#define R_036500_PA_SC_PERFCOUNTER0_SELECT 0x036500
+#define S_036500_PERF_SEL(x) (((x) & 0x3FF) << 0)
+#define G_036500_PERF_SEL(x) (((x) >> 0) & 0x3FF)
+#define C_036500_PERF_SEL 0xFFFFFC00
+#define S_036500_PERF_SEL1(x) (((x) & 0x3FF) << 10)
+#define G_036500_PERF_SEL1(x) (((x) >> 10) & 0x3FF)
+#define C_036500_PERF_SEL1 0xFFF003FF
+#define S_036500_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036500_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036500_CNTR_MODE 0xFF0FFFFF
+#define R_036504_PA_SC_PERFCOUNTER0_SELECT1 0x036504
+#define S_036504_PERF_SEL2(x) (((x) & 0x3FF) << 0)
+#define G_036504_PERF_SEL2(x) (((x) >> 0) & 0x3FF)
+#define C_036504_PERF_SEL2 0xFFFFFC00
+#define S_036504_PERF_SEL3(x) (((x) & 0x3FF) << 10)
+#define G_036504_PERF_SEL3(x) (((x) >> 10) & 0x3FF)
+#define C_036504_PERF_SEL3 0xFFF003FF
+#define R_036508_PA_SC_PERFCOUNTER1_SELECT 0x036508
+#define R_03650C_PA_SC_PERFCOUNTER2_SELECT 0x03650C
+#define R_036510_PA_SC_PERFCOUNTER3_SELECT 0x036510
+#define R_036514_PA_SC_PERFCOUNTER4_SELECT 0x036514
+#define R_036518_PA_SC_PERFCOUNTER5_SELECT 0x036518
+#define R_03651C_PA_SC_PERFCOUNTER6_SELECT 0x03651C
+#define R_036520_PA_SC_PERFCOUNTER7_SELECT 0x036520
+#define R_036600_SPI_PERFCOUNTER0_SELECT 0x036600
+#define S_036600_PERF_SEL(x) (((x) & 0x3FF) << 0)
+#define G_036600_PERF_SEL(x) (((x) >> 0) & 0x3FF)
+#define C_036600_PERF_SEL 0xFFFFFC00
+#define S_036600_PERF_SEL1(x) (((x) & 0x3FF) << 10)
+#define G_036600_PERF_SEL1(x) (((x) >> 10) & 0x3FF)
+#define C_036600_PERF_SEL1 0xFFF003FF
+#define S_036600_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036600_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036600_CNTR_MODE 0xFF0FFFFF
+#define R_036604_SPI_PERFCOUNTER1_SELECT 0x036604
+#define R_036608_SPI_PERFCOUNTER2_SELECT 0x036608
+#define R_03660C_SPI_PERFCOUNTER3_SELECT 0x03660C
+#define R_036610_SPI_PERFCOUNTER0_SELECT1 0x036610
+#define S_036610_PERF_SEL2(x) (((x) & 0x3FF) << 0)
+#define G_036610_PERF_SEL2(x) (((x) >> 0) & 0x3FF)
+#define C_036610_PERF_SEL2 0xFFFFFC00
+#define S_036610_PERF_SEL3(x) (((x) & 0x3FF) << 10)
+#define G_036610_PERF_SEL3(x) (((x) >> 10) & 0x3FF)
+#define C_036610_PERF_SEL3 0xFFF003FF
+#define R_036614_SPI_PERFCOUNTER1_SELECT1 0x036614
+#define R_036618_SPI_PERFCOUNTER2_SELECT1 0x036618
+#define R_03661C_SPI_PERFCOUNTER3_SELECT1 0x03661C
+#define R_036620_SPI_PERFCOUNTER4_SELECT 0x036620
+#define R_036624_SPI_PERFCOUNTER5_SELECT 0x036624
+#define R_036628_SPI_PERFCOUNTER_BINS 0x036628
+#define S_036628_BIN0_MIN(x) (((x) & 0x0F) << 0)
+#define G_036628_BIN0_MIN(x) (((x) >> 0) & 0x0F)
+#define C_036628_BIN0_MIN 0xFFFFFFF0
+#define S_036628_BIN0_MAX(x) (((x) & 0x0F) << 4)
+#define G_036628_BIN0_MAX(x) (((x) >> 4) & 0x0F)
+#define C_036628_BIN0_MAX 0xFFFFFF0F
+#define S_036628_BIN1_MIN(x) (((x) & 0x0F) << 8)
+#define G_036628_BIN1_MIN(x) (((x) >> 8) & 0x0F)
+#define C_036628_BIN1_MIN 0xFFFFF0FF
+#define S_036628_BIN1_MAX(x) (((x) & 0x0F) << 12)
+#define G_036628_BIN1_MAX(x) (((x) >> 12) & 0x0F)
+#define C_036628_BIN1_MAX 0xFFFF0FFF
+#define S_036628_BIN2_MIN(x) (((x) & 0x0F) << 16)
+#define G_036628_BIN2_MIN(x) (((x) >> 16) & 0x0F)
+#define C_036628_BIN2_MIN 0xFFF0FFFF
+#define S_036628_BIN2_MAX(x) (((x) & 0x0F) << 20)
+#define G_036628_BIN2_MAX(x) (((x) >> 20) & 0x0F)
+#define C_036628_BIN2_MAX 0xFF0FFFFF
+#define S_036628_BIN3_MIN(x) (((x) & 0x0F) << 24)
+#define G_036628_BIN3_MIN(x) (((x) >> 24) & 0x0F)
+#define C_036628_BIN3_MIN 0xF0FFFFFF
+#define S_036628_BIN3_MAX(x) (((x) & 0x0F) << 28)
+#define G_036628_BIN3_MAX(x) (((x) >> 28) & 0x0F)
+#define C_036628_BIN3_MAX 0x0FFFFFFF
+#define R_036700_SQ_PERFCOUNTER0_SELECT 0x036700
+#define S_036700_PERF_SEL(x) (((x) & 0x1FF) << 0)
+#define G_036700_PERF_SEL(x) (((x) >> 0) & 0x1FF)
+#define C_036700_PERF_SEL 0xFFFFFE00
+#define S_036700_SQC_BANK_MASK(x) (((x) & 0x0F) << 12)
+#define G_036700_SQC_BANK_MASK(x) (((x) >> 12) & 0x0F)
+#define C_036700_SQC_BANK_MASK 0xFFFF0FFF
+#define S_036700_SQC_CLIENT_MASK(x) (((x) & 0x0F) << 16)
+#define G_036700_SQC_CLIENT_MASK(x) (((x) >> 16) & 0x0F)
+#define C_036700_SQC_CLIENT_MASK 0xFFF0FFFF
+#define S_036700_SPM_MODE(x) (((x) & 0x0F) << 20)
+#define G_036700_SPM_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036700_SPM_MODE 0xFF0FFFFF
+#define S_036700_SIMD_MASK(x) (((x) & 0x0F) << 24)
+#define G_036700_SIMD_MASK(x) (((x) >> 24) & 0x0F)
+#define C_036700_SIMD_MASK 0xF0FFFFFF
+#define S_036700_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_036700_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_036700_PERF_MODE 0x0FFFFFFF
+#define R_036704_SQ_PERFCOUNTER1_SELECT 0x036704
+#define R_036708_SQ_PERFCOUNTER2_SELECT 0x036708
+#define R_03670C_SQ_PERFCOUNTER3_SELECT 0x03670C
+#define R_036710_SQ_PERFCOUNTER4_SELECT 0x036710
+#define R_036714_SQ_PERFCOUNTER5_SELECT 0x036714
+#define R_036718_SQ_PERFCOUNTER6_SELECT 0x036718
+#define R_03671C_SQ_PERFCOUNTER7_SELECT 0x03671C
+#define R_036720_SQ_PERFCOUNTER8_SELECT 0x036720
+#define R_036724_SQ_PERFCOUNTER9_SELECT 0x036724
+#define R_036728_SQ_PERFCOUNTER10_SELECT 0x036728
+#define R_03672C_SQ_PERFCOUNTER11_SELECT 0x03672C
+#define R_036730_SQ_PERFCOUNTER12_SELECT 0x036730
+#define R_036734_SQ_PERFCOUNTER13_SELECT 0x036734
+#define R_036738_SQ_PERFCOUNTER14_SELECT 0x036738
+#define R_03673C_SQ_PERFCOUNTER15_SELECT 0x03673C
+#define R_036780_SQ_PERFCOUNTER_CTRL 0x036780
+#define S_036780_PS_EN(x) (((x) & 0x1) << 0)
+#define G_036780_PS_EN(x) (((x) >> 0) & 0x1)
+#define C_036780_PS_EN 0xFFFFFFFE
+#define S_036780_VS_EN(x) (((x) & 0x1) << 1)
+#define G_036780_VS_EN(x) (((x) >> 1) & 0x1)
+#define C_036780_VS_EN 0xFFFFFFFD
+#define S_036780_GS_EN(x) (((x) & 0x1) << 2)
+#define G_036780_GS_EN(x) (((x) >> 2) & 0x1)
+#define C_036780_GS_EN 0xFFFFFFFB
+#define S_036780_ES_EN(x) (((x) & 0x1) << 3)
+#define G_036780_ES_EN(x) (((x) >> 3) & 0x1)
+#define C_036780_ES_EN 0xFFFFFFF7
+#define S_036780_HS_EN(x) (((x) & 0x1) << 4)
+#define G_036780_HS_EN(x) (((x) >> 4) & 0x1)
+#define C_036780_HS_EN 0xFFFFFFEF
+#define S_036780_LS_EN(x) (((x) & 0x1) << 5)
+#define G_036780_LS_EN(x) (((x) >> 5) & 0x1)
+#define C_036780_LS_EN 0xFFFFFFDF
+#define S_036780_CS_EN(x) (((x) & 0x1) << 6)
+#define G_036780_CS_EN(x) (((x) >> 6) & 0x1)
+#define C_036780_CS_EN 0xFFFFFFBF
+#define S_036780_CNTR_RATE(x) (((x) & 0x1F) << 8)
+#define G_036780_CNTR_RATE(x) (((x) >> 8) & 0x1F)
+#define C_036780_CNTR_RATE 0xFFFFE0FF
+#define S_036780_DISABLE_FLUSH(x) (((x) & 0x1) << 13)
+#define G_036780_DISABLE_FLUSH(x) (((x) >> 13) & 0x1)
+#define C_036780_DISABLE_FLUSH 0xFFFFDFFF
+#define R_036784_SQ_PERFCOUNTER_MASK 0x036784
+#define S_036784_SH0_MASK(x) (((x) & 0xFFFF) << 0)
+#define G_036784_SH0_MASK(x) (((x) >> 0) & 0xFFFF)
+#define C_036784_SH0_MASK 0xFFFF0000
+#define S_036784_SH1_MASK(x) (((x) & 0xFFFF) << 16)
+#define G_036784_SH1_MASK(x) (((x) >> 16) & 0xFFFF)
+#define C_036784_SH1_MASK 0x0000FFFF
+#define R_036788_SQ_PERFCOUNTER_CTRL2 0x036788
+#define S_036788_FORCE_EN(x) (((x) & 0x1) << 0)
+#define G_036788_FORCE_EN(x) (((x) >> 0) & 0x1)
+#define C_036788_FORCE_EN 0xFFFFFFFE
+#define R_036900_SX_PERFCOUNTER0_SELECT 0x036900
+#define S_036900_PERFCOUNTER_SELECT(x) (((x) & 0x3FF) << 0)
+#define G_036900_PERFCOUNTER_SELECT(x) (((x) >> 0) & 0x3FF)
+#define C_036900_PERFCOUNTER_SELECT 0xFFFFFC00
+#define S_036900_PERFCOUNTER_SELECT1(x) (((x) & 0x3FF) << 10)
+#define G_036900_PERFCOUNTER_SELECT1(x) (((x) >> 10) & 0x3FF)
+#define C_036900_PERFCOUNTER_SELECT1 0xFFF003FF
+#define S_036900_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036900_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036900_CNTR_MODE 0xFF0FFFFF
+#define R_036904_SX_PERFCOUNTER1_SELECT 0x036904
+#define R_036908_SX_PERFCOUNTER2_SELECT 0x036908
+#define R_03690C_SX_PERFCOUNTER3_SELECT 0x03690C
+#define R_036910_SX_PERFCOUNTER0_SELECT1 0x036910
+#define S_036910_PERFCOUNTER_SELECT2(x) (((x) & 0x3FF) << 0)
+#define G_036910_PERFCOUNTER_SELECT2(x) (((x) >> 0) & 0x3FF)
+#define C_036910_PERFCOUNTER_SELECT2 0xFFFFFC00
+#define S_036910_PERFCOUNTER_SELECT3(x) (((x) & 0x3FF) << 10)
+#define G_036910_PERFCOUNTER_SELECT3(x) (((x) >> 10) & 0x3FF)
+#define C_036910_PERFCOUNTER_SELECT3 0xFFF003FF
+#define R_036914_SX_PERFCOUNTER1_SELECT1 0x036914
+#define R_036A00_GDS_PERFCOUNTER0_SELECT 0x036A00
+#define S_036A00_PERFCOUNTER_SELECT(x) (((x) & 0x3FF) << 0)
+#define G_036A00_PERFCOUNTER_SELECT(x) (((x) >> 0) & 0x3FF)
+#define C_036A00_PERFCOUNTER_SELECT 0xFFFFFC00
+#define S_036A00_PERFCOUNTER_SELECT1(x) (((x) & 0x3FF) << 10)
+#define G_036A00_PERFCOUNTER_SELECT1(x) (((x) >> 10) & 0x3FF)
+#define C_036A00_PERFCOUNTER_SELECT1 0xFFF003FF
+#define S_036A00_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036A00_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036A00_CNTR_MODE 0xFF0FFFFF
+#define R_036A04_GDS_PERFCOUNTER1_SELECT 0x036A04
+#define R_036A08_GDS_PERFCOUNTER2_SELECT 0x036A08
+#define R_036A0C_GDS_PERFCOUNTER3_SELECT 0x036A0C
+#define R_036A10_GDS_PERFCOUNTER0_SELECT1 0x036A10
+#define S_036A10_PERFCOUNTER_SELECT2(x) (((x) & 0x3FF) << 0)
+#define G_036A10_PERFCOUNTER_SELECT2(x) (((x) >> 0) & 0x3FF)
+#define C_036A10_PERFCOUNTER_SELECT2 0xFFFFFC00
+#define S_036A10_PERFCOUNTER_SELECT3(x) (((x) & 0x3FF) << 10)
+#define G_036A10_PERFCOUNTER_SELECT3(x) (((x) >> 10) & 0x3FF)
+#define C_036A10_PERFCOUNTER_SELECT3 0xFFF003FF
+#define R_036B00_TA_PERFCOUNTER0_SELECT 0x036B00
+#define S_036B00_PERF_SEL(x) (((x) & 0xFF) << 0)
+#define G_036B00_PERF_SEL(x) (((x) >> 0) & 0xFF)
+#define C_036B00_PERF_SEL 0xFFFFFF00
+#define S_036B00_PERF_SEL1(x) (((x) & 0xFF) << 10)
+#define G_036B00_PERF_SEL1(x) (((x) >> 10) & 0xFF)
+#define C_036B00_PERF_SEL1 0xFFFC03FF
+#define S_036B00_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036B00_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036B00_CNTR_MODE 0xFF0FFFFF
+#define S_036B00_PERF_MODE1(x) (((x) & 0x0F) << 24)
+#define G_036B00_PERF_MODE1(x) (((x) >> 24) & 0x0F)
+#define C_036B00_PERF_MODE1 0xF0FFFFFF
+#define S_036B00_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_036B00_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_036B00_PERF_MODE 0x0FFFFFFF
+#define R_036B04_TA_PERFCOUNTER0_SELECT1 0x036B04
+#define S_036B04_PERF_SEL2(x) (((x) & 0xFF) << 0)
+#define G_036B04_PERF_SEL2(x) (((x) >> 0) & 0xFF)
+#define C_036B04_PERF_SEL2 0xFFFFFF00
+#define S_036B04_PERF_SEL3(x) (((x) & 0xFF) << 10)
+#define G_036B04_PERF_SEL3(x) (((x) >> 10) & 0xFF)
+#define C_036B04_PERF_SEL3 0xFFFC03FF
+#define S_036B04_PERF_MODE3(x) (((x) & 0x0F) << 24)
+#define G_036B04_PERF_MODE3(x) (((x) >> 24) & 0x0F)
+#define C_036B04_PERF_MODE3 0xF0FFFFFF
+#define S_036B04_PERF_MODE2(x) (((x) & 0x0F) << 28)
+#define G_036B04_PERF_MODE2(x) (((x) >> 28) & 0x0F)
+#define C_036B04_PERF_MODE2 0x0FFFFFFF
+#define R_036B08_TA_PERFCOUNTER1_SELECT 0x036B08
+#define R_036C00_TD_PERFCOUNTER0_SELECT 0x036C00
+#define S_036C00_PERF_SEL(x) (((x) & 0xFF) << 0)
+#define G_036C00_PERF_SEL(x) (((x) >> 0) & 0xFF)
+#define C_036C00_PERF_SEL 0xFFFFFF00
+#define S_036C00_PERF_SEL1(x) (((x) & 0xFF) << 10)
+#define G_036C00_PERF_SEL1(x) (((x) >> 10) & 0xFF)
+#define C_036C00_PERF_SEL1 0xFFFC03FF
+#define S_036C00_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036C00_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036C00_CNTR_MODE 0xFF0FFFFF
+#define S_036C00_PERF_MODE1(x) (((x) & 0x0F) << 24)
+#define G_036C00_PERF_MODE1(x) (((x) >> 24) & 0x0F)
+#define C_036C00_PERF_MODE1 0xF0FFFFFF
+#define S_036C00_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_036C00_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_036C00_PERF_MODE 0x0FFFFFFF
+#define R_036C04_TD_PERFCOUNTER0_SELECT1 0x036C04
+#define S_036C04_PERF_SEL2(x) (((x) & 0xFF) << 0)
+#define G_036C04_PERF_SEL2(x) (((x) >> 0) & 0xFF)
+#define C_036C04_PERF_SEL2 0xFFFFFF00
+#define S_036C04_PERF_SEL3(x) (((x) & 0xFF) << 10)
+#define G_036C04_PERF_SEL3(x) (((x) >> 10) & 0xFF)
+#define C_036C04_PERF_SEL3 0xFFFC03FF
+#define S_036C04_PERF_MODE3(x) (((x) & 0x0F) << 24)
+#define G_036C04_PERF_MODE3(x) (((x) >> 24) & 0x0F)
+#define C_036C04_PERF_MODE3 0xF0FFFFFF
+#define S_036C04_PERF_MODE2(x) (((x) & 0x0F) << 28)
+#define G_036C04_PERF_MODE2(x) (((x) >> 28) & 0x0F)
+#define C_036C04_PERF_MODE2 0x0FFFFFFF
+#define R_036C08_TD_PERFCOUNTER1_SELECT 0x036C08
+#define R_036D00_TCP_PERFCOUNTER0_SELECT 0x036D00
+#define S_036D00_PERF_SEL(x) (((x) & 0x3FF) << 0)
+#define G_036D00_PERF_SEL(x) (((x) >> 0) & 0x3FF)
+#define C_036D00_PERF_SEL 0xFFFFFC00
+#define S_036D00_PERF_SEL1(x) (((x) & 0x3FF) << 10)
+#define G_036D00_PERF_SEL1(x) (((x) >> 10) & 0x3FF)
+#define C_036D00_PERF_SEL1 0xFFF003FF
+#define S_036D00_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036D00_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036D00_CNTR_MODE 0xFF0FFFFF
+#define S_036D00_PERF_MODE1(x) (((x) & 0x0F) << 24)
+#define G_036D00_PERF_MODE1(x) (((x) >> 24) & 0x0F)
+#define C_036D00_PERF_MODE1 0xF0FFFFFF
+#define S_036D00_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_036D00_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_036D00_PERF_MODE 0x0FFFFFFF
+#define R_036D04_TCP_PERFCOUNTER0_SELECT1 0x036D04
+#define S_036D04_PERF_SEL2(x) (((x) & 0x3FF) << 0)
+#define G_036D04_PERF_SEL2(x) (((x) >> 0) & 0x3FF)
+#define C_036D04_PERF_SEL2 0xFFFFFC00
+#define S_036D04_PERF_SEL3(x) (((x) & 0x3FF) << 10)
+#define G_036D04_PERF_SEL3(x) (((x) >> 10) & 0x3FF)
+#define C_036D04_PERF_SEL3 0xFFF003FF
+#define S_036D04_PERF_MODE3(x) (((x) & 0x0F) << 24)
+#define G_036D04_PERF_MODE3(x) (((x) >> 24) & 0x0F)
+#define C_036D04_PERF_MODE3 0xF0FFFFFF
+#define S_036D04_PERF_MODE2(x) (((x) & 0x0F) << 28)
+#define G_036D04_PERF_MODE2(x) (((x) >> 28) & 0x0F)
+#define C_036D04_PERF_MODE2 0x0FFFFFFF
+#define R_036D08_TCP_PERFCOUNTER1_SELECT 0x036D08
+#define R_036D0C_TCP_PERFCOUNTER1_SELECT1 0x036D0C
+#define R_036D10_TCP_PERFCOUNTER2_SELECT 0x036D10
+#define R_036D14_TCP_PERFCOUNTER3_SELECT 0x036D14
+#define R_036E00_TCC_PERFCOUNTER0_SELECT 0x036E00
+#define S_036E00_PERF_SEL(x) (((x) & 0x3FF) << 0)
+#define G_036E00_PERF_SEL(x) (((x) >> 0) & 0x3FF)
+#define C_036E00_PERF_SEL 0xFFFFFC00
+#define S_036E00_PERF_SEL1(x) (((x) & 0x3FF) << 10)
+#define G_036E00_PERF_SEL1(x) (((x) >> 10) & 0x3FF)
+#define C_036E00_PERF_SEL1 0xFFF003FF
+#define S_036E00_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036E00_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036E00_CNTR_MODE 0xFF0FFFFF
+#define S_036E00_PERF_MODE1(x) (((x) & 0x0F) << 24)
+#define G_036E00_PERF_MODE1(x) (((x) >> 24) & 0x0F)
+#define C_036E00_PERF_MODE1 0xF0FFFFFF
+#define S_036E00_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_036E00_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_036E00_PERF_MODE 0x0FFFFFFF
+#define R_036E04_TCC_PERFCOUNTER0_SELECT1 0x036E04
+#define S_036E04_PERF_SEL2(x) (((x) & 0x3FF) << 0)
+#define G_036E04_PERF_SEL2(x) (((x) >> 0) & 0x3FF)
+#define C_036E04_PERF_SEL2 0xFFFFFC00
+#define S_036E04_PERF_SEL3(x) (((x) & 0x3FF) << 10)
+#define G_036E04_PERF_SEL3(x) (((x) >> 10) & 0x3FF)
+#define C_036E04_PERF_SEL3 0xFFF003FF
+#define S_036E04_PERF_MODE2(x) (((x) & 0x0F) << 24)
+#define G_036E04_PERF_MODE2(x) (((x) >> 24) & 0x0F)
+#define C_036E04_PERF_MODE2 0xF0FFFFFF
+#define S_036E04_PERF_MODE3(x) (((x) & 0x0F) << 28)
+#define G_036E04_PERF_MODE3(x) (((x) >> 28) & 0x0F)
+#define C_036E04_PERF_MODE3 0x0FFFFFFF
+#define R_036E08_TCC_PERFCOUNTER1_SELECT 0x036E08
+#define R_036E0C_TCC_PERFCOUNTER1_SELECT1 0x036E0C
+#define R_036E10_TCC_PERFCOUNTER2_SELECT 0x036E10
+#define R_036E14_TCC_PERFCOUNTER3_SELECT 0x036E14
+#define R_036E40_TCA_PERFCOUNTER0_SELECT 0x036E40
+#define S_036E40_PERF_SEL(x) (((x) & 0x3FF) << 0)
+#define G_036E40_PERF_SEL(x) (((x) >> 0) & 0x3FF)
+#define C_036E40_PERF_SEL 0xFFFFFC00
+#define S_036E40_PERF_SEL1(x) (((x) & 0x3FF) << 10)
+#define G_036E40_PERF_SEL1(x) (((x) >> 10) & 0x3FF)
+#define C_036E40_PERF_SEL1 0xFFF003FF
+#define S_036E40_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_036E40_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_036E40_CNTR_MODE 0xFF0FFFFF
+#define S_036E40_PERF_MODE1(x) (((x) & 0x0F) << 24)
+#define G_036E40_PERF_MODE1(x) (((x) >> 24) & 0x0F)
+#define C_036E40_PERF_MODE1 0xF0FFFFFF
+#define S_036E40_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_036E40_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_036E40_PERF_MODE 0x0FFFFFFF
+#define R_036E44_TCA_PERFCOUNTER0_SELECT1 0x036E44
+#define S_036E44_PERF_SEL2(x) (((x) & 0x3FF) << 0)
+#define G_036E44_PERF_SEL2(x) (((x) >> 0) & 0x3FF)
+#define C_036E44_PERF_SEL2 0xFFFFFC00
+#define S_036E44_PERF_SEL3(x) (((x) & 0x3FF) << 10)
+#define G_036E44_PERF_SEL3(x) (((x) >> 10) & 0x3FF)
+#define C_036E44_PERF_SEL3 0xFFF003FF
+#define S_036E44_PERF_MODE2(x) (((x) & 0x0F) << 24)
+#define G_036E44_PERF_MODE2(x) (((x) >> 24) & 0x0F)
+#define C_036E44_PERF_MODE2 0xF0FFFFFF
+#define S_036E44_PERF_MODE3(x) (((x) & 0x0F) << 28)
+#define G_036E44_PERF_MODE3(x) (((x) >> 28) & 0x0F)
+#define C_036E44_PERF_MODE3 0x0FFFFFFF
+#define R_036E48_TCA_PERFCOUNTER1_SELECT 0x036E48
+#define R_036E4C_TCA_PERFCOUNTER1_SELECT1 0x036E4C
+#define R_036E50_TCA_PERFCOUNTER2_SELECT 0x036E50
+#define R_036E54_TCA_PERFCOUNTER3_SELECT 0x036E54
+#define R_037000_CB_PERFCOUNTER_FILTER 0x037000
+#define S_037000_OP_FILTER_ENABLE(x) (((x) & 0x1) << 0)
+#define G_037000_OP_FILTER_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_037000_OP_FILTER_ENABLE 0xFFFFFFFE
+#define S_037000_OP_FILTER_SEL(x) (((x) & 0x07) << 1)
+#define G_037000_OP_FILTER_SEL(x) (((x) >> 1) & 0x07)
+#define C_037000_OP_FILTER_SEL 0xFFFFFFF1
+#define S_037000_FORMAT_FILTER_ENABLE(x) (((x) & 0x1) << 4)
+#define G_037000_FORMAT_FILTER_ENABLE(x) (((x) >> 4) & 0x1)
+#define C_037000_FORMAT_FILTER_ENABLE 0xFFFFFFEF
+#define S_037000_FORMAT_FILTER_SEL(x) (((x) & 0x1F) << 5)
+#define G_037000_FORMAT_FILTER_SEL(x) (((x) >> 5) & 0x1F)
+#define C_037000_FORMAT_FILTER_SEL 0xFFFFFC1F
+#define S_037000_CLEAR_FILTER_ENABLE(x) (((x) & 0x1) << 10)
+#define G_037000_CLEAR_FILTER_ENABLE(x) (((x) >> 10) & 0x1)
+#define C_037000_CLEAR_FILTER_ENABLE 0xFFFFFBFF
+#define S_037000_CLEAR_FILTER_SEL(x) (((x) & 0x1) << 11)
+#define G_037000_CLEAR_FILTER_SEL(x) (((x) >> 11) & 0x1)
+#define C_037000_CLEAR_FILTER_SEL 0xFFFFF7FF
+#define S_037000_MRT_FILTER_ENABLE(x) (((x) & 0x1) << 12)
+#define G_037000_MRT_FILTER_ENABLE(x) (((x) >> 12) & 0x1)
+#define C_037000_MRT_FILTER_ENABLE 0xFFFFEFFF
+#define S_037000_MRT_FILTER_SEL(x) (((x) & 0x07) << 13)
+#define G_037000_MRT_FILTER_SEL(x) (((x) >> 13) & 0x07)
+#define C_037000_MRT_FILTER_SEL 0xFFFF1FFF
+#define S_037000_NUM_SAMPLES_FILTER_ENABLE(x) (((x) & 0x1) << 17)
+#define G_037000_NUM_SAMPLES_FILTER_ENABLE(x) (((x) >> 17) & 0x1)
+#define C_037000_NUM_SAMPLES_FILTER_ENABLE 0xFFFDFFFF
+#define S_037000_NUM_SAMPLES_FILTER_SEL(x) (((x) & 0x07) << 18)
+#define G_037000_NUM_SAMPLES_FILTER_SEL(x) (((x) >> 18) & 0x07)
+#define C_037000_NUM_SAMPLES_FILTER_SEL 0xFFE3FFFF
+#define S_037000_NUM_FRAGMENTS_FILTER_ENABLE(x) (((x) & 0x1) << 21)
+#define G_037000_NUM_FRAGMENTS_FILTER_ENABLE(x) (((x) >> 21) & 0x1)
+#define C_037000_NUM_FRAGMENTS_FILTER_ENABLE 0xFFDFFFFF
+#define S_037000_NUM_FRAGMENTS_FILTER_SEL(x) (((x) & 0x03) << 22)
+#define G_037000_NUM_FRAGMENTS_FILTER_SEL(x) (((x) >> 22) & 0x03)
+#define C_037000_NUM_FRAGMENTS_FILTER_SEL 0xFF3FFFFF
+#define R_037004_CB_PERFCOUNTER0_SELECT 0x037004
+#define S_037004_PERF_SEL(x) (((x) & 0x1FF) << 0)
+#define G_037004_PERF_SEL(x) (((x) >> 0) & 0x1FF)
+#define C_037004_PERF_SEL 0xFFFFFE00
+#define S_037004_PERF_SEL1(x) (((x) & 0x1FF) << 10)
+#define G_037004_PERF_SEL1(x) (((x) >> 10) & 0x1FF)
+#define C_037004_PERF_SEL1 0xFFF803FF
+#define S_037004_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_037004_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_037004_CNTR_MODE 0xFF0FFFFF
+#define S_037004_PERF_MODE1(x) (((x) & 0x0F) << 24)
+#define G_037004_PERF_MODE1(x) (((x) >> 24) & 0x0F)
+#define C_037004_PERF_MODE1 0xF0FFFFFF
+#define S_037004_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_037004_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_037004_PERF_MODE 0x0FFFFFFF
+#define R_037008_CB_PERFCOUNTER0_SELECT1 0x037008
+#define S_037008_PERF_SEL2(x) (((x) & 0x1FF) << 0)
+#define G_037008_PERF_SEL2(x) (((x) >> 0) & 0x1FF)
+#define C_037008_PERF_SEL2 0xFFFFFE00
+#define S_037008_PERF_SEL3(x) (((x) & 0x1FF) << 10)
+#define G_037008_PERF_SEL3(x) (((x) >> 10) & 0x1FF)
+#define C_037008_PERF_SEL3 0xFFF803FF
+#define S_037008_PERF_MODE3(x) (((x) & 0x0F) << 24)
+#define G_037008_PERF_MODE3(x) (((x) >> 24) & 0x0F)
+#define C_037008_PERF_MODE3 0xF0FFFFFF
+#define S_037008_PERF_MODE2(x) (((x) & 0x0F) << 28)
+#define G_037008_PERF_MODE2(x) (((x) >> 28) & 0x0F)
+#define C_037008_PERF_MODE2 0x0FFFFFFF
+#define R_03700C_CB_PERFCOUNTER1_SELECT 0x03700C
+#define R_037010_CB_PERFCOUNTER2_SELECT 0x037010
+#define R_037014_CB_PERFCOUNTER3_SELECT 0x037014
+#define R_037100_DB_PERFCOUNTER0_SELECT 0x037100
+#define S_037100_PERF_SEL(x) (((x) & 0x3FF) << 0)
+#define G_037100_PERF_SEL(x) (((x) >> 0) & 0x3FF)
+#define C_037100_PERF_SEL 0xFFFFFC00
+#define S_037100_PERF_SEL1(x) (((x) & 0x3FF) << 10)
+#define G_037100_PERF_SEL1(x) (((x) >> 10) & 0x3FF)
+#define C_037100_PERF_SEL1 0xFFF003FF
+#define S_037100_CNTR_MODE(x) (((x) & 0x0F) << 20)
+#define G_037100_CNTR_MODE(x) (((x) >> 20) & 0x0F)
+#define C_037100_CNTR_MODE 0xFF0FFFFF
+#define S_037100_PERF_MODE1(x) (((x) & 0x0F) << 24)
+#define G_037100_PERF_MODE1(x) (((x) >> 24) & 0x0F)
+#define C_037100_PERF_MODE1 0xF0FFFFFF
+#define S_037100_PERF_MODE(x) (((x) & 0x0F) << 28)
+#define G_037100_PERF_MODE(x) (((x) >> 28) & 0x0F)
+#define C_037100_PERF_MODE 0x0FFFFFFF
+#define R_037104_DB_PERFCOUNTER0_SELECT1 0x037104
+#define S_037104_PERF_SEL2(x) (((x) & 0x3FF) << 0)
+#define G_037104_PERF_SEL2(x) (((x) >> 0) & 0x3FF)
+#define C_037104_PERF_SEL2 0xFFFFFC00
+#define S_037104_PERF_SEL3(x) (((x) & 0x3FF) << 10)
+#define G_037104_PERF_SEL3(x) (((x) >> 10) & 0x3FF)
+#define C_037104_PERF_SEL3 0xFFF003FF
+#define S_037104_PERF_MODE3(x) (((x) & 0x0F) << 24)
+#define G_037104_PERF_MODE3(x) (((x) >> 24) & 0x0F)
+#define C_037104_PERF_MODE3 0xF0FFFFFF
+#define S_037104_PERF_MODE2(x) (((x) & 0x0F) << 28)
+#define G_037104_PERF_MODE2(x) (((x) >> 28) & 0x0F)
+#define C_037104_PERF_MODE2 0x0FFFFFFF
+#define R_037108_DB_PERFCOUNTER1_SELECT 0x037108
+#define R_03710C_DB_PERFCOUNTER1_SELECT1 0x03710C
+#define R_037110_DB_PERFCOUNTER2_SELECT 0x037110
+#define R_037118_DB_PERFCOUNTER3_SELECT 0x037118
#define R_028000_DB_RENDER_CONTROL 0x028000
#define S_028000_DEPTH_CLEAR_ENABLE(x) (((x) & 0x1) << 0)
#define G_028000_DEPTH_CLEAR_ENABLE(x) (((x) >> 0) & 0x1)
diff --git a/src/gallium/drivers/rbug/rbug_objects.c b/src/gallium/drivers/rbug/rbug_objects.c
index 25d55a383c2..2aa4e123f87 100644
--- a/src/gallium/drivers/rbug/rbug_objects.c
+++ b/src/gallium/drivers/rbug/rbug_objects.c
@@ -43,13 +43,13 @@ rbug_resource_create(struct rbug_screen *rb_screen,
{
struct rbug_resource *rb_resource;
- if(!resource)
+ if (!resource)
goto error;
assert(resource->screen == rb_screen->screen);
rb_resource = CALLOC_STRUCT(rbug_resource);
- if(!rb_resource)
+ if (!rb_resource)
goto error;
memcpy(&rb_resource->base, resource, sizeof(struct pipe_resource));
@@ -88,13 +88,13 @@ rbug_surface_create(struct rbug_context *rb_context,
{
struct rbug_surface *rb_surface;
- if(!surface)
+ if (!surface)
goto error;
assert(surface->texture == rb_resource->resource);
rb_surface = CALLOC_STRUCT(rbug_surface);
- if(!rb_surface)
+ if (!rb_surface)
goto error;
memcpy(&rb_surface->base, surface, sizeof(struct pipe_surface));
@@ -165,13 +165,13 @@ rbug_transfer_create(struct rbug_context *rb_context,
{
struct rbug_transfer *rb_transfer;
- if(!transfer)
+ if (!transfer)
goto error;
assert(transfer->resource == rb_resource->resource);
rb_transfer = CALLOC_STRUCT(rbug_transfer);
- if(!rb_transfer)
+ if (!rb_transfer)
goto error;
memcpy(&rb_transfer->base, transfer, sizeof(struct pipe_transfer));
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index bb4cef29ec9..2ae72b2332b 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -362,7 +362,8 @@ softpipe_is_format_supported( struct pipe_screen *screen,
return FALSE;
}
- if (format_desc->layout == UTIL_FORMAT_LAYOUT_BPTC) {
+ if (format_desc->layout == UTIL_FORMAT_LAYOUT_BPTC ||
+ format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC) {
/* Software decoding is not hooked up. */
return FALSE;
}
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index ff3cb9fe5e1..973803e909d 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -840,7 +840,7 @@ sp_setup_tri(struct setup_context *setup,
setup->span.right[1] = 0;
/* setup->span.z_mode = tri_z_mode( setup->ctx ); */
if (setup->softpipe->layer_slot > 0) {
- layer = *(unsigned *)v1[setup->softpipe->layer_slot];
+ layer = *(unsigned *)setup->vprovoke[setup->softpipe->layer_slot];
layer = MIN2(layer, setup->max_layer);
}
setup->quad[0].input.layer = layer;
@@ -1127,7 +1127,7 @@ sp_setup_line(struct setup_context *setup,
setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1;
setup->quad[0].inout.mask = 0x0;
if (setup->softpipe->layer_slot > 0) {
- layer = *(unsigned *)v1[setup->softpipe->layer_slot];
+ layer = *(unsigned *)setup->vprovoke[setup->softpipe->layer_slot];
layer = MIN2(layer, setup->max_layer);
}
setup->quad[0].input.layer = layer;
diff --git a/src/gallium/drivers/softpipe/sp_state_shader.c b/src/gallium/drivers/softpipe/sp_state_shader.c
index 8ab2903dced..dce0404de5b 100644
--- a/src/gallium/drivers/softpipe/sp_state_shader.c
+++ b/src/gallium/drivers/softpipe/sp_state_shader.c
@@ -207,7 +207,7 @@ softpipe_create_vs_state(struct pipe_context *pipe,
struct sp_vertex_shader *state;
state = CALLOC_STRUCT(sp_vertex_shader);
- if (state == NULL )
+ if (!state)
goto fail;
/* copy shader tokens, the ones passed in will go away.
@@ -269,7 +269,7 @@ softpipe_create_gs_state(struct pipe_context *pipe,
struct sp_geometry_shader *state;
state = CALLOC_STRUCT(sp_geometry_shader);
- if (state == NULL )
+ if (!state)
goto fail;
state->shader = *templ;
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 3347f5f1883..52df89504b8 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -435,7 +435,7 @@ softpipe_transfer_map(struct pipe_context *pipe,
map = spr->data;
}
- if (map == NULL) {
+ if (!map) {
pipe_resource_reference(&pt->resource, NULL);
FREE(spt);
return NULL;
diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c
index 0e1e332d6cb..10442cb46e7 100644
--- a/src/gallium/drivers/svga/svga_cmd.c
+++ b/src/gallium/drivers/svga/svga_cmd.c
@@ -1386,7 +1386,7 @@ SVGA3D_BeginGBQuery(struct svga_winsys_context *swc,
SVGA_3D_CMD_BEGIN_GB_QUERY,
sizeof *cmd,
1);
- if(!cmd)
+ if (!cmd)
return PIPE_ERROR_OUT_OF_MEMORY;
cmd->cid = swc->cid;
@@ -1466,7 +1466,7 @@ SVGA3D_EndGBQuery(struct svga_winsys_context *swc,
SVGA_3D_CMD_END_GB_QUERY,
sizeof *cmd,
2);
- if(!cmd)
+ if (!cmd)
return PIPE_ERROR_OUT_OF_MEMORY;
cmd->cid = swc->cid;
@@ -1553,7 +1553,7 @@ SVGA3D_WaitForGBQuery(struct svga_winsys_context *swc,
SVGA_3D_CMD_WAIT_FOR_GB_QUERY,
sizeof *cmd,
2);
- if(!cmd)
+ if (!cmd)
return PIPE_ERROR_OUT_OF_MEMORY;
cmd->cid = swc->cid;
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index f8622b96f45..d407785ddd9 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -134,7 +134,7 @@ struct pipe_context *svga_context_create(struct pipe_screen *screen,
enum pipe_error ret;
svga = CALLOC_STRUCT(svga_context);
- if (svga == NULL)
+ if (!svga)
goto cleanup;
LIST_INITHEAD(&svga->dirty_buffers);
@@ -340,7 +340,7 @@ void svga_context_flush( struct svga_context *svga,
PIPE_TIMEOUT_INFINITE);
}
- if(pfence)
+ if (pfence)
svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence);
svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 6a4f9d8d076..c4284cc3e5b 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -392,6 +392,9 @@ struct svga_context
boolean no_line_width;
boolean force_hw_line_stipple;
+
+ /** To report perf/conformance/etc issues to the state tracker */
+ struct pipe_debug_callback callback;
} debug;
struct {
diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c
index 9b6451da2f9..cca499a65c7 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -48,7 +48,7 @@ struct svga_hwtnl *
svga_hwtnl_create(struct svga_context *svga)
{
struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl);
- if (hwtnl == NULL)
+ if (!hwtnl)
goto fail;
hwtnl->svga = svga;
@@ -189,7 +189,7 @@ draw_vgpu9(struct svga_hwtnl *hwtnl)
for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
handle = svga_buffer_handle(svga, hwtnl->cmd.vbufs[j].buffer);
- if (handle == NULL)
+ if (!handle)
return PIPE_ERROR_OUT_OF_MEMORY;
vb_handle[i] = handle;
@@ -198,7 +198,7 @@ draw_vgpu9(struct svga_hwtnl *hwtnl)
for (i = 0; i < hwtnl->cmd.prim_count; i++) {
if (hwtnl->cmd.prim_ib[i]) {
handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]);
- if (handle == NULL)
+ if (!handle)
return PIPE_ERROR_OUT_OF_MEMORY;
}
else
@@ -491,7 +491,7 @@ draw_vgpu10(struct svga_hwtnl *hwtnl,
(void) sbuf; /* silence unused var warning */
ib_handle = svga_buffer_handle(svga, ib);
- if (ib_handle == NULL)
+ if (!ib_handle)
return PIPE_ERROR_OUT_OF_MEMORY;
}
else {
diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c
index acb2e95e747..7d82930677b 100644
--- a/src/gallium/drivers/svga/svga_draw_arrays.c
+++ b/src/gallium/drivers/svga/svga_draw_arrays.c
@@ -26,6 +26,7 @@
#include "svga_cmd.h"
#include "util/u_inlines.h"
+#include "util/u_prim.h"
#include "indices/u_indices.h"
#include "svga_hw_reg.h"
@@ -52,11 +53,11 @@ generate_indices(struct svga_hwtnl *hwtnl,
dst = pipe_buffer_create(pipe->screen, PIPE_BIND_INDEX_BUFFER,
PIPE_USAGE_IMMUTABLE, size);
- if (dst == NULL)
+ if (!dst)
goto fail;
dst_map = pipe_buffer_map(pipe, dst, PIPE_TRANSFER_WRITE, &transfer);
- if (dst_map == NULL)
+ if (!dst_map)
goto fail;
generate(0, nr, dst_map);
@@ -277,6 +278,10 @@ svga_hwtnl_draw_arrays(struct svga_hwtnl *hwtnl,
if (ret != PIPE_OK)
goto done;
+ pipe_debug_message(&svga->debug.callback, PERF_INFO,
+ "generating temporary index buffer for drawing %s",
+ u_prim_name(prim));
+
ret = svga_hwtnl_simple_draw_range_elements(hwtnl,
gen_buf,
gen_size,
diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c
index 0213409ef29..74bfebda18f 100644
--- a/src/gallium/drivers/svga/svga_draw_elements.c
+++ b/src/gallium/drivers/svga/svga_draw_elements.c
@@ -60,15 +60,15 @@ translate_indices(struct svga_hwtnl *hwtnl, struct pipe_resource *src,
dst = pipe_buffer_create(pipe->screen,
PIPE_BIND_INDEX_BUFFER, PIPE_USAGE_DEFAULT, size);
- if (dst == NULL)
+ if (!dst)
goto fail;
src_map = pipe_buffer_map(pipe, src, PIPE_TRANSFER_READ, &src_transfer);
- if (src_map == NULL)
+ if (!src_map)
goto fail;
dst_map = pipe_buffer_map(pipe, dst, PIPE_TRANSFER_WRITE, &dst_transfer);
- if (dst_map == NULL)
+ if (!dst_map)
goto fail;
translate((const char *) src_map + offset, 0, 0, nr, 0, dst_map);
diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c
index 0c9d6129b53..0af80cd4296 100644
--- a/src/gallium/drivers/svga/svga_pipe_blend.c
+++ b/src/gallium/drivers/svga/svga_pipe_blend.c
@@ -243,6 +243,15 @@ svga_create_blend_state(struct pipe_context *pipe,
blend->rt[i].srcblend_alpha = blend->rt[i].srcblend;
blend->rt[i].dstblend_alpha = blend->rt[i].dstblend;
blend->rt[i].blendeq_alpha = blend->rt[i].blendeq;
+
+ if (templ->logicop_func == PIPE_LOGICOP_XOR) {
+ pipe_debug_message(&svga->debug.callback, CONFORMANCE,
+ "XOR logicop mode has limited support");
+ }
+ else if (templ->logicop_func != PIPE_LOGICOP_COPY) {
+ pipe_debug_message(&svga->debug.callback, CONFORMANCE,
+ "general logicops are not supported");
+ }
}
else {
/* Note: the vgpu10 device does not yet support independent
diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c
index bab61780610..c874726b6da 100644
--- a/src/gallium/drivers/svga/svga_pipe_clear.c
+++ b/src/gallium/drivers/svga/svga_pipe_clear.c
@@ -178,7 +178,7 @@ try_clear(struct svga_context *svga,
rtv = svga_validate_surface_view(svga,
svga_surface(fb->cbufs[i]));
- if (rtv == NULL)
+ if (!rtv)
return PIPE_ERROR_OUT_OF_MEMORY;
ret = SVGA3D_vgpu10_ClearRenderTargetView(svga->swc,
@@ -191,7 +191,7 @@ try_clear(struct svga_context *svga,
if (flags & (SVGA3D_CLEAR_DEPTH | SVGA3D_CLEAR_STENCIL)) {
struct pipe_surface *dsv =
svga_validate_surface_view(svga, svga_surface(fb->zsbuf));
- if (dsv == NULL)
+ if (!dsv)
return PIPE_ERROR_OUT_OF_MEMORY;
ret = SVGA3D_vgpu10_ClearDepthStencilView(svga->swc, dsv, flags,
diff --git a/src/gallium/drivers/svga/svga_pipe_misc.c b/src/gallium/drivers/svga/svga_pipe_misc.c
index c8020da7c7a..af9356d7c75 100644
--- a/src/gallium/drivers/svga/svga_pipe_misc.c
+++ b/src/gallium/drivers/svga/svga_pipe_misc.c
@@ -244,6 +244,22 @@ static void svga_set_viewport_states( struct pipe_context *pipe,
}
+/**
+ * Called by state tracker to specify a callback function the driver
+ * can use to report info back to the state tracker.
+ */
+static void
+svga_set_debug_callback(struct pipe_context *pipe,
+ const struct pipe_debug_callback *cb)
+{
+ struct svga_context *svga = svga_context(pipe);
+
+ if (cb)
+ svga->debug.callback = *cb;
+ else
+ memset(&svga->debug.callback, 0, sizeof(svga->debug.callback));
+}
+
void svga_init_misc_functions( struct svga_context *svga )
{
@@ -252,6 +268,7 @@ void svga_init_misc_functions( struct svga_context *svga )
svga->pipe.set_framebuffer_state = svga_set_framebuffer_state;
svga->pipe.set_clip_state = svga_set_clip_state;
svga->pipe.set_viewport_states = svga_set_viewport_states;
+ svga->pipe.set_debug_callback = svga_set_debug_callback;
}
diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c
index 5416a009dcb..b67d56c4ccf 100644
--- a/src/gallium/drivers/svga/svga_pipe_query.c
+++ b/src/gallium/drivers/svga/svga_pipe_query.c
@@ -348,7 +348,7 @@ allocate_query_block_entry(struct svga_context *svga,
if (block_index == -1)
return NULL;
alloc_entry = CALLOC_STRUCT(svga_qmem_alloc_entry);
- if (alloc_entry == NULL)
+ if (!alloc_entry)
return NULL;
alloc_entry->block_index = block_index;
@@ -381,13 +381,13 @@ allocate_query(struct svga_context *svga,
alloc_entry = svga->gb_query_map[type];
- if (alloc_entry == NULL) {
+ if (!alloc_entry) {
/**
* No query memory block has been allocated for this query type,
* allocate one now
*/
alloc_entry = allocate_query_block_entry(svga, len);
- if (alloc_entry == NULL)
+ if (!alloc_entry)
return -1;
svga->gb_query_map[type] = alloc_entry;
}
@@ -398,7 +398,7 @@ allocate_query(struct svga_context *svga,
if (slot_index == -1) {
/* This query memory block is full, allocate another one */
alloc_entry = allocate_query_block_entry(svga, len);
- if (alloc_entry == NULL)
+ if (!alloc_entry)
return -1;
alloc_entry->next = svga->gb_query_map[type];
svga->gb_query_map[type] = alloc_entry;
@@ -753,8 +753,9 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
struct svga_query *sq;
- if (q == NULL) {
- return destroy_gb_query_obj(svga);
+ if (!q) {
+ destroy_gb_query_obj(svga);
+ return;
}
sq = svga_query(q);
diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
index 6310b7a5e86..fa1744fc33e 100644
--- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c
+++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
@@ -352,6 +352,11 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
define_rasterizer_object(svga, rast);
}
+ if (templ->poly_smooth) {
+ pipe_debug_message(&svga->debug.callback, CONFORMANCE,
+ "GL_POLYGON_SMOOTH not supported");
+ }
+
svga->hud.num_state_objects++;
return rast;
diff --git a/src/gallium/drivers/svga/svga_pipe_streamout.c b/src/gallium/drivers/svga/svga_pipe_streamout.c
index 1da63204428..3f443c44eee 100644
--- a/src/gallium/drivers/svga/svga_pipe_streamout.c
+++ b/src/gallium/drivers/svga/svga_pipe_streamout.c
@@ -75,7 +75,7 @@ svga_create_stream_output(struct svga_context *svga,
/* Allocate the streamout data structure */
streamout = CALLOC_STRUCT(svga_stream_output);
- if (streamout == NULL)
+ if (!streamout)
return NULL;
streamout->info = *info;
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c
index 449cc149a81..a8ffcc7f680 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -86,7 +86,7 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
assert(box->depth == 1);
transfer = CALLOC_STRUCT(pipe_transfer);
- if (transfer == NULL) {
+ if (!transfer) {
return NULL;
}
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
index 81594777258..4c7aeff92e8 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -506,7 +506,7 @@ svga_texture_transfer_map(struct pipe_context *pipe,
/*
* Make sure we return NULL if the map fails
*/
- if (map == NULL) {
+ if (!map) {
FREE(st);
return map;
}
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 09a3d33552b..fca501bc47d 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -780,26 +780,39 @@ svga_get_driver_query_info(struct pipe_screen *screen,
unsigned index,
struct pipe_driver_query_info *info)
{
+#define QUERY(NAME, ENUM, UNITS) \
+ {NAME, ENUM, {0}, UNITS, PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE, 0, 0x0}
+
static const struct pipe_driver_query_info queries[] = {
/* per-frame counters */
- {"num-draw-calls", SVGA_QUERY_NUM_DRAW_CALLS, {0}},
- {"num-fallbacks", SVGA_QUERY_NUM_FALLBACKS, {0}},
- {"num-flushes", SVGA_QUERY_NUM_FLUSHES, {0}},
- {"num-validations", SVGA_QUERY_NUM_VALIDATIONS, {0}},
- {"map-buffer-time", SVGA_QUERY_MAP_BUFFER_TIME, {0},
- PIPE_DRIVER_QUERY_TYPE_MICROSECONDS},
- {"num-resources-mapped", SVGA_QUERY_NUM_RESOURCES_MAPPED, {0}},
- {"num-bytes-uploaded", SVGA_QUERY_NUM_BYTES_UPLOADED, {0},
- PIPE_DRIVER_QUERY_TYPE_BYTES, PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE},
+ QUERY("num-draw-calls", SVGA_QUERY_NUM_DRAW_CALLS,
+ PIPE_DRIVER_QUERY_TYPE_UINT64),
+ QUERY("num-fallbacks", SVGA_QUERY_NUM_FALLBACKS,
+ PIPE_DRIVER_QUERY_TYPE_UINT64),
+ QUERY("num-flushes", SVGA_QUERY_NUM_FLUSHES,
+ PIPE_DRIVER_QUERY_TYPE_UINT64),
+ QUERY("num-validations", SVGA_QUERY_NUM_VALIDATIONS,
+ PIPE_DRIVER_QUERY_TYPE_UINT64),
+ QUERY("map-buffer-time", SVGA_QUERY_MAP_BUFFER_TIME,
+ PIPE_DRIVER_QUERY_TYPE_MICROSECONDS),
+ QUERY("num-resources-mapped", SVGA_QUERY_NUM_RESOURCES_MAPPED,
+ PIPE_DRIVER_QUERY_TYPE_UINT64),
+ QUERY("num-bytes-uploaded", SVGA_QUERY_NUM_BYTES_UPLOADED,
+ PIPE_DRIVER_QUERY_TYPE_BYTES),
/* running total counters */
- {"memory-used", SVGA_QUERY_MEMORY_USED, {0},
- PIPE_DRIVER_QUERY_TYPE_BYTES},
- {"num-shaders", SVGA_QUERY_NUM_SHADERS, {0}},
- {"num-resources", SVGA_QUERY_NUM_RESOURCES, {0}},
- {"num-state-objects", SVGA_QUERY_NUM_STATE_OBJECTS, {0}},
- {"num-surface-views", SVGA_QUERY_NUM_SURFACE_VIEWS, {0}},
+ QUERY("memory-used", SVGA_QUERY_MEMORY_USED,
+ PIPE_DRIVER_QUERY_TYPE_BYTES),
+ QUERY("num-shaders", SVGA_QUERY_NUM_SHADERS,
+ PIPE_DRIVER_QUERY_TYPE_UINT64),
+ QUERY("num-resources", SVGA_QUERY_NUM_RESOURCES,
+ PIPE_DRIVER_QUERY_TYPE_UINT64),
+ QUERY("num-state-objects", SVGA_QUERY_NUM_STATE_OBJECTS,
+ PIPE_DRIVER_QUERY_TYPE_UINT64),
+ QUERY("num-surface-views", SVGA_QUERY_NUM_SURFACE_VIEWS,
+ PIPE_DRIVER_QUERY_TYPE_UINT64),
};
+#undef QUERY
if (!info)
return Elements(queries);
diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c
index c93d2a5e565..2cf41134bd6 100644
--- a/src/gallium/drivers/svga/svga_state_constants.c
+++ b/src/gallium/drivers/svga/svga_state_constants.c
@@ -459,7 +459,7 @@ emit_consts_vgpu9(struct svga_context *svga, unsigned shader)
data = (const float (*)[4])
pipe_buffer_map(&svga->pipe, svga->curr.constbufs[shader][0].buffer,
PIPE_TRANSFER_READ, &transfer);
- if (data == NULL) {
+ if (!data) {
return PIPE_ERROR_OUT_OF_MEMORY;
}
@@ -747,7 +747,7 @@ emit_fs_consts(struct svga_context *svga, unsigned dirty)
/* SVGA_NEW_FS_VARIANT
*/
- if (variant == NULL)
+ if (!variant)
return PIPE_OK;
/* SVGA_NEW_FS_CONST_BUFFER
@@ -782,7 +782,7 @@ emit_vs_consts(struct svga_context *svga, unsigned dirty)
/* SVGA_NEW_VS_VARIANT
*/
- if (variant == NULL)
+ if (!variant)
return PIPE_OK;
/* SVGA_NEW_VS_CONST_BUFFER
@@ -816,7 +816,7 @@ emit_gs_consts(struct svga_context *svga, unsigned dirty)
/* SVGA_NEW_GS_VARIANT
*/
- if (variant == NULL)
+ if (!variant)
return PIPE_OK;
/* SVGA_NEW_GS_CONST_BUFFER
diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c
index 9abacc9fa20..4b0400bf80a 100644
--- a/src/gallium/drivers/svga/svga_state_framebuffer.c
+++ b/src/gallium/drivers/svga/svga_state_framebuffer.c
@@ -196,7 +196,7 @@ emit_fb_vgpu10(struct svga_context *svga)
/* Setup depth stencil view */
if (curr->zsbuf) {
dsv = svga_validate_surface_view(svga, svga_surface(curr->zsbuf));
- if (dsv == NULL) {
+ if (!dsv) {
return PIPE_ERROR_OUT_OF_MEMORY;
}
}
diff --git a/src/gallium/drivers/svga/svga_state_gs.c b/src/gallium/drivers/svga/svga_state_gs.c
index 0b336baee86..618bec248dd 100644
--- a/src/gallium/drivers/svga/svga_state_gs.c
+++ b/src/gallium/drivers/svga/svga_state_gs.c
@@ -72,7 +72,7 @@ compile_gs(struct svga_context *svga,
enum pipe_error ret = PIPE_ERROR;
variant = translate_geometry_program(svga, gs, key);
- if (variant == NULL) {
+ if (!variant) {
/* some problem during translation, try the dummy shader */
const struct tgsi_token *dummy = get_dummy_geometry_shader();
if (!dummy) {
@@ -82,7 +82,7 @@ compile_gs(struct svga_context *svga,
FREE((void *) gs->base.tokens);
gs->base.tokens = dummy;
variant = translate_geometry_program(svga, gs, key);
- if (variant == NULL) {
+ if (!variant) {
return PIPE_ERROR;
}
}
@@ -181,7 +181,7 @@ emit_hw_gs(struct svga_context *svga, unsigned dirty)
if (svga->curr.user_gs)
assert(svga->curr.gs);
- if (gs == NULL) {
+ if (!gs) {
if (svga->state.hw_draw.gs != NULL) {
/** The previous geometry shader is made inactive.
diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c
index 429241e64e2..b07c62da405 100644
--- a/src/gallium/drivers/svga/svga_state_need_swtnl.c
+++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c
@@ -62,6 +62,7 @@ update_need_pipeline(struct svga_context *svga, unsigned dirty)
{
boolean need_pipeline = FALSE;
struct svga_vertex_shader *vs = svga->curr.vs;
+ const char *reason = "";
/* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
*/
@@ -76,6 +77,20 @@ update_need_pipeline(struct svga_context *svga, unsigned dirty)
svga->curr.rast->need_pipeline_lines_str,
svga->curr.rast->need_pipeline_points_str);
need_pipeline = TRUE;
+
+ switch (svga->curr.reduced_prim) {
+ case PIPE_PRIM_POINTS:
+ reason = svga->curr.rast->need_pipeline_points_str;
+ break;
+ case PIPE_PRIM_LINES:
+ reason = svga->curr.rast->need_pipeline_lines_str;
+ break;
+ case PIPE_PRIM_TRIANGLES:
+ reason = svga->curr.rast->need_pipeline_tris_str;
+ break;
+ default:
+ assert(!"Unexpected reduced prim type");
+ }
}
/* EDGEFLAGS
@@ -83,6 +98,7 @@ update_need_pipeline(struct svga_context *svga, unsigned dirty)
if (vs && vs->base.info.writes_edgeflag) {
SVGA_DBG(DEBUG_SWTNL, "%s: edgeflags\n", __FUNCTION__);
need_pipeline = TRUE;
+ reason = "edge flags";
}
/* SVGA_NEW_FS, SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
@@ -104,6 +120,7 @@ update_need_pipeline(struct svga_context *svga, unsigned dirty)
* point stage.
*/
need_pipeline = TRUE;
+ reason = "point sprite coordinate generation";
}
}
@@ -116,6 +133,12 @@ update_need_pipeline(struct svga_context *svga, unsigned dirty)
if (0 && svga->state.sw.need_pipeline)
debug_printf("sw.need_pipeline = %d\n", svga->state.sw.need_pipeline);
+ if (svga->state.sw.need_pipeline) {
+ assert(reason);
+ pipe_debug_message(&svga->debug.callback, FALLBACK,
+ "Using semi-fallback for %s", reason);
+ }
+
return PIPE_OK;
}
diff --git a/src/gallium/drivers/svga/svga_state_tgsi_transform.c b/src/gallium/drivers/svga/svga_state_tgsi_transform.c
index 023c5862d27..9e643ff49a7 100644
--- a/src/gallium/drivers/svga/svga_state_tgsi_transform.c
+++ b/src/gallium/drivers/svga/svga_state_tgsi_transform.c
@@ -88,13 +88,13 @@ emulate_point_sprite(struct svga_context *svga,
key.gs.aa_point = svga->curr.rast->templ.point_smooth;
- if (orig_gs != NULL) {
+ if (orig_gs) {
/* Check if the original geometry shader has stream output and
* if position is one of the outputs.
*/
streamout = orig_gs->base.stream_output;
- if (streamout != NULL) {
+ if (streamout) {
pos_out_index = streamout->pos_out_index;
key.gs.point_pos_stream_out = pos_out_index != -1;
}
@@ -119,7 +119,7 @@ emulate_point_sprite(struct svga_context *svga,
key.gs.aa_point ?
&aa_point_coord_index : NULL);
- if (new_tokens == NULL) {
+ if (!new_tokens) {
/* if no new tokens are generated for whatever reason, just return */
return NULL;
}
@@ -134,7 +134,7 @@ emulate_point_sprite(struct svga_context *svga,
templ.tokens = new_tokens;
templ.stream_output.num_outputs = 0;
- if (streamout != NULL) {
+ if (streamout) {
templ.stream_output = streamout->info;
/* The tgsi_add_point_sprite utility adds an extra output
* for the original point position for stream output purpose.
@@ -169,7 +169,7 @@ emulate_point_sprite(struct svga_context *svga,
/* Add the new geometry shader to the head of the shader list
* pointed to by the original geometry shader.
*/
- if (orig_gs != NULL) {
+ if (orig_gs) {
gs->base.next = orig_gs->base.next;
orig_gs->base.next = &gs->base;
}
@@ -207,7 +207,7 @@ add_point_sprite_shader(struct svga_context *svga)
vs->base.info.output_semantic_name,
vs->base.info.output_semantic_index);
- if (orig_gs == NULL)
+ if (!orig_gs)
return NULL;
}
else {
diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c
index 5991da13868..4debbf1669b 100644
--- a/src/gallium/drivers/svga/svga_state_tss.c
+++ b/src/gallium/drivers/svga/svga_state_tss.c
@@ -316,7 +316,7 @@ svga_queue_tss( struct ts_queue *q,
unsigned tss,
unsigned value )
{
- assert(q->ts_count < sizeof(q->ts)/sizeof(q->ts[0]));
+ assert(q->ts_count < ARRAY_SIZE(q->ts));
q->ts[q->ts_count].stage = unit;
q->ts[q->ts_count].name = tss;
q->ts[q->ts_count].value = value;
diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c
index 9f09311116e..ad06a1d531e 100644
--- a/src/gallium/drivers/svga/svga_surface.c
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -357,7 +357,7 @@ create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
{
struct svga_surface *bs = s->backed;
- if (bs == NULL) {
+ if (!bs) {
struct svga_texture *tex = svga_texture(s->base.texture);
struct pipe_surface *backed_view;
diff --git a/src/gallium/drivers/svga/svga_tgsi.c b/src/gallium/drivers/svga/svga_tgsi.c
index 4c16f4313a0..c62d4d671ef 100644
--- a/src/gallium/drivers/svga/svga_tgsi.c
+++ b/src/gallium/drivers/svga/svga_tgsi.c
@@ -71,7 +71,7 @@ svga_shader_expand(struct svga_shader_emitter *emit)
else
new_buf = NULL;
- if (new_buf == NULL) {
+ if (!new_buf) {
emit->ptr = err_buf;
emit->buf = err_buf;
emit->size = sizeof(err_buf);
@@ -229,7 +229,7 @@ svga_tgsi_vgpu9_translate(struct svga_context *svga,
}
variant = svga_new_shader_variant(svga);
- if (variant == NULL)
+ if (!variant)
goto fail;
variant->shader = shader;
diff --git a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c
index 9b7ab16103f..c979f4a8a56 100644
--- a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c
+++ b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c
@@ -240,7 +240,7 @@ expand(struct svga_shader_emitter_v10 *emit)
else
new_buf = NULL;
- if (new_buf == NULL) {
+ if (!new_buf) {
emit->ptr = err_buf;
emit->buf = err_buf;
emit->size = sizeof(err_buf);
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_op.c b/src/gallium/drivers/svga/svgadump/svga_shader_op.c
index ad1549d9f81..03a63cf5e2b 100644
--- a/src/gallium/drivers/svga/svgadump/svga_shader_op.c
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_op.c
@@ -144,7 +144,7 @@ const struct sh_opcode_info *svga_opcode_info( uint op )
{
struct sh_opcode_info *info;
- if (op >= sizeof( opcode_info ) / sizeof( opcode_info[0] )) {
+ if (op >= ARRAY_SIZE(opcode_info)) {
/* The opcode is either PHASE, COMMENT, END or out of range.
*/
assert( 0 );
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index 7f6d0645112..d4c88c9be6d 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -72,7 +72,7 @@ trace_resource_unwrap(struct trace_context *tr_ctx,
{
struct trace_resource *tr_res;
- if(!resource)
+ if (!resource)
return NULL;
tr_res = trace_resource(resource);
@@ -89,7 +89,7 @@ trace_surface_unwrap(struct trace_context *tr_ctx,
struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen);
struct trace_surface *tr_surf;
- if(!surface)
+ if (!surface)
return NULL;
assert(surface->texture);
@@ -1284,7 +1284,7 @@ trace_context_flush(struct pipe_context *_pipe,
pipe->flush(pipe, fence, flags);
- if(fence)
+ if (fence)
trace_dump_ret(ptr, *fence);
trace_dump_call_end();
@@ -1539,14 +1539,14 @@ trace_context_create(struct trace_screen *tr_scr,
{
struct trace_context *tr_ctx;
- if(!pipe)
+ if (!pipe)
goto error1;
if(!trace_enabled())
goto error1;
tr_ctx = CALLOC_STRUCT(trace_context);
- if(!tr_ctx)
+ if (!tr_ctx)
goto error1;
tr_ctx->base.priv = pipe->priv; /* expose wrapped priv data */
diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c
index 601e2cbbec5..b173b8abf89 100644
--- a/src/gallium/drivers/trace/tr_dump.c
+++ b/src/gallium/drivers/trace/tr_dump.c
@@ -218,7 +218,7 @@ trace_dump_tag_end(const char *name)
void
trace_dump_trace_flush(void)
{
- if(stream) {
+ if (stream) {
fflush(stream);
}
}
@@ -226,7 +226,7 @@ trace_dump_trace_flush(void)
static void
trace_dump_trace_close(void)
{
- if(stream) {
+ if (stream) {
trace_dump_writes("\n");
if (close_stream) {
fclose(stream);
@@ -257,10 +257,10 @@ trace_dump_trace_begin(void)
const char *filename;
filename = debug_get_option("GALLIUM_TRACE", NULL);
- if(!filename)
+ if (!filename)
return FALSE;
- if(!stream) {
+ if (!stream) {
if (strcmp(filename, "stderr") == 0) {
close_stream = FALSE;
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index 9bf4a722d80..54f022a8ab6 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -41,7 +41,7 @@ void trace_dump_resource_template(const struct pipe_resource *templat)
if (!trace_dumping_enabled_locked())
return;
- if(!templat) {
+ if (!templat) {
trace_dump_null();
return;
}
@@ -82,7 +82,7 @@ void trace_dump_box(const struct pipe_box *box)
if (!trace_dumping_enabled_locked())
return;
- if(!box) {
+ if (!box) {
trace_dump_null();
return;
}
@@ -105,7 +105,7 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -168,7 +168,7 @@ void trace_dump_poly_stipple(const struct pipe_poly_stipple *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -190,7 +190,7 @@ void trace_dump_viewport_state(const struct pipe_viewport_state *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -209,7 +209,7 @@ void trace_dump_scissor_state(const struct pipe_scissor_state *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -232,7 +232,7 @@ void trace_dump_clip_state(const struct pipe_clip_state *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -260,7 +260,7 @@ void trace_dump_shader_state(const struct pipe_shader_state *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -312,7 +312,7 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -382,7 +382,7 @@ void trace_dump_blend_state(const struct pipe_blend_state *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -411,7 +411,7 @@ void trace_dump_blend_color(const struct pipe_blend_color *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -428,7 +428,7 @@ void trace_dump_stencil_ref(const struct pipe_stencil_ref *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -462,7 +462,7 @@ void trace_dump_sampler_state(const struct pipe_sampler_state *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -495,7 +495,7 @@ void trace_dump_sampler_view_template(const struct pipe_sampler_view *state,
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -541,7 +541,7 @@ void trace_dump_surface_template(const struct pipe_surface *state,
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -582,7 +582,7 @@ void trace_dump_transfer(const struct pipe_transfer *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -611,7 +611,7 @@ void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -632,7 +632,7 @@ void trace_dump_index_buffer(const struct pipe_index_buffer *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -653,7 +653,7 @@ void trace_dump_vertex_element(const struct pipe_vertex_element *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -675,7 +675,7 @@ void trace_dump_constant_buffer(const struct pipe_constant_buffer *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
@@ -693,7 +693,7 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
if (!trace_dumping_enabled_locked())
return;
- if(!state) {
+ if (!state) {
trace_dump_null();
return;
}
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 62a51e9a94d..ff057e2a4a4 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -462,7 +462,7 @@ trace_screen_create(struct pipe_screen *screen)
trace_dump_call_begin("", "pipe_screen_create");
tr_scr = CALLOC_STRUCT(trace_screen);
- if(!tr_scr)
+ if (!tr_scr)
goto error2;
tr_scr->base.destroy = trace_screen_destroy;
diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c
index ebc47870622..47845a35a64 100644
--- a/src/gallium/drivers/trace/tr_texture.c
+++ b/src/gallium/drivers/trace/tr_texture.c
@@ -41,13 +41,13 @@ trace_resource_create(struct trace_screen *tr_scr,
{
struct trace_resource *tr_res;
- if(!texture)
+ if (!texture)
goto error;
assert(texture->screen == tr_scr->screen);
tr_res = CALLOC_STRUCT(trace_resource);
- if(!tr_res)
+ if (!tr_res)
goto error;
memcpy(&tr_res->base, texture, sizeof(struct pipe_resource));
@@ -80,13 +80,13 @@ trace_surf_create(struct trace_context *tr_ctx,
{
struct trace_surface *tr_surf;
- if(!surface)
+ if (!surface)
goto error;
assert(surface->texture == tr_res->resource);
tr_surf = CALLOC_STRUCT(trace_surface);
- if(!tr_surf)
+ if (!tr_surf)
goto error;
memcpy(&tr_surf->base, surface, sizeof(struct pipe_surface));
@@ -122,13 +122,13 @@ trace_transfer_create(struct trace_context *tr_ctx,
{
struct trace_transfer *tr_trans;
- if(!transfer)
+ if (!transfer)
goto error;
assert(transfer->resource == tr_res->resource);
tr_trans = CALLOC_STRUCT(trace_transfer);
- if(!tr_trans)
+ if (!tr_trans)
goto error;
memcpy(&tr_trans->base, transfer, sizeof(struct pipe_transfer));
diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h
index e48b7b39e24..af508511567 100644
--- a/src/gallium/drivers/trace/tr_texture.h
+++ b/src/gallium/drivers/trace/tr_texture.h
@@ -88,7 +88,7 @@ struct trace_transfer
static inline struct trace_resource *
trace_resource(struct pipe_resource *texture)
{
- if(!texture)
+ if (!texture)
return NULL;
(void)trace_screen(texture->screen);
return (struct trace_resource *)texture;
@@ -98,7 +98,7 @@ trace_resource(struct pipe_resource *texture)
static inline struct trace_surface *
trace_surface(struct pipe_surface *surface)
{
- if(!surface)
+ if (!surface)
return NULL;
(void)trace_resource(surface->texture);
return (struct trace_surface *)surface;
@@ -117,7 +117,7 @@ trace_sampler_view(struct pipe_sampler_view *sampler_view)
static inline struct trace_transfer *
trace_transfer(struct pipe_transfer *transfer)
{
- if(!transfer)
+ if (!transfer)
return NULL;
(void)trace_resource(transfer->resource);
return (struct trace_transfer *)transfer;
diff --git a/src/gallium/drivers/vc4/Makefile.sources b/src/gallium/drivers/vc4/Makefile.sources
index 6fb40c20562..24b577ae9f3 100644
--- a/src/gallium/drivers/vc4/Makefile.sources
+++ b/src/gallium/drivers/vc4/Makefile.sources
@@ -21,6 +21,7 @@ C_SOURCES := \
vc4_job.c \
vc4_nir_lower_blend.c \
vc4_nir_lower_io.c \
+ vc4_nir_lower_txf_ms.c \
vc4_opt_algebraic.c \
vc4_opt_constant_folding.c \
vc4_opt_copy_propagation.c \
diff --git a/src/gallium/drivers/vc4/kernel/vc4_packet.h b/src/gallium/drivers/vc4/kernel/vc4_packet.h
index 771e2b78761..c2e3a5128f0 100644
--- a/src/gallium/drivers/vc4/kernel/vc4_packet.h
+++ b/src/gallium/drivers/vc4/kernel/vc4_packet.h
@@ -121,6 +121,11 @@ enum vc4_packet {
#define VC4_PACKET_TILE_COORDINATES_SIZE 3
#define VC4_PACKET_GEM_HANDLES_SIZE 9
+/* Number of multisamples supported. */
+#define VC4_MAX_SAMPLES 4
+/* Size of a full resolution color or Z tile buffer load/store. */
+#define VC4_TILE_BUFFER_SIZE (64 * 64 * 4)
+
#define VC4_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low))
/* Using the GNU statement expression extension */
#define VC4_SET_FIELD(value, field) \
@@ -151,6 +156,16 @@ enum vc4_packet {
#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS (1 << 1)
#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR (1 << 0)
+/** @{
+ *
+ * low bits of VC4_PACKET_STORE_FULL_RES_TILE_BUFFER and
+ * VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER.
+ */
+#define VC4_LOADSTORE_FULL_RES_EOF (1 << 3)
+#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL (1 << 2)
+#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS (1 << 1)
+#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR (1 << 0)
+
/** @{
*
* byte 2 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
diff --git a/src/gallium/drivers/vc4/kernel/vc4_render_cl.c b/src/gallium/drivers/vc4/kernel/vc4_render_cl.c
index b827eb7e9e1..d9c68423f8b 100644
--- a/src/gallium/drivers/vc4/kernel/vc4_render_cl.c
+++ b/src/gallium/drivers/vc4/kernel/vc4_render_cl.c
@@ -36,9 +36,11 @@
struct vc4_rcl_setup {
struct drm_gem_cma_object *color_read;
- struct drm_gem_cma_object *color_ms_write;
+ struct drm_gem_cma_object *color_write;
struct drm_gem_cma_object *zs_read;
struct drm_gem_cma_object *zs_write;
+ struct drm_gem_cma_object *msaa_color_write;
+ struct drm_gem_cma_object *msaa_zs_write;
struct drm_gem_cma_object *rcl;
u32 next_offset;
@@ -62,7 +64,6 @@ static inline void rcl_u32(struct vc4_rcl_setup *setup, u32 val)
setup->next_offset += 4;
}
-
/*
* Emits a no-op STORE_TILE_BUFFER_GENERAL.
*
@@ -81,6 +82,22 @@ static void vc4_store_before_load(struct vc4_rcl_setup *setup)
rcl_u32(setup, 0); /* no address, since we're in None mode */
}
+/*
+ * Calculates the physical address of the start of a tile in a RCL surface.
+ *
+ * Unlike the other load/store packets,
+ * VC4_PACKET_LOAD/STORE_FULL_RES_TILE_BUFFER don't look at the tile
+ * coordinates packet, and instead just store to the address given.
+ */
+static uint32_t vc4_full_res_offset(struct vc4_exec_info *exec,
+ struct drm_gem_cma_object *bo,
+ struct drm_vc4_submit_rcl_surface *surf,
+ uint8_t x, uint8_t y)
+{
+ return bo->paddr + surf->offset + VC4_TILE_BUFFER_SIZE *
+ (DIV_ROUND_UP(exec->args->width, 32) * y + x);
+}
+
/*
* Emits a PACKET_TILE_COORDINATES if one isn't already pending.
*
@@ -108,22 +125,41 @@ static void emit_tile(struct vc4_exec_info *exec,
* may be outstanding at a time.
*/
if (setup->color_read) {
- rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
- rcl_u16(setup, args->color_read.bits);
- rcl_u32(setup,
- setup->color_read->paddr + args->color_read.offset);
+ if (args->color_read.flags &
+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
+ rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER);
+ rcl_u32(setup,
+ vc4_full_res_offset(exec, setup->color_read,
+ &args->color_read, x, y) |
+ VC4_LOADSTORE_FULL_RES_DISABLE_ZS);
+ } else {
+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
+ rcl_u16(setup, args->color_read.bits);
+ rcl_u32(setup, setup->color_read->paddr +
+ args->color_read.offset);
+ }
}
if (setup->zs_read) {
- if (setup->color_read) {
- /* Exec previous load. */
- vc4_tile_coordinates(setup, x, y);
- vc4_store_before_load(setup);
- }
+ if (args->zs_read.flags &
+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
+ rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER);
+ rcl_u32(setup,
+ vc4_full_res_offset(exec, setup->zs_read,
+ &args->zs_read, x, y) |
+ VC4_LOADSTORE_FULL_RES_DISABLE_COLOR);
+ } else {
+ if (setup->color_read) {
+ /* Exec previous load. */
+ vc4_tile_coordinates(setup, x, y);
+ vc4_store_before_load(setup);
+ }
- rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
- rcl_u16(setup, args->zs_read.bits);
- rcl_u32(setup, setup->zs_read->paddr + args->zs_read.offset);
+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
+ rcl_u16(setup, args->zs_read.bits);
+ rcl_u32(setup, setup->zs_read->paddr +
+ args->zs_read.offset);
+ }
}
/* Clipping depends on tile coordinates having been
@@ -144,20 +180,60 @@ static void emit_tile(struct vc4_exec_info *exec,
(y * exec->bin_tiles_x + x) * 32));
}
+ if (setup->msaa_color_write) {
+ bool last_tile_write = (!setup->msaa_zs_write &&
+ !setup->zs_write &&
+ !setup->color_write);
+ uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_ZS;
+
+ if (!last_tile_write)
+ bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL;
+ else if (last)
+ bits |= VC4_LOADSTORE_FULL_RES_EOF;
+ rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER);
+ rcl_u32(setup,
+ vc4_full_res_offset(exec, setup->msaa_color_write,
+ &args->msaa_color_write, x, y) |
+ bits);
+ }
+
+ if (setup->msaa_zs_write) {
+ bool last_tile_write = (!setup->zs_write &&
+ !setup->color_write);
+ uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_COLOR;
+
+ if (setup->msaa_color_write)
+ vc4_tile_coordinates(setup, x, y);
+ if (!last_tile_write)
+ bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL;
+ else if (last)
+ bits |= VC4_LOADSTORE_FULL_RES_EOF;
+ rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER);
+ rcl_u32(setup,
+ vc4_full_res_offset(exec, setup->msaa_zs_write,
+ &args->msaa_zs_write, x, y) |
+ bits);
+ }
+
if (setup->zs_write) {
+ bool last_tile_write = !setup->color_write;
+
+ if (setup->msaa_color_write || setup->msaa_zs_write)
+ vc4_tile_coordinates(setup, x, y);
+
rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
rcl_u16(setup, args->zs_write.bits |
- (setup->color_ms_write ?
- VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR : 0));
+ (last_tile_write ?
+ 0 : VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR));
rcl_u32(setup,
(setup->zs_write->paddr + args->zs_write.offset) |
- ((last && !setup->color_ms_write) ?
+ ((last && last_tile_write) ?
VC4_LOADSTORE_TILE_BUFFER_EOF : 0));
}
- if (setup->color_ms_write) {
- if (setup->zs_write) {
- /* Reset after previous store */
+ if (setup->color_write) {
+ if (setup->msaa_color_write || setup->msaa_zs_write ||
+ setup->zs_write) {
vc4_tile_coordinates(setup, x, y);
}
@@ -192,14 +268,26 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
}
if (setup->color_read) {
- loop_body_size += (VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE);
+ if (args->color_read.flags &
+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
+ loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE;
+ } else {
+ loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
+ }
}
if (setup->zs_read) {
- if (setup->color_read) {
- loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE;
- loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
+ if (args->zs_read.flags &
+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
+ loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE;
+ } else {
+ if (setup->color_read &&
+ !(args->color_read.flags &
+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES)) {
+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE;
+ loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
+ }
+ loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
}
- loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
}
if (has_bin) {
@@ -207,13 +295,23 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
loop_body_size += VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE;
}
+ if (setup->msaa_color_write)
+ loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE;
+ if (setup->msaa_zs_write)
+ loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE;
+
if (setup->zs_write)
loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
- if (setup->color_ms_write) {
- if (setup->zs_write)
- loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE;
+ if (setup->color_write)
loop_body_size += VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE;
- }
+
+ /* We need a VC4_PACKET_TILE_COORDINATES in between each store. */
+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE *
+ ((setup->msaa_color_write != NULL) +
+ (setup->msaa_zs_write != NULL) +
+ (setup->color_write != NULL) +
+ (setup->zs_write != NULL) - 1);
+
size += xtiles * ytiles * loop_body_size;
setup->rcl = drm_gem_cma_create(dev, size);
@@ -224,13 +322,12 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
rcl_u32(setup,
- (setup->color_ms_write ?
- (setup->color_ms_write->paddr +
- args->color_ms_write.offset) :
+ (setup->color_write ? (setup->color_write->paddr +
+ args->color_write.offset) :
0));
rcl_u16(setup, args->width);
rcl_u16(setup, args->height);
- rcl_u16(setup, args->color_ms_write.bits);
+ rcl_u16(setup, args->color_write.bits);
/* The tile buffer gets cleared when the previous tile is stored. If
* the clear values changed between frames, then the tile buffer has
@@ -255,6 +352,7 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
for (x = min_x_tile; x <= max_x_tile; x++) {
bool first = (x == min_x_tile && y == min_y_tile);
bool last = (x == max_x_tile && y == max_y_tile);
+
emit_tile(exec, setup, x, y, first, last);
}
}
@@ -266,6 +364,56 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
return 0;
}
+static int vc4_full_res_bounds_check(struct vc4_exec_info *exec,
+ struct drm_gem_cma_object *obj,
+ struct drm_vc4_submit_rcl_surface *surf)
+{
+ struct drm_vc4_submit_cl *args = exec->args;
+ u32 render_tiles_stride = DIV_ROUND_UP(exec->args->width, 32);
+
+ if (surf->offset > obj->base.size) {
+ DRM_ERROR("surface offset %d > BO size %zd\n",
+ surf->offset, obj->base.size);
+ return -EINVAL;
+ }
+
+ if ((obj->base.size - surf->offset) / VC4_TILE_BUFFER_SIZE <
+ render_tiles_stride * args->max_y_tile + args->max_x_tile) {
+ DRM_ERROR("MSAA tile %d, %d out of bounds "
+ "(bo size %zd, offset %d).\n",
+ args->max_x_tile, args->max_y_tile,
+ obj->base.size,
+ surf->offset);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
+ struct drm_gem_cma_object **obj,
+ struct drm_vc4_submit_rcl_surface *surf)
+{
+ if (surf->flags != 0 || surf->bits != 0) {
+ DRM_ERROR("MSAA surface had nonzero flags/bits\n");
+ return -EINVAL;
+ }
+
+ if (surf->hindex == ~0)
+ return 0;
+
+ *obj = vc4_use_bo(exec, surf->hindex);
+ if (!*obj)
+ return -EINVAL;
+
+ if (surf->offset & 0xf) {
+ DRM_ERROR("MSAA write must be 16b aligned.\n");
+ return -EINVAL;
+ }
+
+ return vc4_full_res_bounds_check(exec, *obj, surf);
+}
+
static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
struct drm_gem_cma_object **obj,
struct drm_vc4_submit_rcl_surface *surf)
@@ -277,9 +425,10 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
uint8_t format = VC4_GET_FIELD(surf->bits,
VC4_LOADSTORE_TILE_BUFFER_FORMAT);
int cpp;
+ int ret;
- if (surf->pad != 0) {
- DRM_ERROR("Padding unset\n");
+ if (surf->flags & ~VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
+ DRM_ERROR("Extra flags set\n");
return -EINVAL;
}
@@ -290,6 +439,25 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
if (!*obj)
return -EINVAL;
+ if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
+ if (surf == &exec->args->zs_write) {
+ DRM_ERROR("general zs write may not be a full-res.\n");
+ return -EINVAL;
+ }
+
+ if (surf->bits != 0) {
+ DRM_ERROR("load/store general bits set with "
+ "full res load/store.\n");
+ return -EINVAL;
+ }
+
+ ret = vc4_full_res_bounds_check(exec, *obj, surf);
+ if (!ret)
+ return ret;
+
+ return 0;
+ }
+
if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK |
VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK |
VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) {
@@ -341,9 +509,10 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
}
static int
-vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec,
- struct drm_gem_cma_object **obj,
- struct drm_vc4_submit_rcl_surface *surf)
+vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
+ struct vc4_rcl_setup *setup,
+ struct drm_gem_cma_object **obj,
+ struct drm_vc4_submit_rcl_surface *surf)
{
uint8_t tiling = VC4_GET_FIELD(surf->bits,
VC4_RENDER_CONFIG_MEMORY_FORMAT);
@@ -351,13 +520,15 @@ vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec,
VC4_RENDER_CONFIG_FORMAT);
int cpp;
- if (surf->pad != 0) {
- DRM_ERROR("Padding unset\n");
+ if (surf->flags != 0) {
+ DRM_ERROR("No flags supported on render config.\n");
return -EINVAL;
}
if (surf->bits & ~(VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK |
- VC4_RENDER_CONFIG_FORMAT_MASK)) {
+ VC4_RENDER_CONFIG_FORMAT_MASK |
+ VC4_RENDER_CONFIG_MS_MODE_4X |
+ VC4_RENDER_CONFIG_DECIMATE_MODE_4X)) {
DRM_ERROR("Unknown bits in render config: 0x%04x\n",
surf->bits);
return -EINVAL;
@@ -414,18 +585,20 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
if (has_bin &&
(args->max_x_tile > exec->bin_tiles_x ||
args->max_y_tile > exec->bin_tiles_y)) {
- DRM_ERROR("Render tiles (%d,%d) outside of bin config (%d,%d)\n",
+ DRM_ERROR("Render tiles (%d,%d) outside of bin config "
+ "(%d,%d)\n",
args->max_x_tile, args->max_y_tile,
exec->bin_tiles_x, exec->bin_tiles_y);
return -EINVAL;
}
- ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read);
+ ret = vc4_rcl_render_config_surface_setup(exec, &setup,
+ &setup.color_write,
+ &args->color_write);
if (ret)
return ret;
- ret = vc4_rcl_ms_surface_setup(exec, &setup.color_ms_write,
- &args->color_ms_write);
+ ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read);
if (ret)
return ret;
@@ -437,10 +610,21 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
if (ret)
return ret;
+ ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_color_write,
+ &args->msaa_color_write);
+ if (ret)
+ return ret;
+
+ ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_zs_write,
+ &args->msaa_zs_write);
+ if (ret)
+ return ret;
+
/* We shouldn't even have the job submitted to us if there's no
* surface to write out.
*/
- if (!setup.color_ms_write && !setup.zs_write) {
+ if (!setup.color_write && !setup.zs_write &&
+ !setup.msaa_color_write && !setup.msaa_zs_write) {
DRM_ERROR("RCL requires color or Z/S write\n");
return -EINVAL;
}
diff --git a/src/gallium/drivers/vc4/kernel/vc4_validate.c b/src/gallium/drivers/vc4/kernel/vc4_validate.c
index b248831113c..c9e3934ab4b 100644
--- a/src/gallium/drivers/vc4/kernel/vc4_validate.c
+++ b/src/gallium/drivers/vc4/kernel/vc4_validate.c
@@ -47,7 +47,6 @@
void *validated, \
void *untrusted
-
/** Return the width in pixels of a 64-byte microtile. */
static uint32_t
utile_width(int cpp)
@@ -191,7 +190,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
if (size + offset < size ||
size + offset > fbo->base.size) {
- DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %d)\n",
+ DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n",
width, height,
aligned_width, aligned_height,
size, offset, fbo->base.size);
@@ -201,7 +200,6 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
return true;
}
-
static int
validate_flush(VALIDATE_ARGS)
{
@@ -270,7 +268,7 @@ validate_indexed_prim_list(VALIDATE_ARGS)
if (offset > ib->base.size ||
(ib->base.size - offset) / index_size < length) {
- DRM_ERROR("IB access overflow (%d + %d*%d > %d)\n",
+ DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n",
offset, length, index_size, ib->base.size);
return -EINVAL;
}
@@ -361,9 +359,8 @@ validate_tile_binning_config(VALIDATE_ARGS)
}
if (flags & (VC4_BIN_CONFIG_DB_NON_MS |
- VC4_BIN_CONFIG_TILE_BUFFER_64BIT |
- VC4_BIN_CONFIG_MS_MODE_4X)) {
- DRM_ERROR("unsupported bining config flags 0x%02x\n", flags);
+ VC4_BIN_CONFIG_TILE_BUFFER_64BIT)) {
+ DRM_ERROR("unsupported binning config flags 0x%02x\n", flags);
return -EINVAL;
}
@@ -424,8 +421,8 @@ validate_gem_handles(VALIDATE_ARGS)
return 0;
}
-#define VC4_DEFINE_PACKET(packet, name, func) \
- [packet] = { packet ## _SIZE, name, func }
+#define VC4_DEFINE_PACKET(packet, func) \
+ [packet] = { packet ## _SIZE, #packet, func }
static const struct cmd_info {
uint16_t len;
@@ -433,42 +430,42 @@ static const struct cmd_info {
int (*func)(struct vc4_exec_info *exec, void *validated,
void *untrusted);
} cmd_info[] = {
- VC4_DEFINE_PACKET(VC4_PACKET_HALT, "halt", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_NOP, "nop", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, "flush", validate_flush),
- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, "flush all state", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, "start tile binning", validate_start_tile_binning),
- VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, "increment semaphore", validate_increment_semaphore),
+ VC4_DEFINE_PACKET(VC4_PACKET_HALT, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_NOP, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, validate_flush),
+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING,
+ validate_start_tile_binning),
+ VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE,
+ validate_increment_semaphore),
- VC4_DEFINE_PACKET(VC4_PACKET_GL_INDEXED_PRIMITIVE, "Indexed Primitive List", validate_indexed_prim_list),
+ VC4_DEFINE_PACKET(VC4_PACKET_GL_INDEXED_PRIMITIVE,
+ validate_indexed_prim_list),
+ VC4_DEFINE_PACKET(VC4_PACKET_GL_ARRAY_PRIMITIVE,
+ validate_gl_array_primitive),
- VC4_DEFINE_PACKET(VC4_PACKET_GL_ARRAY_PRIMITIVE, "Vertex Array Primitives", validate_gl_array_primitive),
+ VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, NULL),
- /* This is only used by clipped primitives (packets 48 and 49), which
- * we don't support parsing yet.
- */
- VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, "primitive list format", NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, validate_gl_shader_state),
- VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, "GL Shader State", validate_gl_shader_state),
- /* We don't support validating NV shader states. */
-
- VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, "configuration bits", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, "flat shade flags", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_POINT_SIZE, "point size", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_LINE_WIDTH, "line width", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_RHT_X_BOUNDARY, "RHT X boundary", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_DEPTH_OFFSET, "Depth Offset", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_CLIP_WINDOW, "Clip Window", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_VIEWPORT_OFFSET, "Viewport Offset", NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_XY_SCALING, "Clipper XY Scaling", NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_POINT_SIZE, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_LINE_WIDTH, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_RHT_X_BOUNDARY, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_DEPTH_OFFSET, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_CLIP_WINDOW, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_VIEWPORT_OFFSET, NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_XY_SCALING, NULL),
/* Note: The docs say this was also 105, but it was 106 in the
* initial userland code drop.
*/
- VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_Z_SCALING, "Clipper Z Scale and Offset", NULL),
+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_Z_SCALING, NULL),
- VC4_DEFINE_PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG, "tile binning configuration", validate_tile_binning_config),
+ VC4_DEFINE_PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG,
+ validate_tile_binning_config),
- VC4_DEFINE_PACKET(VC4_PACKET_GEM_HANDLES, "GEM handles", validate_gem_handles),
+ VC4_DEFINE_PACKET(VC4_PACKET_GEM_HANDLES, validate_gem_handles),
};
int
@@ -500,11 +497,6 @@ vc4_validate_bin_cl(struct drm_device *dev,
return -EINVAL;
}
-#if 0
- DRM_INFO("0x%08x: packet %d (%s) size %d processing...\n",
- src_offset, cmd, info->name, info->len);
-#endif
-
if (src_offset + info->len > len) {
DRM_ERROR("0x%08x: packet %d (%s) length 0x%08x "
"exceeds bounds (0x%08x)\n",
@@ -519,8 +511,7 @@ vc4_validate_bin_cl(struct drm_device *dev,
if (info->func && info->func(exec,
dst_pkt + 1,
src_pkt + 1)) {
- DRM_ERROR("0x%08x: packet %d (%s) failed to "
- "validate\n",
+ DRM_ERROR("0x%08x: packet %d (%s) failed to validate\n",
src_offset, cmd, info->name);
return -EINVAL;
}
@@ -588,12 +579,14 @@ reloc_tex(struct vc4_exec_info *exec,
if (sample->is_direct) {
uint32_t remaining_size = tex->base.size - p0;
+
if (p0 > tex->base.size - 4) {
DRM_ERROR("UBO offset greater than UBO size\n");
goto fail;
}
if (p1 > remaining_size - 4) {
- DRM_ERROR("UBO clamp would allow reads outside of UBO\n");
+ DRM_ERROR("UBO clamp would allow reads "
+ "outside of UBO\n");
goto fail;
}
*validated_p0 = tex->paddr + p0;
@@ -866,7 +859,7 @@ validate_gl_shader_rec(struct drm_device *dev,
if (vbo->base.size < offset ||
vbo->base.size - offset < attr_size) {
- DRM_ERROR("BO offset overflow (%d + %d > %d)\n",
+ DRM_ERROR("BO offset overflow (%d + %d > %zd)\n",
offset, attr_size, vbo->base.size);
return -EINVAL;
}
@@ -875,7 +868,8 @@ validate_gl_shader_rec(struct drm_device *dev,
max_index = ((vbo->base.size - offset - attr_size) /
stride);
if (state->max_index > max_index) {
- DRM_ERROR("primitives use index %d out of supplied %d\n",
+ DRM_ERROR("primitives use index %d out of "
+ "supplied %d\n",
state->max_index, max_index);
return -EINVAL;
}
diff --git a/src/gallium/drivers/vc4/kernel/vc4_validate_shaders.c b/src/gallium/drivers/vc4/kernel/vc4_validate_shaders.c
index ab9a6512e82..868a0ad1a3a 100644
--- a/src/gallium/drivers/vc4/kernel/vc4_validate_shaders.c
+++ b/src/gallium/drivers/vc4/kernel/vc4_validate_shaders.c
@@ -24,24 +24,16 @@
/**
* DOC: Shader validator for VC4.
*
- * The VC4 has no IOMMU between it and system memory. So, a user with access
- * to execute shaders could escalate privilege by overwriting system memory
- * (using the VPM write address register in the general-purpose DMA mode) or
- * reading system memory it shouldn't (reading it as a texture, or uniform
- * data, or vertex data).
+ * The VC4 has no IOMMU between it and system memory, so a user with
+ * access to execute shaders could escalate privilege by overwriting
+ * system memory (using the VPM write address register in the
+ * general-purpose DMA mode) or reading system memory it shouldn't
+ * (reading it as a texture, or uniform data, or vertex data).
*
- * This walks over a shader starting from some offset within a BO, ensuring
- * that its accesses are appropriately bounded, and recording how many texture
- * accesses are made and where so that we can do relocations for them in the
+ * This walks over a shader BO, ensuring that its accesses are
+ * appropriately bounded, and recording how many texture accesses are
+ * made and where so that we can do relocations for them in the
* uniform stream.
- *
- * The kernel API has shaders stored in user-mapped BOs. The BOs will be
- * forcibly unmapped from the process before validation, and any cache of
- * validated state will be flushed if the mapping is faulted back in.
- *
- * Storing the shaders in BOs means that the validation process will be slow
- * due to uncached reads, but since shaders are long-lived and shader BOs are
- * never actually modified, this shouldn't be a problem.
*/
#include "vc4_drv.h"
@@ -71,7 +63,6 @@ waddr_to_live_reg_index(uint32_t waddr, bool is_b)
else
return waddr;
} else if (waddr <= QPU_W_ACC3) {
-
return 64 + waddr - QPU_W_ACC0;
} else {
return ~0;
@@ -86,15 +77,14 @@ raddr_add_a_to_live_reg_index(uint64_t inst)
uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A);
uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B);
- if (add_a == QPU_MUX_A) {
+ if (add_a == QPU_MUX_A)
return raddr_a;
- } else if (add_a == QPU_MUX_B && sig != QPU_SIG_SMALL_IMM) {
+ else if (add_a == QPU_MUX_B && sig != QPU_SIG_SMALL_IMM)
return 32 + raddr_b;
- } else if (add_a <= QPU_MUX_R3) {
+ else if (add_a <= QPU_MUX_R3)
return 64 + add_a;
- } else {
+ else
return ~0;
- }
}
static bool
@@ -112,9 +102,9 @@ is_tmu_write(uint32_t waddr)
}
static bool
-record_validated_texture_sample(struct vc4_validated_shader_info *validated_shader,
- struct vc4_shader_validation_state *validation_state,
- int tmu)
+record_texture_sample(struct vc4_validated_shader_info *validated_shader,
+ struct vc4_shader_validation_state *validation_state,
+ int tmu)
{
uint32_t s = validated_shader->num_texture_samples;
int i;
@@ -227,8 +217,8 @@ check_tmu_write(uint64_t inst,
validated_shader->uniforms_size += 4;
if (submit) {
- if (!record_validated_texture_sample(validated_shader,
- validation_state, tmu)) {
+ if (!record_texture_sample(validated_shader,
+ validation_state, tmu)) {
return false;
}
@@ -239,10 +229,10 @@ check_tmu_write(uint64_t inst,
}
static bool
-check_register_write(uint64_t inst,
- struct vc4_validated_shader_info *validated_shader,
- struct vc4_shader_validation_state *validation_state,
- bool is_mul)
+check_reg_write(uint64_t inst,
+ struct vc4_validated_shader_info *validated_shader,
+ struct vc4_shader_validation_state *validation_state,
+ bool is_mul)
{
uint32_t waddr = (is_mul ?
QPU_GET_FIELD(inst, QPU_WADDR_MUL) :
@@ -298,7 +288,7 @@ check_register_write(uint64_t inst,
return true;
case QPU_W_TLB_STENCIL_SETUP:
- return true;
+ return true;
}
return true;
@@ -361,7 +351,7 @@ track_live_clamps(uint64_t inst,
}
validation_state->live_max_clamp_regs[lri_add] = true;
- } if (op_add == QPU_A_MIN) {
+ } else if (op_add == QPU_A_MIN) {
/* Track live clamps of a value clamped to a minimum of 0 and
* a maximum of some uniform's offset.
*/
@@ -393,8 +383,10 @@ check_instruction_writes(uint64_t inst,
return false;
}
- ok = (check_register_write(inst, validated_shader, validation_state, false) &&
- check_register_write(inst, validated_shader, validation_state, true));
+ ok = (check_reg_write(inst, validated_shader, validation_state,
+ false) &&
+ check_reg_write(inst, validated_shader, validation_state,
+ true));
track_live_clamps(inst, validated_shader, validation_state);
@@ -442,7 +434,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
shader = shader_obj->vaddr;
max_ip = shader_obj->base.size / sizeof(uint64_t);
- validated_shader = kcalloc(sizeof(*validated_shader), 1, GFP_KERNEL);
+ validated_shader = kcalloc(1, sizeof(*validated_shader), GFP_KERNEL);
if (!validated_shader)
return NULL;
@@ -498,7 +490,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
if (ip == max_ip) {
DRM_ERROR("shader failed to terminate before "
- "shader BO end at %d\n",
+ "shader BO end at %zd\n",
shader_obj->base.size);
goto fail;
}
@@ -514,6 +506,9 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
return validated_shader;
fail:
- kfree(validated_shader);
+ if (validated_shader) {
+ kfree(validated_shader->texture_samples);
+ kfree(validated_shader);
+ }
return NULL;
}
diff --git a/src/gallium/drivers/vc4/vc4_blit.c b/src/gallium/drivers/vc4/vc4_blit.c
index e52a1941730..16dcece1ea1 100644
--- a/src/gallium/drivers/vc4/vc4_blit.c
+++ b/src/gallium/drivers/vc4/vc4_blit.c
@@ -41,47 +41,100 @@ vc4_get_blit_surface(struct pipe_context *pctx,
return pctx->create_surface(pctx, prsc, &tmpl);
}
+static bool
+is_tile_unaligned(unsigned size, unsigned tile_size)
+{
+ return size & (tile_size - 1);
+}
+
static bool
vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
{
struct vc4_context *vc4 = vc4_context(pctx);
+ bool old_msaa = vc4->msaa;
+ int old_tile_width = vc4->tile_width;
+ int old_tile_height = vc4->tile_height;
+ bool msaa = (info->src.resource->nr_samples ||
+ info->dst.resource->nr_samples);
+ int tile_width = msaa ? 32 : 64;
+ int tile_height = msaa ? 32 : 64;
if (util_format_is_depth_or_stencil(info->dst.resource->format))
return false;
+ if (info->scissor_enable)
+ return false;
+
if ((info->mask & PIPE_MASK_RGBA) == 0)
return false;
- if (info->dst.box.x != 0 || info->dst.box.y != 0 ||
- info->src.box.x != 0 || info->src.box.y != 0 ||
+ if (info->dst.box.x != info->src.box.x ||
+ info->dst.box.y != info->src.box.y ||
info->dst.box.width != info->src.box.width ||
info->dst.box.height != info->src.box.height) {
return false;
}
+ int dst_surface_width = u_minify(info->dst.resource->width0,
+ info->dst.level);
+ int dst_surface_height = u_minify(info->dst.resource->height0,
+ info->dst.level);
+ if (is_tile_unaligned(info->dst.box.x, tile_width) ||
+ is_tile_unaligned(info->dst.box.y, tile_height) ||
+ (is_tile_unaligned(info->dst.box.width, tile_width) &&
+ info->dst.box.x + info->dst.box.width != dst_surface_width) ||
+ (is_tile_unaligned(info->dst.box.height, tile_height) &&
+ info->dst.box.y + info->dst.box.height != dst_surface_height)) {
+ return false;
+ }
+
if (info->dst.resource->format != info->src.resource->format)
return false;
vc4_flush(pctx);
+ if (false) {
+ fprintf(stderr, "RCL blit from %d,%d to %d,%d (%d,%d)\n",
+ info->src.box.x,
+ info->src.box.y,
+ info->dst.box.x,
+ info->dst.box.y,
+ info->dst.box.width,
+ info->dst.box.height);
+ }
+
struct pipe_surface *dst_surf =
vc4_get_blit_surface(pctx, info->dst.resource, info->dst.level);
struct pipe_surface *src_surf =
vc4_get_blit_surface(pctx, info->src.resource, info->src.level);
pipe_surface_reference(&vc4->color_read, src_surf);
- pipe_surface_reference(&vc4->color_write, dst_surf);
+ pipe_surface_reference(&vc4->color_write,
+ dst_surf->texture->nr_samples ? NULL : dst_surf);
+ pipe_surface_reference(&vc4->msaa_color_write,
+ dst_surf->texture->nr_samples ? dst_surf : NULL);
pipe_surface_reference(&vc4->zs_read, NULL);
pipe_surface_reference(&vc4->zs_write, NULL);
- vc4->draw_min_x = 0;
- vc4->draw_min_y = 0;
- vc4->draw_max_x = dst_surf->width;
- vc4->draw_max_y = dst_surf->height;
+ pipe_surface_reference(&vc4->msaa_zs_write, NULL);
+
+ vc4->draw_min_x = info->dst.box.x;
+ vc4->draw_min_y = info->dst.box.y;
+ vc4->draw_max_x = info->dst.box.x + info->dst.box.width;
+ vc4->draw_max_y = info->dst.box.y + info->dst.box.height;
vc4->draw_width = dst_surf->width;
vc4->draw_height = dst_surf->height;
+
+ vc4->tile_width = tile_width;
+ vc4->tile_height = tile_height;
+ vc4->msaa = msaa;
vc4->needs_flush = true;
+
vc4_job_submit(vc4);
+ vc4->msaa = old_msaa;
+ vc4->tile_width = old_tile_width;
+ vc4->tile_height = old_tile_height;
+
pipe_surface_reference(&dst_surf, NULL);
pipe_surface_reference(&src_surf, NULL);
@@ -131,14 +184,6 @@ vc4_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
{
struct pipe_blit_info info = *blit_info;
- if (info.src.resource->nr_samples > 1 &&
- info.dst.resource->nr_samples <= 1 &&
- !util_format_is_depth_or_stencil(info.src.resource->format) &&
- !util_format_is_pure_integer(info.src.resource->format)) {
- fprintf(stderr, "color resolve unimplemented\n");
- return;
- }
-
if (vc4_tile_blit(pctx, blit_info))
return;
diff --git a/src/gallium/drivers/vc4/vc4_context.c b/src/gallium/drivers/vc4/vc4_context.c
index d490fad5167..1cd167600b9 100644
--- a/src/gallium/drivers/vc4/vc4_context.c
+++ b/src/gallium/drivers/vc4/vc4_context.c
@@ -67,8 +67,16 @@ vc4_flush(struct pipe_context *pctx)
cl_u8(&bcl, VC4_PACKET_FLUSH);
cl_end(&vc4->bcl, bcl);
+ vc4->msaa = false;
if (cbuf && (vc4->resolve & PIPE_CLEAR_COLOR0)) {
- pipe_surface_reference(&vc4->color_write, cbuf);
+ pipe_surface_reference(&vc4->color_write,
+ cbuf->texture->nr_samples ? NULL : cbuf);
+ pipe_surface_reference(&vc4->msaa_color_write,
+ cbuf->texture->nr_samples ? cbuf : NULL);
+
+ if (cbuf->texture->nr_samples)
+ vc4->msaa = true;
+
if (!(vc4->cleared & PIPE_CLEAR_COLOR0)) {
pipe_surface_reference(&vc4->color_read, cbuf);
} else {
@@ -78,11 +86,21 @@ vc4_flush(struct pipe_context *pctx)
} else {
pipe_surface_reference(&vc4->color_write, NULL);
pipe_surface_reference(&vc4->color_read, NULL);
+ pipe_surface_reference(&vc4->msaa_color_write, NULL);
}
if (vc4->framebuffer.zsbuf &&
(vc4->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
- pipe_surface_reference(&vc4->zs_write, zsbuf);
+ pipe_surface_reference(&vc4->zs_write,
+ zsbuf->texture->nr_samples ?
+ NULL : zsbuf);
+ pipe_surface_reference(&vc4->msaa_zs_write,
+ zsbuf->texture->nr_samples ?
+ zsbuf : NULL);
+
+ if (zsbuf->texture->nr_samples)
+ vc4->msaa = true;
+
if (!(vc4->cleared & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
pipe_surface_reference(&vc4->zs_read, zsbuf);
} else {
@@ -91,6 +109,7 @@ vc4_flush(struct pipe_context *pctx)
} else {
pipe_surface_reference(&vc4->zs_write, NULL);
pipe_surface_reference(&vc4->zs_read, NULL);
+ pipe_surface_reference(&vc4->msaa_zs_write, NULL);
}
vc4_job_submit(vc4);
@@ -207,7 +226,7 @@ vc4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
vc4_debug &= ~VC4_DEBUG_SHADERDB;
vc4 = rzalloc(NULL, struct vc4_context);
- if (vc4 == NULL)
+ if (!vc4)
return NULL;
struct pipe_context *pctx = &vc4->base;
@@ -245,6 +264,8 @@ vc4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
vc4_debug |= saved_shaderdb_flag;
+ vc4->sample_mask = (1 << VC4_MAX_SAMPLES) - 1;
+
return &vc4->base;
fail:
diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h
index 86f2ce5e608..aa973bddcda 100644
--- a/src/gallium/drivers/vc4/vc4_context.h
+++ b/src/gallium/drivers/vc4/vc4_context.h
@@ -206,6 +206,8 @@ struct vc4_context {
struct pipe_surface *color_write;
struct pipe_surface *zs_read;
struct pipe_surface *zs_write;
+ struct pipe_surface *msaa_color_write;
+ struct pipe_surface *msaa_zs_write;
/** @} */
/** @{
* Bounding box of the scissor across all queued drawing.
@@ -224,6 +226,15 @@ struct vc4_context {
uint32_t draw_width;
uint32_t draw_height;
/** @} */
+ /** @{ Tile information, depending on MSAA and float color buffer. */
+ uint32_t draw_tiles_x; /** @< Number of tiles wide for framebuffer. */
+ uint32_t draw_tiles_y; /** @< Number of tiles high for framebuffer. */
+
+ uint32_t tile_width; /** @< Width of a tile. */
+ uint32_t tile_height; /** @< Height of a tile. */
+ /** Whether the current rendering is in a 4X MSAA tile buffer. */
+ bool msaa;
+ /** @} */
struct util_slab_mempool transfer_pool;
struct blitter_context *blitter;
diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c
index 624a236c573..c00855698b8 100644
--- a/src/gallium/drivers/vc4/vc4_draw.c
+++ b/src/gallium/drivers/vc4/vc4_draw.c
@@ -68,21 +68,17 @@ vc4_start_draw(struct vc4_context *vc4)
vc4_get_draw_cl_space(vc4);
- uint32_t width = vc4->framebuffer.width;
- uint32_t height = vc4->framebuffer.height;
- uint32_t tilew = align(width, 64) / 64;
- uint32_t tileh = align(height, 64) / 64;
struct vc4_cl_out *bcl = cl_start(&vc4->bcl);
-
// Tile state data is 48 bytes per tile, I think it can be thrown away
// as soon as binning is finished.
cl_u8(&bcl, VC4_PACKET_TILE_BINNING_MODE_CONFIG);
cl_u32(&bcl, 0); /* tile alloc addr, filled by kernel */
cl_u32(&bcl, 0); /* tile alloc size, filled by kernel */
cl_u32(&bcl, 0); /* tile state addr, filled by kernel */
- cl_u8(&bcl, tilew);
- cl_u8(&bcl, tileh);
- cl_u8(&bcl, 0); /* flags, filled by kernel. */
+ cl_u8(&bcl, vc4->draw_tiles_x);
+ cl_u8(&bcl, vc4->draw_tiles_y);
+ /* Other flags are filled by kernel. */
+ cl_u8(&bcl, vc4->msaa ? VC4_BIN_CONFIG_MS_MODE_4X : 0);
/* START_TILE_BINNING resets the statechange counters in the hardware,
* which are what is used when a primitive is binned to a tile to
@@ -102,8 +98,8 @@ vc4_start_draw(struct vc4_context *vc4)
vc4->needs_flush = true;
vc4->draw_calls_queued++;
- vc4->draw_width = width;
- vc4->draw_height = height;
+ vc4->draw_width = vc4->framebuffer.width;
+ vc4->draw_height = vc4->framebuffer.height;
cl_end(&vc4->bcl, bcl);
}
diff --git a/src/gallium/drivers/vc4/vc4_drm.h b/src/gallium/drivers/vc4/vc4_drm.h
index 863ef8da8fb..bf58c6cd078 100644
--- a/src/gallium/drivers/vc4/vc4_drm.h
+++ b/src/gallium/drivers/vc4/vc4_drm.h
@@ -44,10 +44,13 @@ struct drm_vc4_submit_rcl_surface {
uint32_t hindex; /* Handle index, or ~0 if not present. */
uint32_t offset; /* Offset to start of buffer. */
/*
- * Bits for either render config (color_ms_write) or load/store packet.
+ * Bits for either render config (color_write) or load/store packet.
+ * Bits should all be 0 for MSAA load/stores.
*/
uint16_t bits;
- uint16_t pad;
+
+#define VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES (1 << 0)
+ uint16_t flags;
};
/**
@@ -126,9 +129,11 @@ struct drm_vc4_submit_cl {
uint8_t max_x_tile;
uint8_t max_y_tile;
struct drm_vc4_submit_rcl_surface color_read;
- struct drm_vc4_submit_rcl_surface color_ms_write;
+ struct drm_vc4_submit_rcl_surface color_write;
struct drm_vc4_submit_rcl_surface zs_read;
struct drm_vc4_submit_rcl_surface zs_write;
+ struct drm_vc4_submit_rcl_surface msaa_color_write;
+ struct drm_vc4_submit_rcl_surface msaa_zs_write;
uint32_t clear_color[2];
uint32_t clear_z;
uint8_t clear_s;
diff --git a/src/gallium/drivers/vc4/vc4_emit.c b/src/gallium/drivers/vc4/vc4_emit.c
index ba064ff889b..5d647977755 100644
--- a/src/gallium/drivers/vc4/vc4_emit.c
+++ b/src/gallium/drivers/vc4/vc4_emit.c
@@ -29,17 +29,35 @@ vc4_emit_state(struct pipe_context *pctx)
struct vc4_context *vc4 = vc4_context(pctx);
struct vc4_cl_out *bcl = cl_start(&vc4->bcl);
- if (vc4->dirty & (VC4_DIRTY_SCISSOR | VC4_DIRTY_VIEWPORT)) {
+ if (vc4->dirty & (VC4_DIRTY_SCISSOR | VC4_DIRTY_VIEWPORT |
+ VC4_DIRTY_RASTERIZER)) {
float *vpscale = vc4->viewport.scale;
float *vptranslate = vc4->viewport.translate;
float vp_minx = -fabsf(vpscale[0]) + vptranslate[0];
float vp_maxx = fabsf(vpscale[0]) + vptranslate[0];
float vp_miny = -fabsf(vpscale[1]) + vptranslate[1];
float vp_maxy = fabsf(vpscale[1]) + vptranslate[1];
- uint32_t minx = MAX2(vc4->scissor.minx, vp_minx);
- uint32_t miny = MAX2(vc4->scissor.miny, vp_miny);
- uint32_t maxx = MIN2(vc4->scissor.maxx, vp_maxx);
- uint32_t maxy = MIN2(vc4->scissor.maxy, vp_maxy);
+
+ /* Clip to the scissor if it's enabled, but still clip to the
+ * drawable regardless since that controls where the binner
+ * tries to put things.
+ *
+ * Additionally, always clip the rendering to the viewport,
+ * since the hardware does guardband clipping, meaning
+ * primitives would rasterize outside of the view volume.
+ */
+ uint32_t minx, miny, maxx, maxy;
+ if (!vc4->rasterizer->base.scissor) {
+ minx = MAX2(vp_minx, 0);
+ miny = MAX2(vp_miny, 0);
+ maxx = MIN2(vp_maxx, vc4->draw_width);
+ maxy = MIN2(vp_maxy, vc4->draw_height);
+ } else {
+ minx = MAX2(vp_minx, vc4->scissor.minx);
+ miny = MAX2(vp_miny, vc4->scissor.miny);
+ maxx = MIN2(vp_maxx, vc4->scissor.maxx);
+ maxy = MIN2(vp_maxy, vc4->scissor.maxy);
+ }
cl_u8(&bcl, VC4_PACKET_CLIP_WINDOW);
cl_u16(&bcl, minx);
@@ -54,6 +72,20 @@ vc4_emit_state(struct pipe_context *pctx)
}
if (vc4->dirty & (VC4_DIRTY_RASTERIZER | VC4_DIRTY_ZSA)) {
+ uint8_t ez_enable_mask_out = ~0;
+
+ /* HW-2905: If the RCL ends up doing a full-res load when
+ * multisampling, then early Z tracking may end up with values
+ * from the previous tile due to a HW bug. Disable it to
+ * avoid that.
+ *
+ * We should be able to skip this when the Z is cleared, but I
+ * was seeing bad rendering on glxgears -samples 4 even in
+ * that case.
+ */
+ if (vc4->msaa)
+ ez_enable_mask_out &= ~VC4_CONFIG_BITS_EARLY_Z;
+
cl_u8(&bcl, VC4_PACKET_CONFIGURATION_BITS);
cl_u8(&bcl,
vc4->rasterizer->config_bits[0] |
@@ -62,8 +94,8 @@ vc4_emit_state(struct pipe_context *pctx)
vc4->rasterizer->config_bits[1] |
vc4->zsa->config_bits[1]);
cl_u8(&bcl,
- vc4->rasterizer->config_bits[2] |
- vc4->zsa->config_bits[2]);
+ (vc4->rasterizer->config_bits[2] |
+ vc4->zsa->config_bits[2]) & ez_enable_mask_out);
}
if (vc4->dirty & VC4_DIRTY_RASTERIZER) {
diff --git a/src/gallium/drivers/vc4/vc4_job.c b/src/gallium/drivers/vc4/vc4_job.c
index 9ad79c2ea10..79bf2c49eec 100644
--- a/src/gallium/drivers/vc4/vc4_job.c
+++ b/src/gallium/drivers/vc4/vc4_job.c
@@ -89,31 +89,37 @@ vc4_submit_setup_rcl_surface(struct vc4_context *vc4,
submit_surf->hindex = vc4_gem_hindex(vc4, rsc->bo);
submit_surf->offset = surf->offset;
- if (is_depth) {
- submit_surf->bits =
- VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_ZS,
- VC4_LOADSTORE_TILE_BUFFER_BUFFER);
+ if (psurf->texture->nr_samples == 0) {
+ if (is_depth) {
+ submit_surf->bits =
+ VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_ZS,
+ VC4_LOADSTORE_TILE_BUFFER_BUFFER);
+ } else {
+ submit_surf->bits =
+ VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_COLOR,
+ VC4_LOADSTORE_TILE_BUFFER_BUFFER) |
+ VC4_SET_FIELD(vc4_rt_format_is_565(psurf->format) ?
+ VC4_LOADSTORE_TILE_BUFFER_BGR565 :
+ VC4_LOADSTORE_TILE_BUFFER_RGBA8888,
+ VC4_LOADSTORE_TILE_BUFFER_FORMAT);
+ }
+ submit_surf->bits |=
+ VC4_SET_FIELD(surf->tiling,
+ VC4_LOADSTORE_TILE_BUFFER_TILING);
} else {
- submit_surf->bits =
- VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_COLOR,
- VC4_LOADSTORE_TILE_BUFFER_BUFFER) |
- VC4_SET_FIELD(vc4_rt_format_is_565(psurf->format) ?
- VC4_LOADSTORE_TILE_BUFFER_BGR565 :
- VC4_LOADSTORE_TILE_BUFFER_RGBA8888,
- VC4_LOADSTORE_TILE_BUFFER_FORMAT);
+ assert(!is_write);
+ submit_surf->flags |= VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES;
}
- submit_surf->bits |=
- VC4_SET_FIELD(surf->tiling, VC4_LOADSTORE_TILE_BUFFER_TILING);
if (is_write)
rsc->writes++;
}
static void
-vc4_submit_setup_ms_rcl_surface(struct vc4_context *vc4,
- struct drm_vc4_submit_rcl_surface *submit_surf,
- struct pipe_surface *psurf)
+vc4_submit_setup_rcl_render_config_surface(struct vc4_context *vc4,
+ struct drm_vc4_submit_rcl_surface *submit_surf,
+ struct pipe_surface *psurf)
{
struct vc4_surface *surf = vc4_surface(psurf);
@@ -126,16 +132,38 @@ vc4_submit_setup_ms_rcl_surface(struct vc4_context *vc4,
submit_surf->hindex = vc4_gem_hindex(vc4, rsc->bo);
submit_surf->offset = surf->offset;
- submit_surf->bits =
- VC4_SET_FIELD(vc4_rt_format_is_565(surf->base.format) ?
- VC4_RENDER_CONFIG_FORMAT_BGR565 :
- VC4_RENDER_CONFIG_FORMAT_RGBA8888,
- VC4_RENDER_CONFIG_FORMAT) |
- VC4_SET_FIELD(surf->tiling, VC4_RENDER_CONFIG_MEMORY_FORMAT);
+ if (psurf->texture->nr_samples == 0) {
+ submit_surf->bits =
+ VC4_SET_FIELD(vc4_rt_format_is_565(surf->base.format) ?
+ VC4_RENDER_CONFIG_FORMAT_BGR565 :
+ VC4_RENDER_CONFIG_FORMAT_RGBA8888,
+ VC4_RENDER_CONFIG_FORMAT) |
+ VC4_SET_FIELD(surf->tiling,
+ VC4_RENDER_CONFIG_MEMORY_FORMAT);
+ }
rsc->writes++;
}
+static void
+vc4_submit_setup_rcl_msaa_surface(struct vc4_context *vc4,
+ struct drm_vc4_submit_rcl_surface *submit_surf,
+ struct pipe_surface *psurf)
+{
+ struct vc4_surface *surf = vc4_surface(psurf);
+
+ if (!surf) {
+ submit_surf->hindex = ~0;
+ return;
+ }
+
+ struct vc4_resource *rsc = vc4_resource(psurf->texture);
+ submit_surf->hindex = vc4_gem_hindex(vc4, rsc->bo);
+ submit_surf->offset = surf->offset;
+ submit_surf->bits = 0;
+ rsc->writes++;
+}
+
/**
* Submits the job to the kernel and then reinitializes it.
*/
@@ -150,18 +178,35 @@ vc4_job_submit(struct vc4_context *vc4)
struct drm_vc4_submit_cl submit;
memset(&submit, 0, sizeof(submit));
- cl_ensure_space(&vc4->bo_handles, 4 * sizeof(uint32_t));
- cl_ensure_space(&vc4->bo_pointers, 4 * sizeof(struct vc4_bo *));
+ cl_ensure_space(&vc4->bo_handles, 6 * sizeof(uint32_t));
+ cl_ensure_space(&vc4->bo_pointers, 6 * sizeof(struct vc4_bo *));
vc4_submit_setup_rcl_surface(vc4, &submit.color_read,
vc4->color_read, false, false);
- vc4_submit_setup_ms_rcl_surface(vc4, &submit.color_ms_write,
- vc4->color_write);
+ vc4_submit_setup_rcl_render_config_surface(vc4, &submit.color_write,
+ vc4->color_write);
vc4_submit_setup_rcl_surface(vc4, &submit.zs_read,
vc4->zs_read, true, false);
vc4_submit_setup_rcl_surface(vc4, &submit.zs_write,
vc4->zs_write, true, true);
+ vc4_submit_setup_rcl_msaa_surface(vc4, &submit.msaa_color_write,
+ vc4->msaa_color_write);
+ vc4_submit_setup_rcl_msaa_surface(vc4, &submit.msaa_zs_write,
+ vc4->msaa_zs_write);
+
+ if (vc4->msaa) {
+ /* This bit controls how many pixels the general
+ * (i.e. subsampled) loads/stores are iterating over
+ * (multisample loads replicate out to the other samples).
+ */
+ submit.color_write.bits |= VC4_RENDER_CONFIG_MS_MODE_4X;
+ /* Controls whether color_write's
+ * VC4_PACKET_STORE_MS_TILE_BUFFER does 4x decimation
+ */
+ submit.color_write.bits |= VC4_RENDER_CONFIG_DECIMATE_MODE_4X;
+ }
+
submit.bo_handles = (uintptr_t)vc4->bo_handles.base;
submit.bo_handle_count = cl_offset(&vc4->bo_handles) / 4;
submit.bin_cl = (uintptr_t)vc4->bcl.base;
@@ -173,10 +218,10 @@ vc4_job_submit(struct vc4_context *vc4)
submit.uniforms_size = cl_offset(&vc4->uniforms);
assert(vc4->draw_min_x != ~0 && vc4->draw_min_y != ~0);
- submit.min_x_tile = vc4->draw_min_x / 64;
- submit.min_y_tile = vc4->draw_min_y / 64;
- submit.max_x_tile = (vc4->draw_max_x - 1) / 64;
- submit.max_y_tile = (vc4->draw_max_y - 1) / 64;
+ submit.min_x_tile = vc4->draw_min_x / vc4->tile_width;
+ submit.min_y_tile = vc4->draw_min_y / vc4->tile_height;
+ submit.max_x_tile = (vc4->draw_max_x - 1) / vc4->tile_width;
+ submit.max_y_tile = (vc4->draw_max_y - 1) / vc4->tile_height;
submit.width = vc4->draw_width;
submit.height = vc4->draw_height;
if (vc4->cleared) {
diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_blend.c b/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
index 0672a92226f..4b10cb7fe56 100644
--- a/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
@@ -29,6 +29,10 @@
* from the tile buffer after having waited for the scoreboard (which is
* handled by vc4_qpu_emit.c), then do math using your output color and that
* destination value, and update the output color appropriately.
+ *
+ * Once this pass is done, the color write will either have one component (for
+ * single sample) with packed argb8888, or 4 components with the per-sample
+ * argb8888 result.
*/
/**
@@ -40,15 +44,24 @@
#include "glsl/nir/nir_builder.h"
#include "vc4_context.h"
+static bool
+blend_depends_on_dst_color(struct vc4_compile *c)
+{
+ return (c->fs_key->blend.blend_enable ||
+ c->fs_key->blend.colormask != 0xf ||
+ c->fs_key->logicop_func != PIPE_LOGICOP_COPY);
+}
+
/** Emits a load of the previous fragment color from the tile buffer. */
static nir_ssa_def *
-vc4_nir_get_dst_color(nir_builder *b)
+vc4_nir_get_dst_color(nir_builder *b, int sample)
{
nir_intrinsic_instr *load =
nir_intrinsic_instr_create(b->shader,
nir_intrinsic_load_input);
load->num_components = 1;
- load->const_index[0] = VC4_NIR_TLB_COLOR_READ_INPUT;
+ load->const_index[0] = VC4_NIR_TLB_COLOR_READ_INPUT + sample;
+ load->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
nir_ssa_dest_init(&load->instr, &load->dest, 1, NULL);
nir_builder_instr_insert(b, &load->instr);
return &load->dest.ssa;
@@ -496,23 +509,26 @@ vc4_nir_swizzle_and_pack(struct vc4_compile *c, nir_builder *b,
}
-static void
-vc4_nir_lower_blend_instr(struct vc4_compile *c, nir_builder *b,
- nir_intrinsic_instr *intr)
+static nir_ssa_def *
+vc4_nir_blend_pipeline(struct vc4_compile *c, nir_builder *b, nir_ssa_def *src,
+ int sample)
{
enum pipe_format color_format = c->fs_key->color_format;
const uint8_t *format_swiz = vc4_get_format_swizzle(color_format);
bool srgb = util_format_is_srgb(color_format);
/* Pull out the float src/dst color components. */
- nir_ssa_def *packed_dst_color = vc4_nir_get_dst_color(b);
+ nir_ssa_def *packed_dst_color = vc4_nir_get_dst_color(b, sample);
nir_ssa_def *dst_vec4 = nir_unpack_unorm_4x8(b, packed_dst_color);
nir_ssa_def *src_color[4], *unpacked_dst_color[4];
for (unsigned i = 0; i < 4; i++) {
- src_color[i] = nir_channel(b, intr->src[0].ssa, i);
+ src_color[i] = nir_channel(b, src, i);
unpacked_dst_color[i] = nir_channel(b, dst_vec4, i);
}
+ if (c->fs_key->sample_alpha_to_one && c->fs_key->msaa)
+ src_color[3] = nir_imm_float(b, 1.0);
+
vc4_nir_emit_alpha_test_discard(c, b, src_color[3]);
nir_ssa_def *packed_color;
@@ -560,16 +576,102 @@ vc4_nir_lower_blend_instr(struct vc4_compile *c, nir_builder *b,
colormask &= ~(0xff << (i * 8));
}
}
- packed_color = nir_ior(b,
- nir_iand(b, packed_color,
- nir_imm_int(b, colormask)),
- nir_iand(b, packed_dst_color,
- nir_imm_int(b, ~colormask)));
- /* Turn the old vec4 output into a store of the packed color. */
- nir_instr_rewrite_src(&intr->instr, &intr->src[0],
- nir_src_for_ssa(packed_color));
+ return nir_ior(b,
+ nir_iand(b, packed_color,
+ nir_imm_int(b, colormask)),
+ nir_iand(b, packed_dst_color,
+ nir_imm_int(b, ~colormask)));
+}
+
+static int
+vc4_nir_next_output_driver_location(nir_shader *s)
+{
+ int maxloc = -1;
+
+ nir_foreach_variable(var, &s->inputs)
+ maxloc = MAX2(maxloc, var->data.driver_location);
+
+ return maxloc;
+}
+
+static void
+vc4_nir_store_sample_mask(struct vc4_compile *c, nir_builder *b,
+ nir_ssa_def *val)
+{
+ nir_variable *sample_mask = nir_variable_create(c->s, nir_var_shader_out,
+ glsl_uint_type(),
+ "sample_mask");
+ sample_mask->data.driver_location =
+ vc4_nir_next_output_driver_location(c->s);
+ sample_mask->data.location = FRAG_RESULT_SAMPLE_MASK;
+ exec_list_push_tail(&c->s->outputs, &sample_mask->node);
+
+ nir_intrinsic_instr *intr =
+ nir_intrinsic_instr_create(c->s, nir_intrinsic_store_output);
intr->num_components = 1;
+ intr->const_index[0] = sample_mask->data.location;
+
+ intr->src[0] = nir_src_for_ssa(val);
+ intr->src[1] = nir_src_for_ssa(nir_imm_int(b, 0));
+ nir_builder_instr_insert(b, &intr->instr);
+}
+
+static void
+vc4_nir_lower_blend_instr(struct vc4_compile *c, nir_builder *b,
+ nir_intrinsic_instr *intr)
+{
+ nir_ssa_def *frag_color = intr->src[0].ssa;
+
+ if (c->fs_key->sample_coverage) {
+ nir_intrinsic_instr *load =
+ nir_intrinsic_instr_create(b->shader,
+ nir_intrinsic_load_sample_mask_in);
+ load->num_components = 1;
+ nir_ssa_dest_init(&load->instr, &load->dest, 1, NULL);
+ nir_builder_instr_insert(b, &load->instr);
+
+ nir_ssa_def *bitmask = &load->dest.ssa;
+
+ vc4_nir_store_sample_mask(c, b, bitmask);
+ } else if (c->fs_key->sample_alpha_to_coverage) {
+ nir_ssa_def *a = nir_channel(b, frag_color, 3);
+
+ /* XXX: We should do a nice dither based on the fragment
+ * coordinate, instead.
+ */
+ nir_ssa_def *num_samples = nir_imm_float(b, VC4_MAX_SAMPLES);
+ nir_ssa_def *num_bits = nir_f2i(b, nir_fmul(b, a, num_samples));
+ nir_ssa_def *bitmask = nir_isub(b,
+ nir_ishl(b,
+ nir_imm_int(b, 1),
+ num_bits),
+ nir_imm_int(b, 1));
+ vc4_nir_store_sample_mask(c, b, bitmask);
+ }
+
+ /* The TLB color read returns each sample in turn, so if our blending
+ * depends on the destination color, we're going to have to run the
+ * blending function separately for each destination sample value, and
+ * then output the per-sample color using TLB_COLOR_MS.
+ */
+ nir_ssa_def *blend_output;
+ if (c->fs_key->msaa && blend_depends_on_dst_color(c)) {
+ c->msaa_per_sample_output = true;
+
+ nir_ssa_def *samples[4];
+ for (int i = 0; i < VC4_MAX_SAMPLES; i++)
+ samples[i] = vc4_nir_blend_pipeline(c, b, frag_color, i);
+ blend_output = nir_vec4(b,
+ samples[0], samples[1],
+ samples[2], samples[3]);
+ } else {
+ blend_output = vc4_nir_blend_pipeline(c, b, frag_color, 0);
+ }
+
+ nir_instr_rewrite_src(&intr->instr, &intr->src[0],
+ nir_src_for_ssa(blend_output));
+ intr->num_components = blend_output->num_components;
}
static bool
@@ -577,7 +679,7 @@ vc4_nir_lower_blend_block(nir_block *block, void *state)
{
struct vc4_compile *c = state;
- nir_foreach_instr(block, instr) {
+ nir_foreach_instr_safe(block, instr) {
if (instr->type != nir_instr_type_intrinsic)
continue;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_io.c b/src/gallium/drivers/vc4/vc4_nir_lower_io.c
index 1afe52a63f4..a46af77f370 100644
--- a/src/gallium/drivers/vc4/vc4_nir_lower_io.c
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_io.c
@@ -179,6 +179,12 @@ vc4_nir_lower_vertex_attr(struct vc4_compile *c, nir_builder *b,
/* All TGSI-to-NIR inputs are vec4. */
assert(intr->num_components == 4);
+ /* We only accept direct outputs and TGSI only ever gives them to us
+ * with an offset value of 0.
+ */
+ assert(nir_src_as_const_value(intr->src[0]) &&
+ nir_src_as_const_value(intr->src[0])->u[0] == 0);
+
/* Generate dword loads for the VPM values (Since these intrinsics may
* be reordered, the actual reads will be generated at the top of the
* shader by ntq_setup_inputs().
@@ -190,6 +196,7 @@ vc4_nir_lower_vertex_attr(struct vc4_compile *c, nir_builder *b,
nir_intrinsic_load_input);
intr_comp->num_components = 1;
intr_comp->const_index[0] = intr->const_index[0] * 4 + i;
+ intr_comp->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
nir_ssa_dest_init(&intr_comp->instr, &intr_comp->dest, 1, NULL);
nir_builder_instr_insert(b, &intr_comp->instr);
@@ -226,7 +233,9 @@ vc4_nir_lower_fs_input(struct vc4_compile *c, nir_builder *b,
{
b->cursor = nir_before_instr(&intr->instr);
- if (intr->const_index[0] == VC4_NIR_TLB_COLOR_READ_INPUT) {
+ if (intr->const_index[0] >= VC4_NIR_TLB_COLOR_READ_INPUT &&
+ intr->const_index[0] < (VC4_NIR_TLB_COLOR_READ_INPUT +
+ VC4_MAX_SAMPLES)) {
/* This doesn't need any lowering. */
return;
}
@@ -243,6 +252,12 @@ vc4_nir_lower_fs_input(struct vc4_compile *c, nir_builder *b,
/* All TGSI-to-NIR inputs are vec4. */
assert(intr->num_components == 4);
+ /* We only accept direct inputs and TGSI only ever gives them to us
+ * with an offset value of 0.
+ */
+ assert(nir_src_as_const_value(intr->src[0]) &&
+ nir_src_as_const_value(intr->src[0])->u[0] == 0);
+
/* Generate scalar loads equivalent to the original VEC4. */
nir_ssa_def *dests[4];
for (unsigned i = 0; i < intr->num_components; i++) {
@@ -250,6 +265,8 @@ vc4_nir_lower_fs_input(struct vc4_compile *c, nir_builder *b,
nir_intrinsic_instr_create(c->s, nir_intrinsic_load_input);
intr_comp->num_components = 1;
intr_comp->const_index[0] = intr->const_index[0] * 4 + i;
+ intr_comp->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
+
nir_ssa_dest_init(&intr_comp->instr, &intr_comp->dest, 1, NULL);
nir_builder_instr_insert(b, &intr_comp->instr);
@@ -317,6 +334,12 @@ vc4_nir_lower_output(struct vc4_compile *c, nir_builder *b,
/* All TGSI-to-NIR outputs are VEC4. */
assert(intr->num_components == 4);
+ /* We only accept direct outputs and TGSI only ever gives them to us
+ * with an offset value of 0.
+ */
+ assert(nir_src_as_const_value(intr->src[1]) &&
+ nir_src_as_const_value(intr->src[1])->u[0] == 0);
+
b->cursor = nir_before_instr(&intr->instr);
for (unsigned i = 0; i < intr->num_components; i++) {
@@ -328,6 +351,7 @@ vc4_nir_lower_output(struct vc4_compile *c, nir_builder *b,
assert(intr->src[0].is_ssa);
intr_comp->src[0] =
nir_src_for_ssa(nir_channel(b, intr->src[0].ssa, i));
+ intr_comp->src[1] = nir_src_for_ssa(nir_imm_int(b, 0));
nir_builder_instr_insert(b, &intr_comp->instr);
}
@@ -338,8 +362,8 @@ static void
vc4_nir_lower_uniform(struct vc4_compile *c, nir_builder *b,
nir_intrinsic_instr *intr)
{
- /* All TGSI-to-NIR uniform loads are vec4, but we may create dword
- * loads in our lowering passes.
+ /* All TGSI-to-NIR uniform loads are vec4, but we need byte offsets
+ * in the backend.
*/
if (intr->num_components == 1)
return;
@@ -355,24 +379,23 @@ vc4_nir_lower_uniform(struct vc4_compile *c, nir_builder *b,
intr_comp->num_components = 1;
nir_ssa_dest_init(&intr_comp->instr, &intr_comp->dest, 1, NULL);
- if (intr->intrinsic == nir_intrinsic_load_uniform_indirect) {
- /* Convert the variable TGSI register index to a byte
- * offset.
+ /* Convert the uniform (not user_clip_plane) offset to bytes.
+ * If it happens to be a constant, constant-folding will clean
+ * up the shift for us.
+ */
+ if (intr->intrinsic == nir_intrinsic_load_uniform) {
+ /* Convert the base offset to bytes and add the
+ * component
*/
- intr_comp->src[0] =
- nir_src_for_ssa(nir_ishl(b,
- intr->src[0].ssa,
- nir_imm_int(b, 4)));
+ intr_comp->const_index[0] = (intr->const_index[0] * 16 + i * 4);
- /* Convert the offset to be a byte index, too. */
- intr_comp->const_index[0] = (intr->const_index[0] * 16 +
- i * 4);
+ intr_comp->src[0] =
+ nir_src_for_ssa(nir_ishl(b, intr->src[0].ssa,
+ nir_imm_int(b, 4)));
} else {
- /* We want a dword index for non-indirect uniform
- * loads.
- */
- intr_comp->const_index[0] = (intr->const_index[0] * 4 +
- i);
+ assert(intr->intrinsic ==
+ nir_intrinsic_load_user_clip_plane);
+ intr_comp->const_index[0] = intr->const_index[0] * 4 + i;
}
dests[i] = &intr_comp->dest.ssa;
@@ -404,7 +427,6 @@ vc4_nir_lower_io_instr(struct vc4_compile *c, nir_builder *b,
break;
case nir_intrinsic_load_uniform:
- case nir_intrinsic_load_uniform_indirect:
case nir_intrinsic_load_user_clip_plane:
vc4_nir_lower_uniform(c, b, intr);
break;
diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_txf_ms.c b/src/gallium/drivers/vc4/vc4_nir_lower_txf_ms.c
new file mode 100644
index 00000000000..54873e6186a
--- /dev/null
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_txf_ms.c
@@ -0,0 +1,172 @@
+/*
+ * 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 "vc4_qir.h"
+#include "kernel/vc4_packet.h"
+#include "tgsi/tgsi_info.h"
+#include "glsl/nir/nir_builder.h"
+
+/** @file vc4_nir_lower_txf_ms.c
+ * Walks the NIR generated by TGSI-to-NIR to lower its nir_texop_txf_ms
+ * coordinates to do the math necessary and use a plain nir_texop_txf instead.
+ *
+ * MSAA textures are laid out as 32x32-aligned blocks of RGBA8888 or Z24S8.
+ * We can't load them through the normal sampler path because of the lack of
+ * linear support in the hardware. So, we treat MSAA textures as a giant UBO
+ * and do the math in the shader.
+ */
+
+static void
+vc4_nir_lower_txf_ms_instr(struct vc4_compile *c, nir_builder *b,
+ nir_tex_instr *txf_ms)
+{
+ if (txf_ms->op != nir_texop_txf_ms)
+ return;
+
+ b->cursor = nir_before_instr(&txf_ms->instr);
+
+ nir_tex_instr *txf = nir_tex_instr_create(c->s, 1);
+ txf->op = nir_texop_txf;
+ txf->sampler = txf_ms->sampler;
+ txf->sampler_index = txf_ms->sampler_index;
+ txf->coord_components = txf_ms->coord_components;
+ txf->is_shadow = txf_ms->is_shadow;
+ txf->is_new_style_shadow = txf_ms->is_new_style_shadow;
+
+ nir_ssa_def *coord = NULL, *sample_index = NULL;
+ for (int i = 0; i < txf_ms->num_srcs; i++) {
+ assert(txf_ms->src[i].src.is_ssa);
+
+ switch (txf_ms->src[i].src_type) {
+ case nir_tex_src_coord:
+ coord = txf_ms->src[i].src.ssa;
+ break;
+ case nir_tex_src_ms_index:
+ sample_index = txf_ms->src[i].src.ssa;
+ break;
+ default:
+ unreachable("Unknown txf_ms src\n");
+ }
+ }
+ assert(coord);
+ assert(sample_index);
+
+ nir_ssa_def *x = nir_channel(b, coord, 0);
+ nir_ssa_def *y = nir_channel(b, coord, 1);
+
+ uint32_t tile_w = 32;
+ uint32_t tile_h = 32;
+ uint32_t tile_w_shift = 5;
+ uint32_t tile_h_shift = 5;
+ uint32_t tile_size = (tile_h * tile_w *
+ VC4_MAX_SAMPLES * sizeof(uint32_t));
+ unsigned unit = txf_ms->sampler_index;
+ uint32_t w = align(c->key->tex[unit].msaa_width, tile_w);
+ uint32_t w_tiles = w / tile_w;
+
+ nir_ssa_def *x_tile = nir_ushr(b, x, nir_imm_int(b, tile_w_shift));
+ nir_ssa_def *y_tile = nir_ushr(b, y, nir_imm_int(b, tile_h_shift));
+ nir_ssa_def *tile_addr = nir_iadd(b,
+ nir_imul(b, x_tile,
+ nir_imm_int(b, tile_size)),
+ nir_imul(b, y_tile,
+ nir_imm_int(b, (w_tiles *
+ tile_size))));
+ nir_ssa_def *x_subspan = nir_iand(b, x,
+ nir_imm_int(b, (tile_w - 1) & ~1));
+ nir_ssa_def *y_subspan = nir_iand(b, y,
+ nir_imm_int(b, (tile_h - 1) & ~1));
+ nir_ssa_def *subspan_addr = nir_iadd(b,
+ nir_imul(b, x_subspan,
+ nir_imm_int(b, 2 * VC4_MAX_SAMPLES * sizeof(uint32_t))),
+ nir_imul(b, y_subspan,
+ nir_imm_int(b,
+ tile_w *
+ VC4_MAX_SAMPLES *
+ sizeof(uint32_t))));
+
+ nir_ssa_def *pixel_addr = nir_ior(b,
+ nir_iand(b,
+ nir_ishl(b, x,
+ nir_imm_int(b, 2)),
+ nir_imm_int(b, (1 << 2))),
+ nir_iand(b,
+ nir_ishl(b, y,
+ nir_imm_int(b, 3)),
+ nir_imm_int(b, (1 << 3))));
+
+ nir_ssa_def *sample_addr = nir_ishl(b, sample_index, nir_imm_int(b, 4));
+
+ nir_ssa_def *addr = nir_iadd(b,
+ nir_ior(b, sample_addr, pixel_addr),
+ nir_iadd(b, subspan_addr, tile_addr));
+
+ txf->src[0].src_type = nir_tex_src_coord;
+ txf->src[0].src = nir_src_for_ssa(nir_vec2(b, addr, nir_imm_int(b, 0)));
+ nir_ssa_dest_init(&txf->instr, &txf->dest, 4, NULL);
+ nir_builder_instr_insert(b, &txf->instr);
+ nir_ssa_def_rewrite_uses(&txf_ms->dest.ssa,
+ nir_src_for_ssa(&txf->dest.ssa));
+ nir_instr_remove(&txf_ms->instr);
+}
+
+static bool
+vc4_nir_lower_txf_ms_block(nir_block *block, void *arg)
+{
+ struct vc4_compile *c = arg;
+ nir_function_impl *impl =
+ nir_cf_node_get_function(&block->cf_node);
+
+ nir_builder b;
+ nir_builder_init(&b, impl);
+
+ nir_foreach_instr_safe(block, instr) {
+ if (instr->type == nir_instr_type_tex) {
+ vc4_nir_lower_txf_ms_instr(c, &b,
+ nir_instr_as_tex(instr));
+ }
+ }
+
+ return true;
+}
+
+static bool
+vc4_nir_lower_txf_ms_impl(struct vc4_compile *c, nir_function_impl *impl)
+{
+ nir_foreach_block(impl, vc4_nir_lower_txf_ms_block, c);
+
+ nir_metadata_preserve(impl,
+ nir_metadata_block_index |
+ nir_metadata_dominance);
+
+ return true;
+}
+
+void
+vc4_nir_lower_txf_ms(struct vc4_compile *c)
+{
+ nir_foreach_overload(c->s, overload) {
+ if (overload->impl)
+ vc4_nir_lower_txf_ms_impl(c, overload->impl);
+ }
+}
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 197577b6c20..caad05cb9f7 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -115,8 +115,9 @@ nir_ssa_def *vc4_nir_get_state_uniform(struct nir_builder *b,
nir_intrinsic_instr *intr =
nir_intrinsic_instr_create(b->shader,
nir_intrinsic_load_uniform);
- intr->const_index[0] = VC4_NIR_STATE_UNIFORM_OFFSET + contents;
+ intr->const_index[0] = (VC4_NIR_STATE_UNIFORM_OFFSET + contents) * 4;
intr->num_components = 1;
+ intr->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
nir_ssa_dest_init(&intr->instr, &intr->dest, 1, NULL);
nir_builder_instr_insert(b, &intr->instr);
return &intr->dest.ssa;
@@ -294,6 +295,76 @@ ntq_umul(struct vc4_compile *c, struct qreg src0, struct qreg src1)
qir_uniform_ui(c, 24)));
}
+static struct qreg
+ntq_scale_depth_texture(struct vc4_compile *c, struct qreg src)
+{
+ struct qreg depthf = qir_ITOF(c, qir_SHR(c, src,
+ qir_uniform_ui(c, 8)));
+ return qir_FMUL(c, depthf, qir_uniform_f(c, 1.0f/0xffffff));
+}
+
+/**
+ * Emits a lowered TXF_MS from an MSAA texture.
+ *
+ * The addressing math has been lowered in NIR, and now we just need to read
+ * it like a UBO.
+ */
+static void
+ntq_emit_txf(struct vc4_compile *c, nir_tex_instr *instr)
+{
+ uint32_t tile_width = 32;
+ uint32_t tile_height = 32;
+ uint32_t tile_size = (tile_height * tile_width *
+ VC4_MAX_SAMPLES * sizeof(uint32_t));
+
+ unsigned unit = instr->sampler_index;
+ uint32_t w = align(c->key->tex[unit].msaa_width, tile_width);
+ uint32_t w_tiles = w / tile_width;
+ uint32_t h = align(c->key->tex[unit].msaa_height, tile_height);
+ uint32_t h_tiles = h / tile_height;
+ uint32_t size = w_tiles * h_tiles * tile_size;
+
+ struct qreg addr;
+ assert(instr->num_srcs == 1);
+ assert(instr->src[0].src_type == nir_tex_src_coord);
+ addr = ntq_get_src(c, instr->src[0].src, 0);
+
+ /* Perform the clamping required by kernel validation. */
+ addr = qir_MAX(c, addr, qir_uniform_ui(c, 0));
+ addr = qir_MIN(c, addr, qir_uniform_ui(c, size - 4));
+
+ qir_TEX_DIRECT(c, addr, qir_uniform(c, QUNIFORM_TEXTURE_MSAA_ADDR, unit));
+
+ struct qreg tex = qir_TEX_RESULT(c);
+ c->num_texture_samples++;
+
+ struct qreg texture_output[4];
+ enum pipe_format format = c->key->tex[unit].format;
+ if (util_format_is_depth_or_stencil(format)) {
+ struct qreg scaled = ntq_scale_depth_texture(c, tex);
+ for (int i = 0; i < 4; i++)
+ texture_output[i] = scaled;
+ } else {
+ struct qreg tex_result_unpacked[4];
+ for (int i = 0; i < 4; i++)
+ tex_result_unpacked[i] = qir_UNPACK_8_F(c, tex, i);
+
+ const uint8_t *format_swiz =
+ vc4_get_format_swizzle(c->key->tex[unit].format);
+ for (int i = 0; i < 4; i++) {
+ texture_output[i] =
+ get_swizzled_channel(c, tex_result_unpacked,
+ format_swiz[i]);
+ }
+ }
+
+ struct qreg *dest = ntq_get_dest(c, &instr->dest);
+ for (int i = 0; i < 4; i++) {
+ dest[i] = get_swizzled_channel(c, texture_output,
+ c->key->tex[unit].swizzle[i]);
+ }
+}
+
static void
ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr)
{
@@ -301,6 +372,11 @@ ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr)
bool is_txb = false, is_txl = false, has_proj = false;
unsigned unit = instr->sampler_index;
+ if (instr->op == nir_texop_txf) {
+ ntq_emit_txf(c, instr);
+ return;
+ }
+
for (unsigned i = 0; i < instr->num_srcs; i++) {
switch (instr->src[i].src_type) {
case nir_tex_src_coord:
@@ -396,11 +472,7 @@ ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr)
struct qreg unpacked[4];
if (util_format_is_depth_or_stencil(format)) {
- struct qreg depthf = qir_ITOF(c, qir_SHR(c, tex,
- qir_uniform_ui(c, 8)));
- struct qreg normalized = qir_FMUL(c, depthf,
- qir_uniform_f(c, 1.0f/0xffffff));
-
+ struct qreg normalized = ntq_scale_depth_texture(c, tex);
struct qreg depth_output;
struct qreg one = qir_uniform_f(c, 1.0f);
@@ -1109,6 +1181,10 @@ emit_frag_end(struct vc4_compile *c)
}
}
+ if (c->output_sample_mask_index != -1) {
+ qir_MS_MASK(c, c->outputs[c->output_sample_mask_index]);
+ }
+
if (c->fs_key->depth_enabled) {
struct qreg z;
if (c->output_position_index != -1) {
@@ -1120,7 +1196,12 @@ emit_frag_end(struct vc4_compile *c)
qir_TLB_Z_WRITE(c, z);
}
- qir_TLB_COLOR_WRITE(c, color);
+ if (!c->msaa_per_sample_output) {
+ qir_TLB_COLOR_WRITE(c, color);
+ } else {
+ for (int i = 0; i < VC4_MAX_SAMPLES; i++)
+ qir_TLB_COLOR_WRITE_MS(c, c->sample_colors[i]);
+ }
}
static void
@@ -1359,6 +1440,9 @@ ntq_setup_outputs(struct vc4_compile *c)
case FRAG_RESULT_DEPTH:
c->output_position_index = loc;
break;
+ case FRAG_RESULT_SAMPLE_MASK:
+ c->output_sample_mask_index = loc;
+ break;
}
} else {
switch (var->data.location) {
@@ -1433,6 +1517,8 @@ static void
ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
{
const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
+ nir_const_value *const_offset;
+ unsigned offset;
struct qreg *dest = NULL;
if (info->has_dest) {
@@ -1442,40 +1528,80 @@ ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
switch (instr->intrinsic) {
case nir_intrinsic_load_uniform:
assert(instr->num_components == 1);
- if (instr->const_index[0] < VC4_NIR_STATE_UNIFORM_OFFSET) {
- *dest = qir_uniform(c, QUNIFORM_UNIFORM,
- instr->const_index[0]);
+ const_offset = nir_src_as_const_value(instr->src[0]);
+ if (const_offset) {
+ offset = instr->const_index[0] + const_offset->u[0];
+ assert(offset % 4 == 0);
+ /* We need dwords */
+ offset = offset / 4;
+ if (offset < VC4_NIR_STATE_UNIFORM_OFFSET) {
+ *dest = qir_uniform(c, QUNIFORM_UNIFORM,
+ offset);
+ } else {
+ *dest = qir_uniform(c, offset -
+ VC4_NIR_STATE_UNIFORM_OFFSET,
+ 0);
+ }
} else {
- *dest = qir_uniform(c, instr->const_index[0] -
- VC4_NIR_STATE_UNIFORM_OFFSET,
- 0);
+ *dest = indirect_uniform_load(c, instr);
}
break;
- case nir_intrinsic_load_uniform_indirect:
- *dest = indirect_uniform_load(c, instr);
-
- break;
-
case nir_intrinsic_load_user_clip_plane:
*dest = qir_uniform(c, QUNIFORM_USER_CLIP_PLANE,
instr->const_index[0]);
break;
+ case nir_intrinsic_load_sample_mask_in:
+ *dest = qir_uniform(c, QUNIFORM_SAMPLE_MASK, 0);
+ break;
+
case nir_intrinsic_load_input:
assert(instr->num_components == 1);
- if (instr->const_index[0] == VC4_NIR_TLB_COLOR_READ_INPUT) {
- *dest = qir_TLB_COLOR_READ(c);
+ const_offset = nir_src_as_const_value(instr->src[0]);
+ assert(const_offset && "vc4 doesn't support indirect inputs");
+ if (instr->const_index[0] >= VC4_NIR_TLB_COLOR_READ_INPUT) {
+ assert(const_offset->u[0] == 0);
+ /* Reads of the per-sample color need to be done in
+ * order.
+ */
+ int sample_index = (instr->const_index[0] -
+ VC4_NIR_TLB_COLOR_READ_INPUT);
+ for (int i = 0; i <= sample_index; i++) {
+ if (c->color_reads[i].file == QFILE_NULL) {
+ c->color_reads[i] =
+ qir_TLB_COLOR_READ(c);
+ }
+ }
+ *dest = c->color_reads[sample_index];
} else {
- *dest = c->inputs[instr->const_index[0]];
+ offset = instr->const_index[0] + const_offset->u[0];
+ *dest = c->inputs[offset];
}
break;
case nir_intrinsic_store_output:
- assert(instr->num_components == 1);
- c->outputs[instr->const_index[0]] =
- qir_MOV(c, ntq_get_src(c, instr->src[0], 0));
- c->num_outputs = MAX2(c->num_outputs, instr->const_index[0] + 1);
+ const_offset = nir_src_as_const_value(instr->src[1]);
+ assert(const_offset && "vc4 doesn't support indirect outputs");
+ offset = instr->const_index[0] + const_offset->u[0];
+
+ /* MSAA color outputs are the only case where we have an
+ * output that's not lowered to being a store of a single 32
+ * bit value.
+ */
+ if (c->stage == QSTAGE_FRAG && instr->num_components == 4) {
+ assert(offset == c->output_color_index);
+ for (int i = 0; i < 4; i++) {
+ c->sample_colors[i] =
+ qir_MOV(c, ntq_get_src(c, instr->src[0],
+ i));
+ }
+ } else {
+ assert(instr->num_components == 1);
+ c->outputs[offset] =
+ qir_MOV(c, ntq_get_src(c, instr->src[0], 0));
+ c->num_outputs = MAX2(c->num_outputs, offset + 1);
+ }
break;
case nir_intrinsic_discard:
@@ -1672,6 +1798,7 @@ vc4_shader_ntq(struct vc4_context *vc4, enum qstage stage,
nir_lower_clip_vs(c->s, c->key->ucp_enables);
vc4_nir_lower_io(c);
+ vc4_nir_lower_txf_ms(c);
nir_lower_idiv(c->s);
nir_lower_load_const_to_scalar(c->s);
@@ -1907,12 +2034,19 @@ vc4_setup_shared_key(struct vc4_context *vc4, struct vc4_key *key,
struct pipe_sampler_state *sampler_state =
texstate->samplers[i];
- if (sampler) {
- key->tex[i].format = sampler->format;
- key->tex[i].swizzle[0] = sampler->swizzle_r;
- key->tex[i].swizzle[1] = sampler->swizzle_g;
- key->tex[i].swizzle[2] = sampler->swizzle_b;
- key->tex[i].swizzle[3] = sampler->swizzle_a;
+ if (!sampler)
+ continue;
+
+ key->tex[i].format = sampler->format;
+ key->tex[i].swizzle[0] = sampler->swizzle_r;
+ key->tex[i].swizzle[1] = sampler->swizzle_g;
+ key->tex[i].swizzle[2] = sampler->swizzle_b;
+ key->tex[i].swizzle[3] = sampler->swizzle_a;
+
+ if (sampler->texture->nr_samples) {
+ key->tex[i].msaa_width = sampler->texture->width0;
+ key->tex[i].msaa_height = sampler->texture->height0;
+ } else if (sampler){
key->tex[i].compare_mode = sampler_state->compare_mode;
key->tex[i].compare_func = sampler_state->compare_func;
key->tex[i].wrap_s = sampler_state->wrap_s;
@@ -1952,6 +2086,11 @@ vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
} else {
key->logicop_func = PIPE_LOGICOP_COPY;
}
+ key->msaa = vc4->rasterizer->base.multisample;
+ key->sample_coverage = (vc4->rasterizer->base.multisample &&
+ vc4->sample_mask != (1 << VC4_MAX_SAMPLES) - 1);
+ key->sample_alpha_to_coverage = vc4->blend->alpha_to_coverage;
+ key->sample_alpha_to_one = vc4->blend->alpha_to_one;
if (vc4->framebuffer.cbufs[0])
key->color_format = vc4->framebuffer.cbufs[0]->format;
diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c
index f2855e159fc..4ec25310b67 100644
--- a/src/gallium/drivers/vc4/vc4_qir.c
+++ b/src/gallium/drivers/vc4/vc4_qir.c
@@ -86,7 +86,9 @@ static const struct qir_op_info qir_op_info[] = {
[QOP_TLB_STENCIL_SETUP] = { "tlb_stencil_setup", 0, 1, true },
[QOP_TLB_Z_WRITE] = { "tlb_z", 0, 1, true },
[QOP_TLB_COLOR_WRITE] = { "tlb_color", 0, 1, true },
+ [QOP_TLB_COLOR_WRITE_MS] = { "tlb_color_ms", 0, 1, true },
[QOP_TLB_COLOR_READ] = { "tlb_color_read", 1, 0 },
+ [QOP_MS_MASK] = { "ms_mask", 0, 1, true },
[QOP_VARY_ADD_C] = { "vary_add_c", 1, 1 },
[QOP_FRAG_X] = { "frag_x", 1, 0 },
@@ -399,6 +401,7 @@ qir_compile_init(void)
c->output_position_index = -1;
c->output_color_index = -1;
c->output_point_size_index = -1;
+ c->output_sample_mask_index = -1;
c->def_ht = _mesa_hash_table_create(c, _mesa_hash_pointer,
_mesa_key_pointer_equal);
diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h
index ddb35e41fcf..b875760a2ca 100644
--- a/src/gallium/drivers/vc4/vc4_qir.h
+++ b/src/gallium/drivers/vc4/vc4_qir.h
@@ -38,6 +38,7 @@
#include "vc4_screen.h"
#include "vc4_qpu_defines.h"
+#include "kernel/vc4_packet.h"
#include "pipe/p_state.h"
struct nir_builder;
@@ -121,7 +122,9 @@ enum qop {
QOP_TLB_STENCIL_SETUP,
QOP_TLB_Z_WRITE,
QOP_TLB_COLOR_WRITE,
+ QOP_TLB_COLOR_WRITE_MS,
QOP_TLB_COLOR_READ,
+ QOP_MS_MASK,
QOP_VARY_ADD_C,
QOP_FRAG_X,
@@ -230,6 +233,8 @@ enum quniform_contents {
/** A reference to a texture config parameter 2 cubemap stride uniform */
QUNIFORM_TEXTURE_CONFIG_P2,
+ QUNIFORM_TEXTURE_MSAA_ADDR,
+
QUNIFORM_UBO_ADDR,
QUNIFORM_TEXRECT_SCALE_X,
@@ -247,6 +252,7 @@ enum quniform_contents {
QUNIFORM_STENCIL,
QUNIFORM_ALPHA_REF,
+ QUNIFORM_SAMPLE_MASK,
};
struct vc4_varying_slot {
@@ -283,11 +289,18 @@ struct vc4_key {
struct vc4_uncompiled_shader *shader_state;
struct {
enum pipe_format format;
- unsigned compare_mode:1;
- unsigned compare_func:3;
- unsigned wrap_s:3;
- unsigned wrap_t:3;
uint8_t swizzle[4];
+ 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;
+ };
+ };
} tex[VC4_MAX_TEXTURE_SAMPLERS];
uint8_t ucp_enables;
};
@@ -304,6 +317,10 @@ struct vc4_fs_key {
bool alpha_test;
bool point_coord_upper_left;
bool light_twoside;
+ bool msaa;
+ bool sample_coverage;
+ bool sample_alpha_to_coverage;
+ bool sample_alpha_to_one;
uint8_t alpha_test_func;
uint8_t logicop_func;
uint32_t point_sprite_mask;
@@ -348,6 +365,9 @@ struct vc4_compile {
*/
struct qreg *inputs;
struct qreg *outputs;
+ bool msaa_per_sample_output;
+ struct qreg color_reads[VC4_MAX_SAMPLES];
+ struct qreg sample_colors[VC4_MAX_SAMPLES];
uint32_t inputs_array_size;
uint32_t outputs_array_size;
uint32_t uniforms_array_size;
@@ -396,6 +416,7 @@ struct vc4_compile {
uint32_t output_position_index;
uint32_t output_color_index;
uint32_t output_point_size_index;
+ uint32_t output_sample_mask_index;
struct qreg undef;
enum qstage stage;
@@ -418,10 +439,12 @@ struct vc4_compile {
*/
#define VC4_NIR_TLB_COLOR_READ_INPUT 2000000000
+#define VC4_NIR_MS_MASK_OUTPUT 2000000000
+
/* Special offset for nir_load_uniform values to get a QUNIFORM_*
* state-dependent value.
*/
-#define VC4_NIR_STATE_UNIFORM_OFFSET 2000000000
+#define VC4_NIR_STATE_UNIFORM_OFFSET 1000000000
struct vc4_compile *qir_compile_init(void);
void qir_compile_destroy(struct vc4_compile *c);
@@ -476,6 +499,7 @@ nir_ssa_def *vc4_nir_get_state_uniform(struct nir_builder *b,
enum quniform_contents contents);
nir_ssa_def *vc4_nir_get_swizzled_channel(struct nir_builder *b,
nir_ssa_def **srcs, int swiz);
+void vc4_nir_lower_txf_ms(struct vc4_compile *c);
void qir_lower_uniforms(struct vc4_compile *c);
void qpu_schedule_instructions(struct vc4_compile *c);
@@ -616,9 +640,11 @@ QIR_ALU0(FRAG_REV_FLAG)
QIR_ALU0(TEX_RESULT)
QIR_ALU0(TLB_COLOR_READ)
QIR_NODST_1(TLB_COLOR_WRITE)
+QIR_NODST_1(TLB_COLOR_WRITE_MS)
QIR_NODST_1(TLB_Z_WRITE)
QIR_NODST_1(TLB_DISCARD_SETUP)
QIR_NODST_1(TLB_STENCIL_SETUP)
+QIR_NODST_1(MS_MASK)
static inline struct qreg
qir_UNPACK_8_F(struct vc4_compile *c, struct qreg src, int i)
diff --git a/src/gallium/drivers/vc4/vc4_qpu.h b/src/gallium/drivers/vc4/vc4_qpu.h
index 866ca5c1300..7c4ff1701ca 100644
--- a/src/gallium/drivers/vc4/vc4_qpu.h
+++ b/src/gallium/drivers/vc4/vc4_qpu.h
@@ -116,6 +116,17 @@ qpu_tlbc()
return r;
}
+static inline struct qpu_reg
+qpu_tlbc_ms()
+{
+ struct qpu_reg r = {
+ QPU_MUX_A,
+ QPU_W_TLB_COLOR_MS,
+ };
+
+ return r;
+}
+
static inline struct qpu_reg qpu_r0(void) { return qpu_rn(0); }
static inline struct qpu_reg qpu_r1(void) { return qpu_rn(1); }
static inline struct qpu_reg qpu_r2(void) { return qpu_rn(2); }
diff --git a/src/gallium/drivers/vc4/vc4_qpu_emit.c b/src/gallium/drivers/vc4/vc4_qpu_emit.c
index e0d3633da42..5800e520068 100644
--- a/src/gallium/drivers/vc4/vc4_qpu_emit.c
+++ b/src/gallium/drivers/vc4/vc4_qpu_emit.c
@@ -387,6 +387,14 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
qpu_rb(QPU_R_MS_REV_FLAGS)));
break;
+ case QOP_MS_MASK:
+ src[1] = qpu_ra(QPU_R_MS_REV_FLAGS);
+ fixup_raddr_conflict(c, dst, &src[0], &src[1],
+ qinst, &unpack);
+ queue(c, qpu_a_AND(qpu_ra(QPU_W_MS_FLAGS),
+ src[0], src[1]) | unpack);
+ break;
+
case QOP_FRAG_Z:
case QOP_FRAG_W:
/* QOP_FRAG_Z/W don't emit instructions, just allocate
@@ -430,6 +438,13 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
}
break;
+ case QOP_TLB_COLOR_WRITE_MS:
+ queue(c, qpu_a_MOV(qpu_tlbc_ms(), src[0]));
+ if (discard) {
+ set_last_cond_add(c, QPU_COND_ZS);
+ }
+ break;
+
case QOP_VARY_ADD_C:
queue(c, qpu_a_FADD(dst, src[0], qpu_r5()) | unpack);
break;
diff --git a/src/gallium/drivers/vc4/vc4_qpu_schedule.c b/src/gallium/drivers/vc4/vc4_qpu_schedule.c
index 19cbf7bb98c..94303d942ec 100644
--- a/src/gallium/drivers/vc4/vc4_qpu_schedule.c
+++ b/src/gallium/drivers/vc4/vc4_qpu_schedule.c
@@ -295,6 +295,10 @@ process_waddr_deps(struct schedule_state *state, struct schedule_node *n,
add_write_dep(state, &state->last_tlb, n);
break;
+ case QPU_W_MS_FLAGS:
+ add_write_dep(state, &state->last_tlb, n);
+ break;
+
case QPU_W_NOP:
break;
diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
index bb723845531..e7069a4e9ff 100644
--- a/src/gallium/drivers/vc4/vc4_resource.c
+++ b/src/gallium/drivers/vc4/vc4_resource.c
@@ -22,6 +22,7 @@
* IN THE SOFTWARE.
*/
+#include "util/u_blit.h"
#include "util/u_memory.h"
#include "util/u_format.h"
#include "util/u_inlines.h"
@@ -72,11 +73,18 @@ vc4_resource_transfer_unmap(struct pipe_context *pctx,
{
struct vc4_context *vc4 = vc4_context(pctx);
struct vc4_transfer *trans = vc4_transfer(ptrans);
- struct pipe_resource *prsc = ptrans->resource;
- struct vc4_resource *rsc = vc4_resource(prsc);
- struct vc4_resource_slice *slice = &rsc->slices[ptrans->level];
if (trans->map) {
+ struct vc4_resource *rsc;
+ struct vc4_resource_slice *slice;
+ if (trans->ss_resource) {
+ rsc = vc4_resource(trans->ss_resource);
+ slice = &rsc->slices[0];
+ } else {
+ rsc = vc4_resource(ptrans->resource);
+ slice = &rsc->slices[ptrans->level];
+ }
+
if (ptrans->usage & PIPE_TRANSFER_WRITE) {
vc4_store_tiled_image(rsc->bo->map + slice->offset +
ptrans->box.z * rsc->cube_map_stride,
@@ -88,10 +96,52 @@ vc4_resource_transfer_unmap(struct pipe_context *pctx,
free(trans->map);
}
+ if (trans->ss_resource && (ptrans->usage & PIPE_TRANSFER_WRITE)) {
+ struct pipe_blit_info blit;
+ memset(&blit, 0, sizeof(blit));
+
+ blit.src.resource = trans->ss_resource;
+ blit.src.format = trans->ss_resource->format;
+ blit.src.box.width = trans->ss_box.width;
+ blit.src.box.height = trans->ss_box.height;
+ blit.src.box.depth = 1;
+
+ blit.dst.resource = ptrans->resource;
+ blit.dst.format = ptrans->resource->format;
+ blit.dst.level = ptrans->level;
+ blit.dst.box = trans->ss_box;
+
+ blit.mask = util_format_get_mask(ptrans->resource->format);
+ blit.filter = PIPE_TEX_FILTER_NEAREST;
+
+ pctx->blit(pctx, &blit);
+ vc4_flush(pctx);
+
+ pipe_resource_reference(&trans->ss_resource, NULL);
+ }
+
pipe_resource_reference(&ptrans->resource, NULL);
util_slab_free(&vc4->transfer_pool, ptrans);
}
+static struct pipe_resource *
+vc4_get_temp_resource(struct pipe_context *pctx,
+ struct pipe_resource *prsc,
+ const struct pipe_box *box)
+{
+ struct pipe_resource temp_setup;
+
+ memset(&temp_setup, 0, sizeof(temp_setup));
+ temp_setup.target = prsc->target;
+ temp_setup.format = prsc->format;
+ temp_setup.width0 = box->width;
+ temp_setup.height0 = box->height;
+ temp_setup.depth0 = 1;
+ temp_setup.array_size = 1;
+
+ return pctx->screen->resource_create(pctx->screen, &temp_setup);
+}
+
static void *
vc4_resource_transfer_map(struct pipe_context *pctx,
struct pipe_resource *prsc,
@@ -101,7 +151,6 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
{
struct vc4_context *vc4 = vc4_context(pctx);
struct vc4_resource *rsc = vc4_resource(prsc);
- struct vc4_resource_slice *slice = &rsc->slices[level];
struct vc4_transfer *trans;
struct pipe_transfer *ptrans;
enum pipe_format format = prsc->format;
@@ -155,6 +204,50 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
ptrans->usage = usage;
ptrans->box = *box;
+ /* If the resource is multisampled, we need to resolve to single
+ * sample. This seems like it should be handled at a higher layer.
+ */
+ if (prsc->nr_samples) {
+ trans->ss_resource = vc4_get_temp_resource(pctx, prsc, box);
+ if (!trans->ss_resource)
+ goto fail;
+ assert(!trans->ss_resource->nr_samples);
+
+ /* The ptrans->box gets modified for tile alignment, so save
+ * the original box for unmap time.
+ */
+ trans->ss_box = *box;
+
+ if (usage & PIPE_TRANSFER_READ) {
+ struct pipe_blit_info blit;
+ memset(&blit, 0, sizeof(blit));
+
+ blit.src.resource = ptrans->resource;
+ blit.src.format = ptrans->resource->format;
+ blit.src.level = ptrans->level;
+ blit.src.box = trans->ss_box;
+
+ blit.dst.resource = trans->ss_resource;
+ blit.dst.format = trans->ss_resource->format;
+ blit.dst.box.width = trans->ss_box.width;
+ blit.dst.box.height = trans->ss_box.height;
+ blit.dst.box.depth = 1;
+
+ blit.mask = util_format_get_mask(prsc->format);
+ blit.filter = PIPE_TEX_FILTER_NEAREST;
+
+ pctx->blit(pctx, &blit);
+ vc4_flush(pctx);
+ }
+
+ /* The rest of the mapping process should use our temporary. */
+ prsc = trans->ss_resource;
+ rsc = vc4_resource(prsc);
+ ptrans->box.x = 0;
+ ptrans->box.y = 0;
+ ptrans->box.z = 0;
+ }
+
/* Note that the current kernel implementation is synchronous, so no
* need to do syncing stuff here yet.
*/
@@ -170,6 +263,7 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
*pptrans = ptrans;
+ struct vc4_resource_slice *slice = &rsc->slices[level];
if (rsc->tiled) {
uint32_t utile_w = vc4_utile_width(rsc->cpp);
uint32_t utile_h = vc4_utile_height(rsc->cpp);
@@ -203,7 +297,7 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
ptrans->box.height != orig_height) {
vc4_load_tiled_image(trans->map, ptrans->stride,
buf + slice->offset +
- box->z * rsc->cube_map_stride,
+ ptrans->box.z * rsc->cube_map_stride,
slice->stride,
slice->tiling, rsc->cpp,
&ptrans->box);
@@ -216,9 +310,9 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
ptrans->layer_stride = ptrans->stride;
return buf + slice->offset +
- box->y / util_format_get_blockheight(format) * ptrans->stride +
- box->x / util_format_get_blockwidth(format) * rsc->cpp +
- box->z * rsc->cube_map_stride;
+ ptrans->box.y / util_format_get_blockheight(format) * ptrans->stride +
+ ptrans->box.x / util_format_get_blockwidth(format) * rsc->cpp +
+ ptrans->box.z * rsc->cube_map_stride;
}
@@ -283,7 +377,13 @@ vc4_setup_slices(struct vc4_resource *rsc)
if (!rsc->tiled) {
slice->tiling = VC4_TILING_FORMAT_LINEAR;
- level_width = align(level_width, utile_w);
+ if (prsc->nr_samples) {
+ /* MSAA (4x) surfaces are stored as raw tile buffer contents. */
+ level_width = align(level_width, 32);
+ level_height = align(level_height, 32);
+ } else {
+ level_width = align(level_width, utile_w);
+ }
} else {
if (vc4_size_is_lt(level_width, level_height,
rsc->cpp)) {
@@ -300,7 +400,8 @@ vc4_setup_slices(struct vc4_resource *rsc)
}
slice->offset = offset;
- slice->stride = level_width * rsc->cpp;
+ slice->stride = (level_width * rsc->cpp *
+ MAX2(prsc->nr_samples, 1));
slice->size = level_height * slice->stride;
offset += slice->size;
@@ -357,7 +458,10 @@ vc4_resource_setup(struct pipe_screen *pscreen,
prsc->screen = pscreen;
rsc->base.vtbl = &vc4_resource_vtbl;
- rsc->cpp = util_format_get_blocksize(tmpl->format);
+ if (prsc->nr_samples == 0)
+ rsc->cpp = util_format_get_blocksize(tmpl->format);
+ else
+ rsc->cpp = sizeof(uint32_t);
assert(rsc->cpp);
@@ -371,8 +475,12 @@ get_resource_texture_format(struct pipe_resource *prsc)
uint8_t format = vc4_get_tex_format(prsc->format);
if (!rsc->tiled) {
- assert(format == VC4_TEXTURE_TYPE_RGBA8888);
- return VC4_TEXTURE_TYPE_RGBA32R;
+ if (prsc->nr_samples) {
+ return ~0;
+ } else {
+ assert(format == VC4_TEXTURE_TYPE_RGBA8888);
+ return VC4_TEXTURE_TYPE_RGBA32R;
+ }
}
return format;
@@ -389,6 +497,7 @@ vc4_resource_create(struct pipe_screen *pscreen,
* communicate metadata about tiling currently.
*/
if (tmpl->target == PIPE_BUFFER ||
+ tmpl->nr_samples ||
(tmpl->bind & (PIPE_BIND_SCANOUT |
PIPE_BIND_LINEAR |
PIPE_BIND_SHARED |
@@ -492,13 +601,9 @@ vc4_surface_destroy(struct pipe_context *pctx, struct pipe_surface *psurf)
FREE(psurf);
}
-/** Debug routine to dump the contents of an 8888 surface to the console */
-void
-vc4_dump_surface(struct pipe_surface *psurf)
+static void
+vc4_dump_surface_non_msaa(struct pipe_surface *psurf)
{
- if (!psurf)
- return;
-
struct pipe_resource *prsc = psurf->texture;
struct vc4_resource *rsc = vc4_resource(prsc);
uint32_t *map = vc4_bo_map(rsc->bo);
@@ -592,6 +697,147 @@ vc4_dump_surface(struct pipe_surface *psurf)
}
}
+static uint32_t
+vc4_surface_msaa_get_sample(struct pipe_surface *psurf,
+ uint32_t x, uint32_t y, uint32_t sample)
+{
+ struct pipe_resource *prsc = psurf->texture;
+ struct vc4_resource *rsc = vc4_resource(prsc);
+ uint32_t tile_w = 32, tile_h = 32;
+ uint32_t tiles_w = DIV_ROUND_UP(psurf->width, 32);
+
+ uint32_t tile_x = x / tile_w;
+ uint32_t tile_y = y / tile_h;
+ uint32_t *tile = (vc4_bo_map(rsc->bo) +
+ VC4_TILE_BUFFER_SIZE * (tile_y * tiles_w + tile_x));
+ uint32_t subtile_x = x % tile_w;
+ uint32_t subtile_y = y % tile_h;
+
+ uint32_t quad_samples = VC4_MAX_SAMPLES * 4;
+ uint32_t tile_stride = quad_samples * tile_w / 2;
+
+ return *((uint32_t *)tile +
+ (subtile_y >> 1) * tile_stride +
+ (subtile_x >> 1) * quad_samples +
+ ((subtile_y & 1) << 1) +
+ (subtile_x & 1) +
+ sample);
+}
+
+static void
+vc4_dump_surface_msaa_char(struct pipe_surface *psurf,
+ uint32_t start_x, uint32_t start_y,
+ uint32_t w, uint32_t h)
+{
+ bool all_same_color = true;
+ uint32_t all_pix = 0;
+
+ for (int y = start_y; y < start_y + h; y++) {
+ for (int x = start_x; x < start_x + w; x++) {
+ for (int s = 0; s < VC4_MAX_SAMPLES; s++) {
+ uint32_t pix = vc4_surface_msaa_get_sample(psurf,
+ x, y,
+ s);
+ if (x == start_x && y == start_y)
+ all_pix = pix;
+ else if (all_pix != pix)
+ all_same_color = false;
+ }
+ }
+ }
+ if (all_same_color) {
+ static const struct {
+ uint32_t val;
+ const char *c;
+ } named_colors[] = {
+ { 0xff000000, "█" },
+ { 0x00000000, "█" },
+ { 0xffff0000, "r" },
+ { 0xff00ff00, "g" },
+ { 0xff0000ff, "b" },
+ { 0xffffffff, "w" },
+ };
+ int i;
+ for (i = 0; i < ARRAY_SIZE(named_colors); i++) {
+ if (named_colors[i].val == all_pix) {
+ fprintf(stderr, "%s",
+ named_colors[i].c);
+ return;
+ }
+ }
+ fprintf(stderr, "x");
+ } else {
+ fprintf(stderr, ".");
+ }
+}
+
+static void
+vc4_dump_surface_msaa(struct pipe_surface *psurf)
+{
+ uint32_t tile_w = 32, tile_h = 32;
+ uint32_t tiles_w = DIV_ROUND_UP(psurf->width, tile_w);
+ uint32_t tiles_h = DIV_ROUND_UP(psurf->height, tile_h);
+ uint32_t char_w = 140, char_h = 60;
+ uint32_t char_w_per_tile = char_w / tiles_w - 1;
+ uint32_t char_h_per_tile = char_h / tiles_h - 1;
+ uint32_t found_colors[10];
+ uint32_t num_found_colors = 0;
+
+ fprintf(stderr, "Surface: %dx%d (%dx MSAA)\n",
+ psurf->width, psurf->height, psurf->texture->nr_samples);
+
+ for (int x = 0; x < (char_w_per_tile + 1) * tiles_w; x++)
+ fprintf(stderr, "-");
+ fprintf(stderr, "\n");
+
+ for (int ty = 0; ty < psurf->height; ty += tile_h) {
+ for (int y = 0; y < char_h_per_tile; y++) {
+
+ for (int tx = 0; tx < psurf->width; tx += tile_w) {
+ for (int x = 0; x < char_w_per_tile; x++) {
+ uint32_t bx1 = (x * tile_w /
+ char_w_per_tile);
+ uint32_t bx2 = ((x + 1) * tile_w /
+ char_w_per_tile);
+ uint32_t by1 = (y * tile_h /
+ char_h_per_tile);
+ uint32_t by2 = ((y + 1) * tile_h /
+ char_h_per_tile);
+
+ vc4_dump_surface_msaa_char(psurf,
+ tx + bx1,
+ ty + by1,
+ bx2 - bx1,
+ by2 - by1);
+ }
+ fprintf(stderr, "|");
+ }
+ fprintf(stderr, "\n");
+ }
+
+ for (int x = 0; x < (char_w_per_tile + 1) * tiles_w; x++)
+ fprintf(stderr, "-");
+ fprintf(stderr, "\n");
+ }
+
+ for (int i = 0; i < num_found_colors; i++) {
+ fprintf(stderr, "color %d: 0x%08x\n", i, found_colors[i]);
+ }
+}
+
+/** Debug routine to dump the contents of an 8888 surface to the console */
+void
+vc4_dump_surface(struct pipe_surface *psurf)
+{
+ if (!psurf)
+ return;
+
+ if (psurf->texture->nr_samples)
+ vc4_dump_surface_msaa(psurf);
+ else
+ vc4_dump_surface_non_msaa(psurf);
+}
+
static void
vc4_flush_resource(struct pipe_context *pctx, struct pipe_resource *resource)
{
diff --git a/src/gallium/drivers/vc4/vc4_resource.h b/src/gallium/drivers/vc4/vc4_resource.h
index 87571b75e8b..b275050da20 100644
--- a/src/gallium/drivers/vc4/vc4_resource.h
+++ b/src/gallium/drivers/vc4/vc4_resource.h
@@ -32,6 +32,9 @@
struct vc4_transfer {
struct pipe_transfer base;
void *map;
+
+ struct pipe_resource *ss_resource;
+ struct pipe_box ss_box;
};
struct vc4_resource_slice {
diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
index 88ee48c0e8f..090579c2c76 100644
--- a/src/gallium/drivers/vc4/vc4_screen.c
+++ b/src/gallium/drivers/vc4/vc4_screen.c
@@ -95,6 +95,7 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
case PIPE_CAP_TWO_SIDED_STENCIL:
case PIPE_CAP_USER_INDEX_BUFFERS:
+ case PIPE_CAP_TEXTURE_MULTISAMPLE:
return 1;
/* lying for GL 2.0 */
@@ -140,7 +141,6 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
case PIPE_CAP_CONDITIONAL_RENDER:
case PIPE_CAP_PRIMITIVE_RESTART:
- case PIPE_CAP_TEXTURE_MULTISAMPLE:
case PIPE_CAP_TEXTURE_BARRIER:
case PIPE_CAP_SM3:
case PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -358,7 +358,6 @@ vc4_screen_is_format_supported(struct pipe_screen *pscreen,
unsigned retval = 0;
if ((target >= PIPE_MAX_TEXTURE_TYPES) ||
- (sample_count > 1) ||
!util_format_is_supported(format, usage)) {
return FALSE;
}
@@ -417,11 +416,13 @@ vc4_screen_is_format_supported(struct pipe_screen *pscreen,
}
if ((usage & PIPE_BIND_RENDER_TARGET) &&
+ (sample_count == 0 || sample_count == VC4_MAX_SAMPLES) &&
vc4_rt_format_supported(format)) {
retval |= PIPE_BIND_RENDER_TARGET;
}
if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
+ (sample_count == 0 || sample_count == VC4_MAX_SAMPLES) &&
(vc4_tex_format_supported(format))) {
retval |= PIPE_BIND_SAMPLER_VIEW;
}
diff --git a/src/gallium/drivers/vc4/vc4_simulator.c b/src/gallium/drivers/vc4/vc4_simulator.c
index 10dabd09f5e..4b1df9234b6 100644
--- a/src/gallium/drivers/vc4/vc4_simulator.c
+++ b/src/gallium/drivers/vc4/vc4_simulator.c
@@ -177,6 +177,12 @@ vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args)
if (ret)
return ret;
+ if (vc4_debug & VC4_DEBUG_CL) {
+ fprintf(stderr, "RCL:\n");
+ vc4_dump_cl(screen->simulator_mem_base + exec.ct1ca,
+ exec.ct1ea - exec.ct1ca, true);
+ }
+
if (exec.ct0ca != exec.ct0ea) {
int bfc = simpenrose_do_binning(exec.ct0ca, exec.ct0ea);
if (bfc != 1) {
diff --git a/src/gallium/drivers/vc4/vc4_simulator_validate.h b/src/gallium/drivers/vc4/vc4_simulator_validate.h
index 68ace0216aa..40d3ada6ca2 100644
--- a/src/gallium/drivers/vc4/vc4_simulator_validate.h
+++ b/src/gallium/drivers/vc4/vc4_simulator_validate.h
@@ -65,7 +65,7 @@ struct drm_device {
};
struct drm_gem_object {
- uint32_t size;
+ size_t size;
struct drm_device *dev;
};
diff --git a/src/gallium/drivers/vc4/vc4_state.c b/src/gallium/drivers/vc4/vc4_state.c
index a234ce53b20..d9c0f55b23d 100644
--- a/src/gallium/drivers/vc4/vc4_state.c
+++ b/src/gallium/drivers/vc4/vc4_state.c
@@ -79,7 +79,7 @@ static void
vc4_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
{
struct vc4_context *vc4 = vc4_context(pctx);
- vc4->sample_mask = (uint16_t)sample_mask;
+ vc4->sample_mask = sample_mask & ((1 << VC4_MAX_SAMPLES) - 1);
vc4->dirty |= VC4_DIRTY_SAMPLE_MASK;
}
@@ -121,6 +121,9 @@ vc4_create_rasterizer_state(struct pipe_context *pctx,
so->offset_factor = float_to_187_half(cso->offset_scale);
}
+ if (cso->multisample)
+ so->config_bits[0] |= VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X;
+
return so;
}
@@ -457,6 +460,22 @@ vc4_set_framebuffer_state(struct pipe_context *pctx,
rsc->cpp);
}
+ vc4->msaa = false;
+ if (cso->cbufs[0])
+ vc4->msaa = cso->cbufs[0]->texture->nr_samples != 0;
+ else if (cso->zsbuf)
+ vc4->msaa = cso->zsbuf->texture->nr_samples != 0;
+
+ if (vc4->msaa) {
+ vc4->tile_width = 32;
+ vc4->tile_height = 32;
+ } else {
+ vc4->tile_width = 64;
+ vc4->tile_height = 64;
+ }
+ vc4->draw_tiles_x = DIV_ROUND_UP(cso->width, vc4->tile_width);
+ vc4->draw_tiles_y = DIV_ROUND_UP(cso->height, vc4->tile_height);
+
vc4->dirty |= VC4_DIRTY_FRAMEBUFFER;
}
diff --git a/src/gallium/drivers/vc4/vc4_uniforms.c b/src/gallium/drivers/vc4/vc4_uniforms.c
index f5ad481f186..262531f1bd7 100644
--- a/src/gallium/drivers/vc4/vc4_uniforms.c
+++ b/src/gallium/drivers/vc4/vc4_uniforms.c
@@ -71,6 +71,18 @@ write_texture_p2(struct vc4_context *vc4,
VC4_SET_FIELD((data >> 16) & 1, VC4_TEX_P2_BSLOD));
}
+static void
+write_texture_msaa_addr(struct vc4_context *vc4,
+ struct vc4_cl_out **uniforms,
+ struct vc4_texture_stateobj *texstate,
+ uint32_t unit)
+{
+ struct pipe_sampler_view *texture = texstate->textures[unit];
+ struct vc4_resource *rsc = vc4_resource(texture->texture);
+
+ cl_aligned_reloc(vc4, &vc4->uniforms, uniforms, rsc->bo, 0);
+}
+
#define SWIZ(x,y,z,w) { \
UTIL_FORMAT_SWIZZLE_##x, \
@@ -244,6 +256,11 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
cl_aligned_reloc(vc4, &vc4->uniforms, &uniforms, ubo, 0);
break;
+ case QUNIFORM_TEXTURE_MSAA_ADDR:
+ write_texture_msaa_addr(vc4, &uniforms,
+ texstate, uinfo->data[i]);
+ break;
+
case QUNIFORM_TEXTURE_BORDER_COLOR:
write_texture_border_color(vc4, &uniforms,
texstate, uinfo->data[i]);
@@ -303,6 +320,10 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
cl_aligned_f(&uniforms,
vc4->zsa->base.alpha.ref_value);
break;
+
+ case QUNIFORM_SAMPLE_MASK:
+ cl_aligned_u32(&uniforms, vc4->sample_mask);
+ break;
}
#if 0
uint32_t written_val = *((uint32_t *)uniforms - 1);
@@ -345,6 +366,7 @@ vc4_set_shader_uniform_dirty_flags(struct vc4_compiled_shader *shader)
case QUNIFORM_TEXTURE_CONFIG_P1:
case QUNIFORM_TEXTURE_CONFIG_P2:
case QUNIFORM_TEXTURE_BORDER_COLOR:
+ case QUNIFORM_TEXTURE_MSAA_ADDR:
case QUNIFORM_TEXRECT_SCALE_X:
case QUNIFORM_TEXRECT_SCALE_Y:
dirty |= VC4_DIRTY_TEXSTATE;
@@ -363,6 +385,10 @@ vc4_set_shader_uniform_dirty_flags(struct vc4_compiled_shader *shader)
case QUNIFORM_ALPHA_REF:
dirty |= VC4_DIRTY_ZSA;
break;
+
+ case QUNIFORM_SAMPLE_MASK:
+ dirty |= VC4_DIRTY_SAMPLE_MASK;
+ break;
}
}
diff --git a/src/gallium/drivers/virgl/virgl_buffer.c b/src/gallium/drivers/virgl/virgl_buffer.c
index ce19fb949d0..94034072439 100644
--- a/src/gallium/drivers/virgl/virgl_buffer.c
+++ b/src/gallium/drivers/virgl/virgl_buffer.c
@@ -63,7 +63,7 @@ static void *virgl_buffer_transfer_map(struct pipe_context *ctx,
ctx->flush(ctx, NULL, 0);
trans = util_slab_alloc(&vctx->texture_transfer_pool);
- if (trans == NULL)
+ if (!trans)
return NULL;
trans->base.resource = resource;
diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c
index e4f02ba1096..527f7637cb6 100644
--- a/src/gallium/drivers/virgl/virgl_context.c
+++ b/src/gallium/drivers/virgl/virgl_context.c
@@ -198,7 +198,7 @@ static struct pipe_surface *virgl_create_surface(struct pipe_context *ctx,
uint32_t handle;
surf = CALLOC_STRUCT(virgl_surface);
- if (surf == NULL)
+ if (!surf)
return NULL;
res->clean = FALSE;
@@ -669,7 +669,7 @@ static struct pipe_sampler_view *virgl_create_sampler_view(struct pipe_context *
uint32_t handle;
struct virgl_resource *res;
- if (state == NULL)
+ if (!state)
return NULL;
grview = CALLOC_STRUCT(virgl_sampler_view);
diff --git a/src/gallium/drivers/virgl/virgl_texture.c b/src/gallium/drivers/virgl/virgl_texture.c
index 31189626144..f395f1f4a66 100644
--- a/src/gallium/drivers/virgl/virgl_texture.c
+++ b/src/gallium/drivers/virgl/virgl_texture.c
@@ -146,7 +146,7 @@ static void *virgl_texture_transfer_map(struct pipe_context *ctx,
ctx->flush(ctx, NULL, 0);
trans = util_slab_alloc(&vctx->texture_transfer_pool);
- if (trans == NULL)
+ if (!trans)
return NULL;
trans->base.resource = resource;
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index 7eed57018b7..c48a55e22fc 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -132,7 +132,7 @@ typedef unsigned char boolean;
/* Macros for data alignment. */
-#if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) || defined(__SUNPRO_CC)
+#if defined(__GNUC__)
/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Type-Attributes.html */
#define PIPE_ALIGN_TYPE(_alignment, _type) _type __attribute__((aligned(_alignment)))
@@ -178,10 +178,6 @@ void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier)
#define PIPE_READ_WRITE_BARRIER() _ReadWriteBarrier()
-#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
-
-#define PIPE_READ_WRITE_BARRIER() __machine_rw_barrier()
-
#else
#warning "Unsupported compiler"
diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h
index ac14f86fdc4..0b570c7894e 100644
--- a/src/gallium/include/pipe/p_config.h
+++ b/src/gallium/include/pipe/p_config.h
@@ -77,10 +77,6 @@
#define PIPE_CC_ICL
#endif
-#if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
-#define PIPE_CC_SUNPRO
-#endif
-
/*
* Processor architecture
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index b3c8b9f7360..cbf0ba617be 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -822,8 +822,8 @@ union pipe_query_result
/* PIPE_QUERY_PIPELINE_STATISTICS */
struct pipe_query_data_pipeline_statistics pipeline_statistics;
- /* batch queries */
- union pipe_numeric_type_union batch[0];
+ /* batch queries (variable length) */
+ union pipe_numeric_type_union batch[1];
};
union pipe_color_union
@@ -861,6 +861,9 @@ enum pipe_driver_query_result_type
*/
#define PIPE_DRIVER_QUERY_FLAG_BATCH (1 << 0)
+/* Do not list this query in the HUD. */
+#define PIPE_DRIVER_QUERY_FLAG_DONT_LIST (1 << 1)
+
struct pipe_driver_query_info
{
const char *name;
diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h
index cd5a27e2482..03d5ee405a4 100644
--- a/src/gallium/include/state_tracker/drisw_api.h
+++ b/src/gallium/include/state_tracker/drisw_api.h
@@ -20,9 +20,4 @@ struct drisw_loader_funcs
void *data, int x, int y, unsigned width, unsigned height, unsigned stride);
};
-/**
- * Implemented by the drisw target.
- */
-struct pipe_screen * drisw_create_screen(struct drisw_loader_funcs *lf);
-
#endif
diff --git a/src/gallium/state_trackers/clover/core/platform.cpp b/src/gallium/state_trackers/clover/core/platform.cpp
index 328b71cdcb1..489e8dc5a83 100644
--- a/src/gallium/state_trackers/clover/core/platform.cpp
+++ b/src/gallium/state_trackers/clover/core/platform.cpp
@@ -32,7 +32,8 @@ platform::platform() : adaptor_range(evals(), devs) {
for (pipe_loader_device *ldev : ldevs) {
try {
- devs.push_back(create(*this, ldev));
+ if (ldev)
+ devs.push_back(create(*this, ldev));
} catch (error &) {
pipe_loader_release(&ldev, 1);
}
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index 3b37f0802b0..4d11c2477c7 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -661,7 +661,11 @@ namespace {
if (dump_asm) {
LLVMSetTargetMachineAsmVerbosity(tm, true);
+#if HAVE_LLVM >= 0x0308
+ LLVMModuleRef debug_mod = wrap(llvm::CloneModule(mod).release());
+#else
LLVMModuleRef debug_mod = wrap(llvm::CloneModule(mod));
+#endif
emit_code(tm, debug_mod, LLVMAssemblyFile, &out_buffer, r_log);
buffer_size = LLVMGetBufferSize(out_buffer);
buffer_data = LLVMGetBufferStart(out_buffer);
diff --git a/src/gallium/state_trackers/clover/tgsi/compiler.cpp b/src/gallium/state_trackers/clover/tgsi/compiler.cpp
index 54cb747e6fb..4d056668a22 100644
--- a/src/gallium/state_trackers/clover/tgsi/compiler.cpp
+++ b/src/gallium/state_trackers/clover/tgsi/compiler.cpp
@@ -97,6 +97,11 @@ namespace {
module
clover::compile_program_tgsi(const std::string &source, std::string &r_log) {
const size_t body_pos = source.find("COMP\n");
+ if (body_pos == std::string::npos) {
+ r_log = "invalid source";
+ throw compile_error();
+ }
+
const char *body = &source[body_pos];
module m;
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index beb0866c83f..a11a6cbbb0c 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -1446,6 +1446,7 @@ dri2_init_screen(__DRIscreen * sPriv)
struct pipe_screen *pscreen = NULL;
const struct drm_conf_ret *throttle_ret;
const struct drm_conf_ret *dmabuf_ret;
+ int fd = -1;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
@@ -1457,7 +1458,10 @@ dri2_init_screen(__DRIscreen * sPriv)
sPriv->driverPrivate = (void *)screen;
- if (pipe_loader_drm_probe_fd(&screen->dev, dup(screen->fd)))
+ if (screen->fd < 0 || (fd = dup(screen->fd)) < 0)
+ goto fail;
+
+ if (pipe_loader_drm_probe_fd(&screen->dev, fd))
pscreen = pipe_loader_create_screen(screen->dev);
if (!pscreen)
@@ -1502,6 +1506,8 @@ fail:
dri_destroy_screen_helper(screen);
if (screen->dev)
pipe_loader_release(&screen->dev, 1);
+ else
+ close(fd);
FREE(screen);
return NULL;
}
@@ -1519,6 +1525,7 @@ dri_kms_init_screen(__DRIscreen * sPriv)
struct dri_screen *screen;
struct pipe_screen *pscreen = NULL;
uint64_t cap;
+ int fd = -1;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
@@ -1529,7 +1536,10 @@ dri_kms_init_screen(__DRIscreen * sPriv)
sPriv->driverPrivate = (void *)screen;
- if (pipe_loader_sw_probe_kms(&screen->dev, dup(screen->fd)))
+ if (screen->fd < 0 || (fd = dup(screen->fd)) < 0)
+ goto fail;
+
+ if (pipe_loader_sw_probe_kms(&screen->dev, fd))
pscreen = pipe_loader_create_screen(screen->dev);
if (!pscreen)
@@ -1557,6 +1567,8 @@ fail:
dri_destroy_screen_helper(screen);
if (screen->dev)
pipe_loader_release(&screen->dev, 1);
+ else
+ close(fd);
FREE(screen);
#endif // GALLIUM_SOFTPIPE
return NULL;
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index 4bcb0291d86..45459906588 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -147,7 +147,6 @@ dri_destroy_screen_helper(struct dri_screen * screen);
void
dri_destroy_screen(__DRIscreen * sPriv);
-extern struct pipe_screen *kms_swrast_create_screen(int fd);
extern const struct __DriverAPIRec dri_kms_driver_api;
extern const struct __DriverAPIRec galliumdrm_driver_api;
diff --git a/src/gallium/state_trackers/osmesa/osmesa.c b/src/gallium/state_trackers/osmesa/osmesa.c
index 0285cb0dac2..0f27ba87f8a 100644
--- a/src/gallium/state_trackers/osmesa/osmesa.c
+++ b/src/gallium/state_trackers/osmesa/osmesa.c
@@ -32,7 +32,7 @@
* may be set to "softpipe" or "llvmpipe" to override.
*
* With softpipe we could render directly into the user's buffer by using a
- * display target resource. However, softpipe doesn't suport "upside-down"
+ * display target resource. However, softpipe doesn't support "upside-down"
* rendering which would be needed for the OSMESA_Y_UP=TRUE case.
*
* With llvmpipe we could only render directly into the user's buffer when its
diff --git a/src/gallium/state_trackers/va/Makefile.sources b/src/gallium/state_trackers/va/Makefile.sources
index d281cdecc52..daebf0120f8 100644
--- a/src/gallium/state_trackers/va/Makefile.sources
+++ b/src/gallium/state_trackers/va/Makefile.sources
@@ -5,6 +5,12 @@ C_SOURCES := \
display.c \
image.c \
picture.c \
+ picture_mpeg12.c \
+ picture_mpeg4.c \
+ picture_h264.c \
+ picture_hevc.c \
+ picture_vc1.c \
+ postproc.c \
subpicture.c \
surface.c \
va_private.h
diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c
index a545a18c1e0..9ca0aa8b4ef 100644
--- a/src/gallium/state_trackers/va/config.c
+++ b/src/gallium/state_trackers/va/config.c
@@ -28,10 +28,14 @@
#include "pipe/p_screen.h"
+#include "util/u_video.h"
+
#include "vl/vl_winsys.h"
#include "va_private.h"
+DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false)
+
VAStatus
vlVaQueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, int *num_profiles)
{
@@ -45,12 +49,16 @@ vlVaQueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, int *num_
*num_profiles = 0;
pscreen = VL_VA_PSCREEN(ctx);
- for (p = PIPE_VIDEO_PROFILE_MPEG2_SIMPLE; p <= PIPE_VIDEO_PROFILE_HEVC_MAIN_444; ++p)
+ for (p = PIPE_VIDEO_PROFILE_MPEG2_SIMPLE; p <= PIPE_VIDEO_PROFILE_HEVC_MAIN_444; ++p) {
+ if (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && !debug_get_option_mpeg4())
+ continue;
+
if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) {
vap = PipeToProfile(p);
if (vap != VAProfileNone)
profile_list[(*num_profiles)++] = vap;
}
+ }
/* Support postprocessing through vl_compositor */
profile_list[(*num_profiles)++] = VAProfileNone;
diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c
index f0051e5f6a5..192794fefaa 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -187,7 +187,6 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
int picture_height, int flag, VASurfaceID *render_targets,
int num_render_targets, VAContextID *context_id)
{
- struct pipe_video_codec templat = {};
vlVaDriver *drv;
vlVaContext *context;
int is_vpp;
@@ -213,27 +212,22 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
return VA_STATUS_ERROR_INVALID_CONTEXT;
}
} else {
- templat.profile = config_id;
- templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
- templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
- templat.width = picture_width;
- templat.height = picture_height;
- templat.max_references = num_render_targets;
- templat.expect_chunked_decode = true;
+ context->templat.profile = config_id;
+ context->templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
+ context->templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
+ context->templat.width = picture_width;
+ context->templat.height = picture_height;
+ context->templat.expect_chunked_decode = true;
- if (u_reduce_video_profile(templat.profile) ==
- PIPE_VIDEO_FORMAT_MPEG4_AVC)
- templat.level = u_get_h264_level(templat.width, templat.height,
- &templat.max_references);
+ switch (u_reduce_video_profile(context->templat.profile)) {
+ case PIPE_VIDEO_FORMAT_MPEG12:
+ case PIPE_VIDEO_FORMAT_VC1:
+ case PIPE_VIDEO_FORMAT_MPEG4:
+ context->templat.max_references = 2;
+ break;
- context->decoder = drv->pipe->create_video_codec(drv->pipe, &templat);
- if (!context->decoder) {
- FREE(context);
- return VA_STATUS_ERROR_ALLOCATION_FAILED;
- }
-
- if (u_reduce_video_profile(context->decoder->profile) ==
- PIPE_VIDEO_FORMAT_MPEG4_AVC) {
+ case PIPE_VIDEO_FORMAT_MPEG4_AVC:
+ context->templat.max_references = 0;
context->desc.h264.pps = CALLOC_STRUCT(pipe_h264_pps);
if (!context->desc.h264.pps) {
FREE(context);
@@ -245,10 +239,10 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
- }
+ break;
- if (u_reduce_video_profile(context->decoder->profile) ==
- PIPE_VIDEO_FORMAT_HEVC) {
+ case PIPE_VIDEO_FORMAT_HEVC:
+ context->templat.max_references = num_render_targets;
context->desc.h265.pps = CALLOC_STRUCT(pipe_h265_pps);
if (!context->desc.h265.pps) {
FREE(context);
@@ -260,6 +254,10 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
+ break;
+
+ default:
+ break;
}
}
diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c
index a37a9b791db..8623139b5be 100644
--- a/src/gallium/state_trackers/va/picture.c
+++ b/src/gallium/state_trackers/va/picture.c
@@ -59,14 +59,17 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende
return VA_STATUS_ERROR_INVALID_SURFACE;
context->target = surf->buffer;
+
if (!context->decoder) {
/* VPP */
- if ((context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM &&
+ if (context->templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN &&
+ ((context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM &&
context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM &&
context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM &&
context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM) ||
- context->target->interlaced)
+ context->target->interlaced))
return VA_STATUS_ERROR_UNIMPLEMENTED;
+
return VA_STATUS_SUCCESS;
}
@@ -75,9 +78,9 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende
return VA_STATUS_SUCCESS;
}
-static void
-getReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id,
- struct pipe_video_buffer **ref_frame)
+void
+vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id,
+ struct pipe_video_buffer **ref_frame)
{
vlVaSurface *surf = handle_table_get(drv->htab, surface_id);
if (surf)
@@ -86,429 +89,81 @@ getReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id,
*ref_frame = NULL;
}
-static void
+static VAStatus
handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
{
- VAPictureParameterBufferMPEG2 *mpeg2;
- VAPictureParameterBufferH264 *h264;
- VAPictureParameterBufferVC1 * vc1;
- VAPictureParameterBufferMPEG4 *mpeg4;
- VAPictureParameterBufferHEVC *hevc;
- vlVaSurface *surf_forward;
- vlVaSurface *surf_backward;
unsigned int i;
- static const uint8_t default_intra_quant_matrix[64] = { 0 };
- static const uint8_t default_non_intra_quant_matrix[64] = { 0 };
+ VAStatus vaStatus = VA_STATUS_SUCCESS;
- switch (u_reduce_video_profile(context->decoder->profile)) {
+ switch (u_reduce_video_profile(context->templat.profile)) {
case PIPE_VIDEO_FORMAT_MPEG12:
- assert(buf->size >= sizeof(VAPictureParameterBufferMPEG2) && buf->num_elements == 1);
- mpeg2 = buf->data;
- /*horizontal_size;*/
- /*vertical_size;*/
- getReferenceFrame(drv, mpeg2->forward_reference_picture, &context->desc.mpeg12.ref[0]);
- getReferenceFrame(drv, mpeg2->backward_reference_picture, &context->desc.mpeg12.ref[1]);
- context->desc.mpeg12.picture_coding_type = mpeg2->picture_coding_type;
- context->desc.mpeg12.f_code[0][0] = ((mpeg2->f_code >> 12) & 0xf) - 1;
- context->desc.mpeg12.f_code[0][1] = ((mpeg2->f_code >> 8) & 0xf) - 1;
- context->desc.mpeg12.f_code[1][0] = ((mpeg2->f_code >> 4) & 0xf) - 1;
- context->desc.mpeg12.f_code[1][1] = (mpeg2->f_code & 0xf) - 1;
- context->desc.mpeg12.intra_dc_precision =
- mpeg2->picture_coding_extension.bits.intra_dc_precision;
- context->desc.mpeg12.picture_structure =
- mpeg2->picture_coding_extension.bits.picture_structure;
- context->desc.mpeg12.top_field_first =
- mpeg2->picture_coding_extension.bits.top_field_first;
- context->desc.mpeg12.frame_pred_frame_dct =
- mpeg2->picture_coding_extension.bits.frame_pred_frame_dct;
- context->desc.mpeg12.concealment_motion_vectors =
- mpeg2->picture_coding_extension.bits.concealment_motion_vectors;
- context->desc.mpeg12.q_scale_type =
- mpeg2->picture_coding_extension.bits.q_scale_type;
- context->desc.mpeg12.intra_vlc_format =
- mpeg2->picture_coding_extension.bits.intra_vlc_format;
- context->desc.mpeg12.alternate_scan =
- mpeg2->picture_coding_extension.bits.alternate_scan;
- /*repeat_first_field*/
- /*progressive_frame*/
- /*is_first_field*/
+ vlVaHandlePictureParameterBufferMPEG12(drv, context, buf);
break;
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
- assert(buf->size >= sizeof(VAPictureParameterBufferH264) && buf->num_elements == 1);
- h264 = buf->data;
- /*CurrPic*/
- context->desc.h264.field_order_cnt[0] = h264->CurrPic.TopFieldOrderCnt;
- context->desc.h264.field_order_cnt[1] = h264->CurrPic.BottomFieldOrderCnt;
- /*ReferenceFrames[16]*/
- /*picture_width_in_mbs_minus1*/
- /*picture_height_in_mbs_minus1*/
- /*bit_depth_luma_minus8*/
- /*bit_depth_chroma_minus8*/
- context->desc.h264.num_ref_frames = h264->num_ref_frames;
- /*chroma_format_idc*/
- /*residual_colour_transform_flag*/
- /*gaps_in_frame_num_value_allowed_flag*/
- context->desc.h264.pps->sps->frame_mbs_only_flag =
- h264->seq_fields.bits.frame_mbs_only_flag;
- context->desc.h264.pps->sps->mb_adaptive_frame_field_flag =
- h264->seq_fields.bits.mb_adaptive_frame_field_flag;
- context->desc.h264.pps->sps->direct_8x8_inference_flag =
- h264->seq_fields.bits.direct_8x8_inference_flag;
- /*MinLumaBiPredSize8x8*/
- context->desc.h264.pps->sps->log2_max_frame_num_minus4 =
- h264->seq_fields.bits.log2_max_frame_num_minus4;
- context->desc.h264.pps->sps->pic_order_cnt_type =
- h264->seq_fields.bits.pic_order_cnt_type;
- context->desc.h264.pps->sps->log2_max_pic_order_cnt_lsb_minus4 =
- h264->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4;
- context->desc.h264.pps->sps->delta_pic_order_always_zero_flag =
- h264->seq_fields.bits.delta_pic_order_always_zero_flag;
- /*num_slice_groups_minus1*/
- /*slice_group_map_type*/
- /*slice_group_change_rate_minus1*/
- context->desc.h264.pps->pic_init_qp_minus26 =
- h264->pic_init_qp_minus26;
- /*pic_init_qs_minus26*/
- context->desc.h264.pps->chroma_qp_index_offset =
- h264->chroma_qp_index_offset;
- context->desc.h264.pps->second_chroma_qp_index_offset =
- h264->second_chroma_qp_index_offset;
- context->desc.h264.pps->entropy_coding_mode_flag =
- h264->pic_fields.bits.entropy_coding_mode_flag;
- context->desc.h264.pps->weighted_pred_flag =
- h264->pic_fields.bits.weighted_pred_flag;
- context->desc.h264.pps->weighted_bipred_idc =
- h264->pic_fields.bits.weighted_bipred_idc;
- context->desc.h264.pps->transform_8x8_mode_flag =
- h264->pic_fields.bits.transform_8x8_mode_flag;
- context->desc.h264.field_pic_flag =
- h264->pic_fields.bits.field_pic_flag;
- context->desc.h264.pps->constrained_intra_pred_flag =
- h264->pic_fields.bits.constrained_intra_pred_flag;
- context->desc.h264.pps->bottom_field_pic_order_in_frame_present_flag =
- h264->pic_fields.bits.pic_order_present_flag;
- context->desc.h264.pps->deblocking_filter_control_present_flag =
- h264->pic_fields.bits.deblocking_filter_control_present_flag;
- context->desc.h264.pps->redundant_pic_cnt_present_flag =
- h264->pic_fields.bits.redundant_pic_cnt_present_flag;
- /*reference_pic_flag*/
- context->desc.h264.frame_num = h264->frame_num;
+ vlVaHandlePictureParameterBufferH264(drv, context, buf);
break;
case PIPE_VIDEO_FORMAT_VC1:
- assert(buf->size >= sizeof(VAPictureParameterBufferVC1) && buf->num_elements == 1);
- vc1 = buf->data;
- getReferenceFrame(drv, vc1->forward_reference_picture, &context->desc.vc1.ref[0]);
- getReferenceFrame(drv, vc1->backward_reference_picture, &context->desc.vc1.ref[1]);
- context->desc.vc1.picture_type = vc1->picture_fields.bits.picture_type;
- context->desc.vc1.frame_coding_mode = vc1->picture_fields.bits.frame_coding_mode;
- context->desc.vc1.postprocflag = vc1->post_processing != 0;
- context->desc.vc1.pulldown = vc1->sequence_fields.bits.pulldown;
- context->desc.vc1.interlace = vc1->sequence_fields.bits.interlace;
- context->desc.vc1.tfcntrflag = vc1->sequence_fields.bits.tfcntrflag;
- context->desc.vc1.finterpflag = vc1->sequence_fields.bits.finterpflag;
- context->desc.vc1.psf = vc1->sequence_fields.bits.psf;
- context->desc.vc1.dquant = vc1->pic_quantizer_fields.bits.dquant;
- context->desc.vc1.panscan_flag = vc1->entrypoint_fields.bits.panscan_flag;
- context->desc.vc1.refdist_flag =
- vc1->reference_fields.bits.reference_distance_flag;
- context->desc.vc1.quantizer = vc1->pic_quantizer_fields.bits.quantizer;
- context->desc.vc1.extended_mv = vc1->mv_fields.bits.extended_mv_flag;
- context->desc.vc1.extended_dmv = vc1->mv_fields.bits.extended_dmv_flag;
- context->desc.vc1.overlap = vc1->sequence_fields.bits.overlap;
- context->desc.vc1.vstransform =
- vc1->transform_fields.bits.variable_sized_transform_flag;
- context->desc.vc1.loopfilter = vc1->entrypoint_fields.bits.loopfilter;
- context->desc.vc1.fastuvmc = vc1->fast_uvmc_flag;
- context->desc.vc1.range_mapy_flag = vc1->range_mapping_fields.bits.luma_flag;
- context->desc.vc1.range_mapy = vc1->range_mapping_fields.bits.luma;
- context->desc.vc1.range_mapuv_flag = vc1->range_mapping_fields.bits.chroma_flag;
- context->desc.vc1.range_mapuv = vc1->range_mapping_fields.bits.chroma;
- context->desc.vc1.multires = vc1->sequence_fields.bits.multires;
- context->desc.vc1.syncmarker = vc1->sequence_fields.bits.syncmarker;
- context->desc.vc1.rangered = vc1->sequence_fields.bits.rangered;
- context->desc.vc1.maxbframes = vc1->sequence_fields.bits.max_b_frames;
- context->desc.vc1.deblockEnable = vc1->post_processing != 0;
- context->desc.vc1.pquant = vc1->pic_quantizer_fields.bits.pic_quantizer_scale;
+ vlVaHandlePictureParameterBufferVC1(drv, context, buf);
break;
case PIPE_VIDEO_FORMAT_MPEG4:
- assert(buf->size >= sizeof(VAPictureParameterBufferMPEG4) && buf->num_elements == 1);
- mpeg4 = buf->data;
-
- context->mpeg4.pps = *mpeg4;
-
- /* vop_width */
- /* vop_height */
- /* forward_reference_picture */
- /* backward_reference_picture */
- context->desc.mpeg4.short_video_header =
- mpeg4->vol_fields.bits.short_video_header;
- /* chroma_format */
- context->desc.mpeg4.interlaced = mpeg4->vol_fields.bits.interlaced;
- /* obmc_disable */
- /* sprite_enable */
- /* sprite_warping_accuracy */
- context->desc.mpeg4.quant_type = mpeg4->vol_fields.bits.quant_type;
- context->desc.mpeg4.quarter_sample = mpeg4->vol_fields.bits.quarter_sample;
- /* data_partitioned */
- /* reversible_vlc */
- context->desc.mpeg4.resync_marker_disable =
- mpeg4->vol_fields.bits.resync_marker_disable;
- /* no_of_sprite_warping_points */
- /* sprite_trajectory_du */
- /* sprite_trajectory_dv */
- /* quant_precision */
- context->desc.mpeg4.vop_coding_type = mpeg4->vop_fields.bits.vop_coding_type;
- /* backward_reference_vop_coding_type */
- /* vop_rounding_type */
- /* intra_dc_vlc_thr */
- context->desc.mpeg4.top_field_first =
- mpeg4->vop_fields.bits.top_field_first;
- context->desc.mpeg4.alternate_vertical_scan_flag =
- mpeg4->vop_fields.bits.alternate_vertical_scan_flag;
- context->desc.mpeg4.vop_fcode_forward = mpeg4->vop_fcode_forward;
- context->desc.mpeg4.vop_fcode_backward = mpeg4->vop_fcode_backward;
- context->desc.mpeg4.vop_time_increment_resolution =
- mpeg4->vop_time_increment_resolution;
- /* num_gobs_in_vop */
- /* num_macroblocks_in_gob */
- context->desc.mpeg4.trb[0] = mpeg4->TRB;
- context->desc.mpeg4.trb[1] = mpeg4->TRB;
- context->desc.mpeg4.trd[0] = mpeg4->TRD;
- context->desc.mpeg4.trd[1] = mpeg4->TRD;
-
- /* default [non-]intra quant matrix because mpv does not set these
- matrices */
- if (!context->desc.mpeg4.intra_matrix)
- context->desc.mpeg4.intra_matrix = default_intra_quant_matrix;
- if (!context->desc.mpeg4.non_intra_matrix)
- context->desc.mpeg4.non_intra_matrix = default_non_intra_quant_matrix;
-
- surf_forward = handle_table_get(drv->htab, mpeg4->forward_reference_picture);
- if (surf_forward)
- context->desc.mpeg4.ref[0] = surf_forward->buffer;
- surf_backward = handle_table_get(drv->htab, mpeg4->backward_reference_picture);
- if (surf_backward)
- context->desc.mpeg4.ref[1] = surf_backward->buffer;
-
- context->mpeg4.vti_bits = 0;
- for (i = context->desc.mpeg4.vop_time_increment_resolution; i > 0; i /= 2)
- ++context->mpeg4.vti_bits;
-
+ vlVaHandlePictureParameterBufferMPEG4(drv, context, buf);
break;
case PIPE_VIDEO_FORMAT_HEVC:
- assert(buf->size >= sizeof(VAPictureParameterBufferHEVC) && buf->num_elements == 1);
- hevc = buf->data;
- context->desc.h265.pps->sps->chroma_format_idc = hevc->pic_fields.bits.chroma_format_idc;
- context->desc.h265.pps->sps->separate_colour_plane_flag =
- hevc->pic_fields.bits.separate_colour_plane_flag;
- context->desc.h265.pps->sps->pic_width_in_luma_samples = hevc->pic_width_in_luma_samples;
- context->desc.h265.pps->sps->pic_height_in_luma_samples = hevc->pic_height_in_luma_samples;
- context->desc.h265.pps->sps->bit_depth_luma_minus8 = hevc->bit_depth_luma_minus8;
- context->desc.h265.pps->sps->bit_depth_chroma_minus8 = hevc->bit_depth_chroma_minus8;
- context->desc.h265.pps->sps->log2_max_pic_order_cnt_lsb_minus4 =
- hevc->log2_max_pic_order_cnt_lsb_minus4;
- context->desc.h265.pps->sps->sps_max_dec_pic_buffering_minus1 =
- hevc->sps_max_dec_pic_buffering_minus1;
- context->desc.h265.pps->sps->log2_min_luma_coding_block_size_minus3 =
- hevc->log2_min_luma_coding_block_size_minus3;
- context->desc.h265.pps->sps->log2_diff_max_min_luma_coding_block_size =
- hevc->log2_diff_max_min_luma_coding_block_size;
- context->desc.h265.pps->sps->log2_min_transform_block_size_minus2 =
- hevc->log2_min_transform_block_size_minus2;
- context->desc.h265.pps->sps->log2_diff_max_min_transform_block_size =
- hevc->log2_diff_max_min_transform_block_size;
- context->desc.h265.pps->sps->max_transform_hierarchy_depth_inter =
- hevc->max_transform_hierarchy_depth_inter;
- context->desc.h265.pps->sps->max_transform_hierarchy_depth_intra =
- hevc->max_transform_hierarchy_depth_intra;
- context->desc.h265.pps->sps->scaling_list_enabled_flag =
- hevc->pic_fields.bits.scaling_list_enabled_flag;
- context->desc.h265.pps->sps->amp_enabled_flag = hevc->pic_fields.bits.amp_enabled_flag;
- context->desc.h265.pps->sps->sample_adaptive_offset_enabled_flag =
- hevc->slice_parsing_fields.bits.sample_adaptive_offset_enabled_flag;
- context->desc.h265.pps->sps->pcm_enabled_flag = hevc->pic_fields.bits.pcm_enabled_flag;
- if (hevc->pic_fields.bits.pcm_enabled_flag == 1) {
- context->desc.h265.pps->sps->pcm_sample_bit_depth_luma_minus1 =
- hevc->pcm_sample_bit_depth_luma_minus1;
- context->desc.h265.pps->sps->pcm_sample_bit_depth_chroma_minus1 =
- hevc->pcm_sample_bit_depth_chroma_minus1;
- context->desc.h265.pps->sps->log2_min_pcm_luma_coding_block_size_minus3 =
- hevc->log2_min_pcm_luma_coding_block_size_minus3;
- context->desc.h265.pps->sps->log2_diff_max_min_pcm_luma_coding_block_size =
- hevc->log2_diff_max_min_pcm_luma_coding_block_size;
- context->desc.h265.pps->sps->pcm_loop_filter_disabled_flag =
- hevc->pic_fields.bits.pcm_loop_filter_disabled_flag;
- }
- context->desc.h265.pps->sps->num_short_term_ref_pic_sets = hevc->num_short_term_ref_pic_sets;
- context->desc.h265.pps->sps->long_term_ref_pics_present_flag =
- hevc->slice_parsing_fields.bits.long_term_ref_pics_present_flag;
- context->desc.h265.pps->sps->num_long_term_ref_pics_sps = hevc->num_long_term_ref_pic_sps;
- context->desc.h265.pps->sps->sps_temporal_mvp_enabled_flag =
- hevc->slice_parsing_fields.bits.sps_temporal_mvp_enabled_flag;
- context->desc.h265.pps->sps->strong_intra_smoothing_enabled_flag =
- hevc->pic_fields.bits.strong_intra_smoothing_enabled_flag;
-
- context->desc.h265.pps->dependent_slice_segments_enabled_flag =
- hevc->slice_parsing_fields.bits.dependent_slice_segments_enabled_flag;
- context->desc.h265.pps->output_flag_present_flag =
- hevc->slice_parsing_fields.bits.output_flag_present_flag;
- context->desc.h265.pps->num_extra_slice_header_bits = hevc->num_extra_slice_header_bits;
- context->desc.h265.pps->sign_data_hiding_enabled_flag =
- hevc->pic_fields.bits.sign_data_hiding_enabled_flag;
- context->desc.h265.pps->cabac_init_present_flag =
- hevc->slice_parsing_fields.bits.cabac_init_present_flag;
- context->desc.h265.pps->num_ref_idx_l0_default_active_minus1 =
- hevc->num_ref_idx_l0_default_active_minus1;
- context->desc.h265.pps->num_ref_idx_l1_default_active_minus1 =
- hevc->num_ref_idx_l1_default_active_minus1;
- context->desc.h265.pps->init_qp_minus26 = hevc->init_qp_minus26;
- context->desc.h265.pps->constrained_intra_pred_flag =
- hevc->pic_fields.bits.constrained_intra_pred_flag;
- context->desc.h265.pps->transform_skip_enabled_flag =
- hevc->pic_fields.bits.transform_skip_enabled_flag;
- context->desc.h265.pps->cu_qp_delta_enabled_flag =
- hevc->pic_fields.bits.cu_qp_delta_enabled_flag;
- context->desc.h265.pps->diff_cu_qp_delta_depth = hevc->diff_cu_qp_delta_depth;
- context->desc.h265.pps->pps_cb_qp_offset = hevc->pps_cb_qp_offset;
- context->desc.h265.pps->pps_cr_qp_offset = hevc->pps_cr_qp_offset;
- context->desc.h265.pps->pps_slice_chroma_qp_offsets_present_flag =
- hevc->slice_parsing_fields.bits.pps_slice_chroma_qp_offsets_present_flag;
- context->desc.h265.pps->weighted_pred_flag = hevc->pic_fields.bits.weighted_pred_flag;
- context->desc.h265.pps->weighted_bipred_flag = hevc->pic_fields.bits.weighted_bipred_flag;
- context->desc.h265.pps->transquant_bypass_enabled_flag =
- hevc->pic_fields.bits.transquant_bypass_enabled_flag;
- context->desc.h265.pps->tiles_enabled_flag = hevc->pic_fields.bits.tiles_enabled_flag;
- context->desc.h265.pps->entropy_coding_sync_enabled_flag =
- hevc->pic_fields.bits.entropy_coding_sync_enabled_flag;
- if (hevc->pic_fields.bits.tiles_enabled_flag == 1) {
- context->desc.h265.pps->num_tile_columns_minus1 = hevc->num_tile_columns_minus1;
- context->desc.h265.pps->num_tile_rows_minus1 = hevc->num_tile_rows_minus1;
- for (i = 0 ; i < 19 ; i++)
- context->desc.h265.pps->column_width_minus1[i] = hevc->column_width_minus1[i];
- for (i = 0 ; i < 21 ; i++)
- context->desc.h265.pps->row_height_minus1[i] = hevc->row_height_minus1[i];
- context->desc.h265.pps->loop_filter_across_tiles_enabled_flag =
- hevc->pic_fields.bits.loop_filter_across_tiles_enabled_flag;
- }
- context->desc.h265.pps->pps_loop_filter_across_slices_enabled_flag =
- hevc->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag;
- context->desc.h265.pps->deblocking_filter_override_enabled_flag =
- hevc->slice_parsing_fields.bits.deblocking_filter_override_enabled_flag;
- context->desc.h265.pps->pps_deblocking_filter_disabled_flag =
- hevc->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag;
- context->desc.h265.pps->pps_beta_offset_div2 = hevc->pps_beta_offset_div2;
- context->desc.h265.pps->pps_tc_offset_div2 = hevc->pps_tc_offset_div2;
- context->desc.h265.pps->lists_modification_present_flag =
- hevc->slice_parsing_fields.bits.lists_modification_present_flag;
- context->desc.h265.pps->log2_parallel_merge_level_minus2 =
- hevc->log2_parallel_merge_level_minus2;
- context->desc.h265.pps->slice_segment_header_extension_present_flag =
- hevc->slice_parsing_fields.bits.slice_segment_header_extension_present_flag;
-
- context->desc.h265.IDRPicFlag = hevc->slice_parsing_fields.bits.IdrPicFlag;
- context->desc.h265.RAPPicFlag = hevc->slice_parsing_fields.bits.RapPicFlag;
-
- context->desc.h265.CurrPicOrderCntVal = hevc->CurrPic.pic_order_cnt;
-
- for (i = 0 ; i < 8 ; i++) {
- context->desc.h265.RefPicSetStCurrBefore[i] = 0xFF;
- context->desc.h265.RefPicSetStCurrAfter[i] = 0xFF;
- context->desc.h265.RefPicSetLtCurr[i] = 0xFF;
- }
- context->desc.h265.NumPocStCurrBefore = 0;
- context->desc.h265.NumPocStCurrAfter = 0;
- context->desc.h265.NumPocLtCurr = 0;
- unsigned int iBefore = 0;
- unsigned int iAfter = 0;
- unsigned int iCurr = 0;
- for (i = 0 ; i < 15 ; i++) {
- context->desc.h265.PicOrderCntVal[i] = hevc->ReferenceFrames[i].pic_order_cnt;
-
- unsigned int index = hevc->ReferenceFrames[i].picture_id & 0x7F;
-
- if (index == 0x7F)
- continue;
-
- getReferenceFrame(drv, hevc->ReferenceFrames[i].picture_id, &context->desc.h265.ref[i]);
-
- if ((hevc->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE) && (iBefore < 8)) {
- context->desc.h265.RefPicSetStCurrBefore[iBefore++] = i;
- context->desc.h265.NumPocStCurrBefore++;
- }
- if ((hevc->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_AFTER) && (iAfter < 8)) {
- context->desc.h265.RefPicSetStCurrAfter[iAfter++] = i;
- context->desc.h265.NumPocStCurrAfter++;
- }
- if ((hevc->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_LT_CURR) && (iCurr < 8)) {
- context->desc.h265.RefPicSetLtCurr[iCurr++] = i;
- context->desc.h265.NumPocLtCurr++;
- }
- }
+ vlVaHandlePictureParameterBufferHEVC(drv, context, buf);
break;
default:
break;
}
+
+ /* Create the decoder once max_references is known. */
+ if (!context->decoder) {
+ if (!context->target)
+ return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+ if (context->templat.max_references == 0)
+ return VA_STATUS_ERROR_INVALID_BUFFER;
+
+ if (u_reduce_video_profile(context->templat.profile) ==
+ PIPE_VIDEO_FORMAT_MPEG4_AVC)
+ context->templat.level = u_get_h264_level(context->templat.width,
+ context->templat.height, &context->templat.max_references);
+
+ context->decoder = drv->pipe->create_video_codec(drv->pipe,
+ &context->templat);
+
+ if (!context->decoder)
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+
+ context->decoder->begin_frame(context->decoder, context->target,
+ &context->desc.base);
+ }
+
+ return vaStatus;
}
static void
handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf)
{
- VAIQMatrixBufferMPEG2 *mpeg2;
- VAIQMatrixBufferH264 *h264;
- VAIQMatrixBufferMPEG4 *mpeg4;
- VAIQMatrixBufferHEVC *h265;
-
- switch (u_reduce_video_profile(context->decoder->profile)) {
+ switch (u_reduce_video_profile(context->templat.profile)) {
case PIPE_VIDEO_FORMAT_MPEG12:
- assert(buf->size >= sizeof(VAIQMatrixBufferMPEG2) && buf->num_elements == 1);
- mpeg2 = buf->data;
- if (mpeg2->load_intra_quantiser_matrix)
- context->desc.mpeg12.intra_matrix = mpeg2->intra_quantiser_matrix;
- else
- context->desc.mpeg12.intra_matrix = NULL;
-
- if (mpeg2->load_non_intra_quantiser_matrix)
- context->desc.mpeg12.non_intra_matrix = mpeg2->non_intra_quantiser_matrix;
- else
- context->desc.mpeg12.non_intra_matrix = NULL;
+ vlVaHandleIQMatrixBufferMPEG12(context, buf);
break;
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
- assert(buf->size >= sizeof(VAIQMatrixBufferH264) && buf->num_elements == 1);
- h264 = buf->data;
- memcpy(&context->desc.h264.pps->ScalingList4x4, h264->ScalingList4x4, 6 * 16);
- memcpy(&context->desc.h264.pps->ScalingList8x8, h264->ScalingList8x8, 2 * 64);
- break;
-
- case PIPE_VIDEO_FORMAT_HEVC:
- assert(buf->size >= sizeof(VAIQMatrixBufferH264) && buf->num_elements == 1);
- h265 = buf->data;
- memcpy(&context->desc.h265.pps->sps->ScalingList4x4, h265->ScalingList4x4, 6 * 16);
- memcpy(&context->desc.h265.pps->sps->ScalingList8x8, h265->ScalingList8x8, 6 * 64);
- memcpy(&context->desc.h265.pps->sps->ScalingList16x16, h265->ScalingList16x16, 6 * 64);
- memcpy(&context->desc.h265.pps->sps->ScalingList32x32, h265->ScalingList32x32, 2 * 64);
- memcpy(&context->desc.h265.pps->sps->ScalingListDCCoeff16x16, h265->ScalingListDC16x16, 6);
- memcpy(&context->desc.h265.pps->sps->ScalingListDCCoeff32x32, h265->ScalingListDC32x32, 2);
+ vlVaHandleIQMatrixBufferH264(context, buf);
break;
case PIPE_VIDEO_FORMAT_MPEG4:
- assert(buf->size >= sizeof(VAIQMatrixBufferMPEG4) && buf->num_elements == 1);
- mpeg4 = buf->data;
+ vlVaHandleIQMatrixBufferMPEG4(context, buf);
+ break;
- if (mpeg4->load_intra_quant_mat)
- context->desc.mpeg4.intra_matrix = mpeg4->intra_quant_mat;
- else
- context->desc.mpeg4.intra_matrix = NULL;
-
- if (mpeg4->load_non_intra_quant_mat)
- context->desc.mpeg4.non_intra_matrix = mpeg4->non_intra_quant_mat;
- else
- context->desc.mpeg4.non_intra_matrix = NULL;
+ case PIPE_VIDEO_FORMAT_HEVC:
+ vlVaHandleIQMatrixBufferHEVC(context, buf);
break;
default:
@@ -519,130 +174,24 @@ handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf)
static void
handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf)
{
- VASliceParameterBufferH264 *h264;
- VASliceParameterBufferMPEG4 *mpeg4;
- VASliceParameterBufferHEVC *h265;
-
- switch (u_reduce_video_profile(context->decoder->profile)) {
+ switch (u_reduce_video_profile(context->templat.profile)) {
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
- assert(buf->size >= sizeof(VASliceParameterBufferH264) && buf->num_elements == 1);
- h264 = buf->data;
- context->desc.h264.num_ref_idx_l0_active_minus1 =
- h264->num_ref_idx_l0_active_minus1;
- context->desc.h264.num_ref_idx_l1_active_minus1 =
- h264->num_ref_idx_l1_active_minus1;
+ vlVaHandleSliceParameterBufferH264(context, buf);
break;
- case PIPE_VIDEO_FORMAT_MPEG4:
- assert(buf->size >= sizeof(VASliceParameterBufferMPEG4) && buf->num_elements == 1);
- mpeg4 = buf->data;
- context->mpeg4.quant_scale = mpeg4->quant_scale;
+ case PIPE_VIDEO_FORMAT_MPEG4:
+ vlVaHandleSliceParameterBufferMPEG4(context, buf);
break;
+
case PIPE_VIDEO_FORMAT_HEVC:
- assert(buf->size >= sizeof(VASliceParameterBufferHEVC) && buf->num_elements == 1);
- h265 = buf->data;
- for (int i = 0 ; i < 2 ; i++) {
- for (int j = 0 ; j < 15 ; j++)
- context->desc.h265.RefPicList[i][j] = h265->RefPicList[i][j];
- }
- context->desc.h265.UseRefPicList = true;
+ vlVaHandleSliceParameterBufferHEVC(context, buf);
break;
+
default:
break;
}
}
-struct bit_stream
-{
- uint8_t *data;
- unsigned int length; /* bits */
- unsigned int pos; /* bits */
-};
-
-static inline void
-write_bit(struct bit_stream *writer, unsigned int bit)
-{
- assert(writer->length > (writer)->pos);
- writer->data[writer->pos>>3] |= ((bit & 1)<<(7 - (writer->pos & 7)));
- writer->pos++;
-}
-
-static inline void
-write_bits(struct bit_stream *writer, unsigned int bits, unsigned int len)
-{
- int i;
- assert(len <= sizeof(bits)*8);
- for (i = len - 1; i >= 0; i--)
- write_bit(writer, bits>>i);
-}
-
-static void
-vlVaDecoderFixMPEG4Startcode(vlVaContext *context)
-{
- uint8_t vop[] = { 0x00, 0x00, 0x01, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00 };
- struct bit_stream bs_vop = {vop, sizeof(vop)*8, 32};
- unsigned int vop_time_inc;
- int mod_time;
- unsigned int vop_size;
- unsigned int vop_coding_type = context->desc.mpeg4.vop_coding_type;
-
- context->mpeg4.start_code_size = 0;
- memset(context->mpeg4.start_code, 0, sizeof(context->mpeg4.start_code));
- if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_I) {
- unsigned int vop_time = context->mpeg4.frame_num/
- context->desc.mpeg4.vop_time_increment_resolution;
- unsigned int vop_hour = vop_time / 3600;
- unsigned int vop_minute = (vop_time / 60) % 60;
- unsigned int vop_second = vop_time % 60;
- uint8_t group_of_vop[] = { 0x00, 0x00, 0x01, 0xb3, 0x00, 0x00, 0x00 };
- struct bit_stream bs_gvop = {group_of_vop, sizeof(group_of_vop)*8, 32};
-
- write_bits(&bs_gvop, vop_hour, 5);
- write_bits(&bs_gvop, vop_minute, 6);
- write_bit(&bs_gvop, 1); /* marker_bit */
- write_bits(&bs_gvop, vop_second, 6);
- write_bit(&bs_gvop, 0); /* closed_gov */ /* TODO replace magic */
- write_bit(&bs_gvop, 0); /* broken_link */
- write_bit(&bs_gvop, 0); /* padding */
- write_bits(&bs_gvop, 7, 3); /* padding */
-
- memcpy(context->mpeg4.start_code, group_of_vop, sizeof(group_of_vop));
- context->mpeg4.start_code_size += sizeof(group_of_vop);
- }
-
- write_bits(&bs_vop, vop_coding_type, 2);
- mod_time = context->mpeg4.frame_num %
- context->desc.mpeg4.vop_time_increment_resolution == 0 &&
- vop_coding_type+1 != PIPE_MPEG12_PICTURE_CODING_TYPE_I;
- while (mod_time--)
- write_bit(&bs_vop, 1); /* modulo_time_base */
- write_bit(&bs_vop, 0); /* modulo_time_base */
-
- write_bit(&bs_vop, 1); /* marker_bit */
- vop_time_inc = context->mpeg4.frame_num %
- context->desc.mpeg4.vop_time_increment_resolution;
- write_bits(&bs_vop, vop_time_inc, context->mpeg4.vti_bits);
- write_bit(&bs_vop, 1); /* marker_bit */
- write_bit(&bs_vop, 1); /* vop_coded */
- if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_P)
- write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.vop_rounding_type);
- write_bits(&bs_vop, context->mpeg4.pps.vop_fields.bits.intra_dc_vlc_thr, 3);
- if (context->mpeg4.pps.vol_fields.bits.interlaced) {
- write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.top_field_first);
- write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.alternate_vertical_scan_flag);
- }
-
- write_bits(&bs_vop, context->mpeg4.quant_scale, context->mpeg4.pps.quant_precision);
- if (vop_coding_type+1 != PIPE_MPEG12_PICTURE_CODING_TYPE_I)
- write_bits(&bs_vop, context->desc.mpeg4.vop_fcode_forward, 3);
- if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_B)
- write_bits(&bs_vop, context->desc.mpeg4.vop_fcode_backward, 3);
-
- vop_size = bs_vop.pos/8;
- memcpy(context->mpeg4.start_code + context->mpeg4.start_code_size, vop, vop_size);
- context->mpeg4.start_code_size += vop_size;
-}
-
static unsigned int
bufHasStartcode(vlVaBuffer *buf, unsigned int code, unsigned int bits)
{
@@ -672,22 +221,22 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
static const uint8_t start_code_h265[] = { 0x00, 0x00, 0x01 };
static const uint8_t start_code_vc1[] = { 0x00, 0x00, 0x01, 0x0d };
- format = u_reduce_video_profile(context->decoder->profile);
+ format = u_reduce_video_profile(context->templat.profile);
switch (format) {
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
- if (bufHasStartcode(buf, 0x000001, 24))
- break;
+ if (bufHasStartcode(buf, 0x000001, 24))
+ break;
- buffers[num_buffers] = (void *const)&start_code_h264;
- sizes[num_buffers++] = sizeof(start_code_h264);
+ buffers[num_buffers] = (void *const)&start_code_h264;
+ sizes[num_buffers++] = sizeof(start_code_h264);
break;
case PIPE_VIDEO_FORMAT_HEVC:
if (bufHasStartcode(buf, 0x000001, 24))
break;
- buffers[num_buffers] = (void *const)&start_code_h265;
- sizes[num_buffers++] = sizeof(start_code_h265);
- break;
+ buffers[num_buffers] = (void *const)&start_code_h265;
+ sizes[num_buffers++] = sizeof(start_code_h265);
+ break;
case PIPE_VIDEO_FORMAT_VC1:
if (bufHasStartcode(buf, 0x0000010d, 32) ||
bufHasStartcode(buf, 0x0000010c, 32) ||
@@ -717,65 +266,6 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
num_buffers, (const void * const*)buffers, sizes);
}
-static VAStatus
-handleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
-{
- struct u_rect src_rect;
- struct u_rect dst_rect;
- struct u_rect *dirty_area;
- vlVaSurface *src_surface;
- VAProcPipelineParameterBuffer *pipeline_param;
- struct pipe_surface **surfaces;
- struct pipe_screen *screen;
- struct pipe_surface *psurf;
-
- if (!drv || !context)
- return VA_STATUS_ERROR_INVALID_CONTEXT;
-
- if (!buf || !buf->data)
- return VA_STATUS_ERROR_INVALID_BUFFER;
-
- if (!context->target)
- return VA_STATUS_ERROR_INVALID_SURFACE;
-
- pipeline_param = (VAProcPipelineParameterBuffer *)buf->data;
-
- src_surface = handle_table_get(drv->htab, pipeline_param->surface);
- if (!src_surface || !src_surface->buffer)
- return VA_STATUS_ERROR_INVALID_SURFACE;
-
- surfaces = context->target->get_surfaces(context->target);
-
- if (!surfaces || !surfaces[0])
- return VA_STATUS_ERROR_INVALID_SURFACE;
-
- screen = drv->pipe->screen;
-
- psurf = surfaces[0];
-
- src_rect.x0 = pipeline_param->surface_region->x;
- src_rect.y0 = pipeline_param->surface_region->y;
- src_rect.x1 = pipeline_param->surface_region->x + pipeline_param->surface_region->width;
- src_rect.y1 = pipeline_param->surface_region->y + pipeline_param->surface_region->height;
-
- dst_rect.x0 = pipeline_param->output_region->x;
- dst_rect.y0 = pipeline_param->output_region->y;
- dst_rect.x1 = pipeline_param->output_region->x + pipeline_param->output_region->width;
- dst_rect.y1 = pipeline_param->output_region->y + pipeline_param->output_region->height;
-
- dirty_area = drv->vscreen->get_dirty_area(drv->vscreen);
-
- vl_compositor_clear_layers(&drv->cstate);
- vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src_surface->buffer, &src_rect, NULL, VL_COMPOSITOR_WEAVE);
- vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dst_rect);
- vl_compositor_render(&drv->cstate, &drv->compositor, psurf, dirty_area, true);
-
- screen->fence_reference(screen, &src_surface->fence, NULL);
- drv->pipe->flush(drv->pipe, &src_surface->fence, 0);
-
- return VA_STATUS_SUCCESS;
-}
-
VAStatus
vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers)
{
@@ -803,7 +293,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff
switch (buf->type) {
case VAPictureParameterBufferType:
- handlePictureParameterBuffer(drv, context, buf);
+ vaStatus = handlePictureParameterBuffer(drv, context, buf);
break;
case VAIQMatrixBufferType:
@@ -818,7 +308,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff
handleVASliceDataBufferType(context, buf);
break;
case VAProcPipelineParameterBufferType:
- vaStatus = handleVAProcPipelineParameterBufferType(drv, context, buf);
+ vaStatus = vlVaHandleVAProcPipelineParameterBufferType(drv, context, buf);
break;
default:
@@ -847,6 +337,9 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
return VA_STATUS_ERROR_INVALID_CONTEXT;
if (!context->decoder) {
+ if (context->templat.profile != PIPE_VIDEO_PROFILE_UNKNOWN)
+ return VA_STATUS_ERROR_INVALID_CONTEXT;
+
/* VPP */
return VA_STATUS_SUCCESS;
}
diff --git a/src/gallium/state_trackers/va/picture_h264.c b/src/gallium/state_trackers/va/picture_h264.c
new file mode 100644
index 00000000000..acbfe5d61ed
--- /dev/null
+++ b/src/gallium/state_trackers/va/picture_h264.c
@@ -0,0 +1,169 @@
+ /**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * Copyright 2014 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "util/u_video.h"
+#include "va_private.h"
+
+static void resetReferencePictureDesc(struct pipe_h264_picture_desc *h264,
+ unsigned int i)
+{
+ h264->ref[i] = NULL;
+ h264->frame_num_list[i] = 0;
+ h264->is_long_term[i] = 0;
+ h264->top_is_reference[i] = 0;
+ h264->bottom_is_reference[i] = 0;
+ h264->field_order_cnt_list[i][0] = 0;
+ h264->field_order_cnt_list[i][1] = 0;
+}
+
+void vlVaHandlePictureParameterBufferH264(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
+{
+ VAPictureParameterBufferH264 *h264 = buf->data;
+ unsigned int top_or_bottom_field;
+ unsigned i;
+
+ assert(buf->size >= sizeof(VAPictureParameterBufferH264) && buf->num_elements == 1);
+ /*CurrPic*/
+ context->desc.h264.field_order_cnt[0] = h264->CurrPic.TopFieldOrderCnt;
+ context->desc.h264.field_order_cnt[1] = h264->CurrPic.BottomFieldOrderCnt;
+ /*ReferenceFrames[16]*/
+ /*picture_width_in_mbs_minus1*/
+ /*picture_height_in_mbs_minus1*/
+ /*bit_depth_luma_minus8*/
+ /*bit_depth_chroma_minus8*/
+ context->desc.h264.num_ref_frames = h264->num_ref_frames;
+ /*chroma_format_idc*/
+ /*residual_colour_transform_flag*/
+ /*gaps_in_frame_num_value_allowed_flag*/
+ context->desc.h264.pps->sps->frame_mbs_only_flag =
+ h264->seq_fields.bits.frame_mbs_only_flag;
+ context->desc.h264.pps->sps->mb_adaptive_frame_field_flag =
+ h264->seq_fields.bits.mb_adaptive_frame_field_flag;
+ context->desc.h264.pps->sps->direct_8x8_inference_flag =
+ h264->seq_fields.bits.direct_8x8_inference_flag;
+ /*MinLumaBiPredSize8x8*/
+ context->desc.h264.pps->sps->log2_max_frame_num_minus4 =
+ h264->seq_fields.bits.log2_max_frame_num_minus4;
+ context->desc.h264.pps->sps->pic_order_cnt_type =
+ h264->seq_fields.bits.pic_order_cnt_type;
+ context->desc.h264.pps->sps->log2_max_pic_order_cnt_lsb_minus4 =
+ h264->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4;
+ context->desc.h264.pps->sps->delta_pic_order_always_zero_flag =
+ h264->seq_fields.bits.delta_pic_order_always_zero_flag;
+ /*num_slice_groups_minus1*/
+ /*slice_group_map_type*/
+ /*slice_group_change_rate_minus1*/
+ context->desc.h264.pps->pic_init_qp_minus26 =
+ h264->pic_init_qp_minus26;
+ /*pic_init_qs_minus26*/
+ context->desc.h264.pps->chroma_qp_index_offset =
+ h264->chroma_qp_index_offset;
+ context->desc.h264.pps->second_chroma_qp_index_offset =
+ h264->second_chroma_qp_index_offset;
+ context->desc.h264.pps->entropy_coding_mode_flag =
+ h264->pic_fields.bits.entropy_coding_mode_flag;
+ context->desc.h264.pps->weighted_pred_flag =
+ h264->pic_fields.bits.weighted_pred_flag;
+ context->desc.h264.pps->weighted_bipred_idc =
+ h264->pic_fields.bits.weighted_bipred_idc;
+ context->desc.h264.pps->transform_8x8_mode_flag =
+ h264->pic_fields.bits.transform_8x8_mode_flag;
+ context->desc.h264.field_pic_flag =
+ h264->pic_fields.bits.field_pic_flag;
+ context->desc.h264.pps->constrained_intra_pred_flag =
+ h264->pic_fields.bits.constrained_intra_pred_flag;
+ context->desc.h264.pps->bottom_field_pic_order_in_frame_present_flag =
+ h264->pic_fields.bits.pic_order_present_flag;
+ context->desc.h264.pps->deblocking_filter_control_present_flag =
+ h264->pic_fields.bits.deblocking_filter_control_present_flag;
+ context->desc.h264.pps->redundant_pic_cnt_present_flag =
+ h264->pic_fields.bits.redundant_pic_cnt_present_flag;
+ /*reference_pic_flag*/
+ context->desc.h264.frame_num = h264->frame_num;
+ context->desc.h264.is_reference = h264->pic_fields.bits.reference_pic_flag;
+ context->desc.h264.bottom_field_flag =
+ h264->pic_fields.bits.field_pic_flag &&
+ (h264->CurrPic.flags & VA_PICTURE_H264_BOTTOM_FIELD) != 0;
+
+ if (!context->decoder && context->desc.h264.num_ref_frames > 0)
+ context->templat.max_references = MIN2(context->desc.h264.num_ref_frames, 16);
+
+ for (i = 0; i < context->templat.max_references; ++i) {
+ if ((h264->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID) ||
+ (h264->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)) {
+ resetReferencePictureDesc(&context->desc.h264, i);
+ break;
+ }
+
+ vlVaGetReferenceFrame(drv, h264->ReferenceFrames[i].picture_id, &context->desc.h264.ref[i]);
+ context->desc.h264.frame_num_list[i] = h264->ReferenceFrames[i].frame_idx;
+
+ top_or_bottom_field = h264->ReferenceFrames[i].flags &
+ (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD);
+ context->desc.h264.is_long_term[i] = (h264->ReferenceFrames[i].flags &
+ (VA_PICTURE_H264_SHORT_TERM_REFERENCE |
+ VA_PICTURE_H264_LONG_TERM_REFERENCE)) !=
+ VA_PICTURE_H264_SHORT_TERM_REFERENCE;
+ context->desc.h264.top_is_reference[i] =
+ !context->desc.h264.is_long_term[i] ||
+ !!(h264->ReferenceFrames[i].flags & VA_PICTURE_H264_TOP_FIELD);
+ context->desc.h264.bottom_is_reference[i] =
+ !context->desc.h264.is_long_term[i] ||
+ !!(h264->ReferenceFrames[i].flags & VA_PICTURE_H264_BOTTOM_FIELD);
+ context->desc.h264.field_order_cnt_list[i][0] =
+ top_or_bottom_field != VA_PICTURE_H264_BOTTOM_FIELD ?
+ h264->ReferenceFrames[i].TopFieldOrderCnt: INT_MAX;
+ context->desc.h264.field_order_cnt_list[i][1] =
+ top_or_bottom_field != VA_PICTURE_H264_TOP_FIELD ?
+ h264->ReferenceFrames[i].BottomFieldOrderCnt: INT_MAX;
+ }
+
+ /* Make sure remaining elements are clean */
+ for (; i < 16; ++i)
+ resetReferencePictureDesc(&context->desc.h264, i);
+}
+
+void vlVaHandleIQMatrixBufferH264(vlVaContext *context, vlVaBuffer *buf)
+{
+ VAIQMatrixBufferH264 *h264 = buf->data;
+
+ assert(buf->size >= sizeof(VAIQMatrixBufferH264) && buf->num_elements == 1);
+ memcpy(&context->desc.h264.pps->ScalingList4x4, h264->ScalingList4x4, 6 * 16);
+ memcpy(&context->desc.h264.pps->ScalingList8x8, h264->ScalingList8x8, 2 * 64);
+}
+
+void vlVaHandleSliceParameterBufferH264(vlVaContext *context, vlVaBuffer *buf)
+{
+ VASliceParameterBufferH264 *h264 = buf->data;
+
+ assert(buf->size >= sizeof(VASliceParameterBufferH264) && buf->num_elements == 1);
+ context->desc.h264.num_ref_idx_l0_active_minus1 =
+ h264->num_ref_idx_l0_active_minus1;
+ context->desc.h264.num_ref_idx_l1_active_minus1 =
+ h264->num_ref_idx_l1_active_minus1;
+}
diff --git a/src/gallium/state_trackers/va/picture_hevc.c b/src/gallium/state_trackers/va/picture_hevc.c
new file mode 100644
index 00000000000..dc66b0f3fd5
--- /dev/null
+++ b/src/gallium/state_trackers/va/picture_hevc.c
@@ -0,0 +1,207 @@
+/**************************************************************************
+ *
+ * Copyright 2014 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "va_private.h"
+
+void vlVaHandlePictureParameterBufferHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
+{
+ VAPictureParameterBufferHEVC *hevc = buf->data;
+ unsigned i;
+
+ assert(buf->size >= sizeof(VAPictureParameterBufferHEVC) && buf->num_elements == 1);
+ context->desc.h265.pps->sps->chroma_format_idc = hevc->pic_fields.bits.chroma_format_idc;
+ context->desc.h265.pps->sps->separate_colour_plane_flag =
+ hevc->pic_fields.bits.separate_colour_plane_flag;
+ context->desc.h265.pps->sps->pic_width_in_luma_samples = hevc->pic_width_in_luma_samples;
+ context->desc.h265.pps->sps->pic_height_in_luma_samples = hevc->pic_height_in_luma_samples;
+ context->desc.h265.pps->sps->bit_depth_luma_minus8 = hevc->bit_depth_luma_minus8;
+ context->desc.h265.pps->sps->bit_depth_chroma_minus8 = hevc->bit_depth_chroma_minus8;
+ context->desc.h265.pps->sps->log2_max_pic_order_cnt_lsb_minus4 =
+ hevc->log2_max_pic_order_cnt_lsb_minus4;
+ context->desc.h265.pps->sps->sps_max_dec_pic_buffering_minus1 =
+ hevc->sps_max_dec_pic_buffering_minus1;
+ context->desc.h265.pps->sps->log2_min_luma_coding_block_size_minus3 =
+ hevc->log2_min_luma_coding_block_size_minus3;
+ context->desc.h265.pps->sps->log2_diff_max_min_luma_coding_block_size =
+ hevc->log2_diff_max_min_luma_coding_block_size;
+ context->desc.h265.pps->sps->log2_min_transform_block_size_minus2 =
+ hevc->log2_min_transform_block_size_minus2;
+ context->desc.h265.pps->sps->log2_diff_max_min_transform_block_size =
+ hevc->log2_diff_max_min_transform_block_size;
+ context->desc.h265.pps->sps->max_transform_hierarchy_depth_inter =
+ hevc->max_transform_hierarchy_depth_inter;
+ context->desc.h265.pps->sps->max_transform_hierarchy_depth_intra =
+ hevc->max_transform_hierarchy_depth_intra;
+ context->desc.h265.pps->sps->scaling_list_enabled_flag =
+ hevc->pic_fields.bits.scaling_list_enabled_flag;
+ context->desc.h265.pps->sps->amp_enabled_flag = hevc->pic_fields.bits.amp_enabled_flag;
+ context->desc.h265.pps->sps->sample_adaptive_offset_enabled_flag =
+ hevc->slice_parsing_fields.bits.sample_adaptive_offset_enabled_flag;
+ context->desc.h265.pps->sps->pcm_enabled_flag = hevc->pic_fields.bits.pcm_enabled_flag;
+ if (hevc->pic_fields.bits.pcm_enabled_flag == 1) {
+ context->desc.h265.pps->sps->pcm_sample_bit_depth_luma_minus1 =
+ hevc->pcm_sample_bit_depth_luma_minus1;
+ context->desc.h265.pps->sps->pcm_sample_bit_depth_chroma_minus1 =
+ hevc->pcm_sample_bit_depth_chroma_minus1;
+ context->desc.h265.pps->sps->log2_min_pcm_luma_coding_block_size_minus3 =
+ hevc->log2_min_pcm_luma_coding_block_size_minus3;
+ context->desc.h265.pps->sps->log2_diff_max_min_pcm_luma_coding_block_size =
+ hevc->log2_diff_max_min_pcm_luma_coding_block_size;
+ context->desc.h265.pps->sps->pcm_loop_filter_disabled_flag =
+ hevc->pic_fields.bits.pcm_loop_filter_disabled_flag;
+ }
+ context->desc.h265.pps->sps->num_short_term_ref_pic_sets = hevc->num_short_term_ref_pic_sets;
+ context->desc.h265.pps->sps->long_term_ref_pics_present_flag =
+ hevc->slice_parsing_fields.bits.long_term_ref_pics_present_flag;
+ context->desc.h265.pps->sps->num_long_term_ref_pics_sps = hevc->num_long_term_ref_pic_sps;
+ context->desc.h265.pps->sps->sps_temporal_mvp_enabled_flag =
+ hevc->slice_parsing_fields.bits.sps_temporal_mvp_enabled_flag;
+ context->desc.h265.pps->sps->strong_intra_smoothing_enabled_flag =
+ hevc->pic_fields.bits.strong_intra_smoothing_enabled_flag;
+
+ context->desc.h265.pps->dependent_slice_segments_enabled_flag =
+ hevc->slice_parsing_fields.bits.dependent_slice_segments_enabled_flag;
+ context->desc.h265.pps->output_flag_present_flag =
+ hevc->slice_parsing_fields.bits.output_flag_present_flag;
+ context->desc.h265.pps->num_extra_slice_header_bits = hevc->num_extra_slice_header_bits;
+ context->desc.h265.pps->sign_data_hiding_enabled_flag =
+ hevc->pic_fields.bits.sign_data_hiding_enabled_flag;
+ context->desc.h265.pps->cabac_init_present_flag =
+ hevc->slice_parsing_fields.bits.cabac_init_present_flag;
+ context->desc.h265.pps->num_ref_idx_l0_default_active_minus1 =
+ hevc->num_ref_idx_l0_default_active_minus1;
+ context->desc.h265.pps->num_ref_idx_l1_default_active_minus1 =
+ hevc->num_ref_idx_l1_default_active_minus1;
+ context->desc.h265.pps->init_qp_minus26 = hevc->init_qp_minus26;
+ context->desc.h265.pps->constrained_intra_pred_flag =
+ hevc->pic_fields.bits.constrained_intra_pred_flag;
+ context->desc.h265.pps->transform_skip_enabled_flag =
+ hevc->pic_fields.bits.transform_skip_enabled_flag;
+ context->desc.h265.pps->cu_qp_delta_enabled_flag =
+ hevc->pic_fields.bits.cu_qp_delta_enabled_flag;
+ context->desc.h265.pps->diff_cu_qp_delta_depth = hevc->diff_cu_qp_delta_depth;
+ context->desc.h265.pps->pps_cb_qp_offset = hevc->pps_cb_qp_offset;
+ context->desc.h265.pps->pps_cr_qp_offset = hevc->pps_cr_qp_offset;
+ context->desc.h265.pps->pps_slice_chroma_qp_offsets_present_flag =
+ hevc->slice_parsing_fields.bits.pps_slice_chroma_qp_offsets_present_flag;
+ context->desc.h265.pps->weighted_pred_flag = hevc->pic_fields.bits.weighted_pred_flag;
+ context->desc.h265.pps->weighted_bipred_flag = hevc->pic_fields.bits.weighted_bipred_flag;
+ context->desc.h265.pps->transquant_bypass_enabled_flag =
+ hevc->pic_fields.bits.transquant_bypass_enabled_flag;
+ context->desc.h265.pps->tiles_enabled_flag = hevc->pic_fields.bits.tiles_enabled_flag;
+ context->desc.h265.pps->entropy_coding_sync_enabled_flag =
+ hevc->pic_fields.bits.entropy_coding_sync_enabled_flag;
+ if (hevc->pic_fields.bits.tiles_enabled_flag == 1) {
+ context->desc.h265.pps->num_tile_columns_minus1 = hevc->num_tile_columns_minus1;
+ context->desc.h265.pps->num_tile_rows_minus1 = hevc->num_tile_rows_minus1;
+ for (i = 0 ; i < 19 ; i++)
+ context->desc.h265.pps->column_width_minus1[i] = hevc->column_width_minus1[i];
+ for (i = 0 ; i < 21 ; i++)
+ context->desc.h265.pps->row_height_minus1[i] = hevc->row_height_minus1[i];
+ context->desc.h265.pps->loop_filter_across_tiles_enabled_flag =
+ hevc->pic_fields.bits.loop_filter_across_tiles_enabled_flag;
+ }
+ context->desc.h265.pps->pps_loop_filter_across_slices_enabled_flag =
+ hevc->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag;
+ context->desc.h265.pps->deblocking_filter_override_enabled_flag =
+ hevc->slice_parsing_fields.bits.deblocking_filter_override_enabled_flag;
+ context->desc.h265.pps->pps_deblocking_filter_disabled_flag =
+ hevc->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag;
+ context->desc.h265.pps->pps_beta_offset_div2 = hevc->pps_beta_offset_div2;
+ context->desc.h265.pps->pps_tc_offset_div2 = hevc->pps_tc_offset_div2;
+ context->desc.h265.pps->lists_modification_present_flag =
+ hevc->slice_parsing_fields.bits.lists_modification_present_flag;
+ context->desc.h265.pps->log2_parallel_merge_level_minus2 =
+ hevc->log2_parallel_merge_level_minus2;
+ context->desc.h265.pps->slice_segment_header_extension_present_flag =
+ hevc->slice_parsing_fields.bits.slice_segment_header_extension_present_flag;
+
+ context->desc.h265.IDRPicFlag = hevc->slice_parsing_fields.bits.IdrPicFlag;
+ context->desc.h265.RAPPicFlag = hevc->slice_parsing_fields.bits.RapPicFlag;
+
+ context->desc.h265.CurrPicOrderCntVal = hevc->CurrPic.pic_order_cnt;
+
+ for (i = 0 ; i < 8 ; i++) {
+ context->desc.h265.RefPicSetStCurrBefore[i] = 0xFF;
+ context->desc.h265.RefPicSetStCurrAfter[i] = 0xFF;
+ context->desc.h265.RefPicSetLtCurr[i] = 0xFF;
+ }
+ context->desc.h265.NumPocStCurrBefore = 0;
+ context->desc.h265.NumPocStCurrAfter = 0;
+ context->desc.h265.NumPocLtCurr = 0;
+ unsigned int iBefore = 0;
+ unsigned int iAfter = 0;
+ unsigned int iCurr = 0;
+ for (i = 0 ; i < 15 ; i++) {
+ context->desc.h265.PicOrderCntVal[i] = hevc->ReferenceFrames[i].pic_order_cnt;
+
+ unsigned int index = hevc->ReferenceFrames[i].picture_id & 0x7F;
+
+ if (index == 0x7F)
+ continue;
+
+ vlVaGetReferenceFrame(drv, hevc->ReferenceFrames[i].picture_id, &context->desc.h265.ref[i]);
+
+ if ((hevc->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE) && (iBefore < 8)) {
+ context->desc.h265.RefPicSetStCurrBefore[iBefore++] = i;
+ context->desc.h265.NumPocStCurrBefore++;
+ }
+ if ((hevc->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_AFTER) && (iAfter < 8)) {
+ context->desc.h265.RefPicSetStCurrAfter[iAfter++] = i;
+ context->desc.h265.NumPocStCurrAfter++;
+ }
+ if ((hevc->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_LT_CURR) && (iCurr < 8)) {
+ context->desc.h265.RefPicSetLtCurr[iCurr++] = i;
+ context->desc.h265.NumPocLtCurr++;
+ }
+ }
+}
+
+void vlVaHandleIQMatrixBufferHEVC(vlVaContext *context, vlVaBuffer *buf)
+{
+ VAIQMatrixBufferHEVC *h265 = buf->data;
+
+ assert(buf->size >= sizeof(VAIQMatrixBufferH264) && buf->num_elements == 1);
+ memcpy(&context->desc.h265.pps->sps->ScalingList4x4, h265->ScalingList4x4, 6 * 16);
+ memcpy(&context->desc.h265.pps->sps->ScalingList8x8, h265->ScalingList8x8, 6 * 64);
+ memcpy(&context->desc.h265.pps->sps->ScalingList16x16, h265->ScalingList16x16, 6 * 64);
+ memcpy(&context->desc.h265.pps->sps->ScalingList32x32, h265->ScalingList32x32, 2 * 64);
+ memcpy(&context->desc.h265.pps->sps->ScalingListDCCoeff16x16, h265->ScalingListDC16x16, 6);
+ memcpy(&context->desc.h265.pps->sps->ScalingListDCCoeff32x32, h265->ScalingListDC32x32, 2);
+}
+
+void vlVaHandleSliceParameterBufferHEVC(vlVaContext *context, vlVaBuffer *buf)
+{
+ VASliceParameterBufferHEVC *h265 = buf->data;
+
+ assert(buf->size >= sizeof(VASliceParameterBufferHEVC) && buf->num_elements == 1);
+ for (int i = 0 ; i < 2 ; i++) {
+ for (int j = 0 ; j < 15 ; j++)
+ context->desc.h265.RefPicList[i][j] = h265->RefPicList[i][j];
+ }
+ context->desc.h265.UseRefPicList = true;
+}
diff --git a/src/gallium/state_trackers/va/picture_mpeg12.c b/src/gallium/state_trackers/va/picture_mpeg12.c
new file mode 100644
index 00000000000..e587b1e9c3f
--- /dev/null
+++ b/src/gallium/state_trackers/va/picture_mpeg12.c
@@ -0,0 +1,80 @@
+/**************************************************************************
+ *
+ * Copyright 2014 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "va_private.h"
+
+void vlVaHandlePictureParameterBufferMPEG12(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
+{
+ VAPictureParameterBufferMPEG2 *mpeg2 = buf->data;
+
+ assert(buf->size >= sizeof(VAPictureParameterBufferMPEG2) && buf->num_elements == 1);
+ /*horizontal_size;*/
+ /*vertical_size;*/
+ vlVaGetReferenceFrame(drv, mpeg2->forward_reference_picture, &context->desc.mpeg12.ref[0]);
+ vlVaGetReferenceFrame(drv, mpeg2->backward_reference_picture, &context->desc.mpeg12.ref[1]);
+ context->desc.mpeg12.picture_coding_type = mpeg2->picture_coding_type;
+ context->desc.mpeg12.f_code[0][0] = ((mpeg2->f_code >> 12) & 0xf) - 1;
+ context->desc.mpeg12.f_code[0][1] = ((mpeg2->f_code >> 8) & 0xf) - 1;
+ context->desc.mpeg12.f_code[1][0] = ((mpeg2->f_code >> 4) & 0xf) - 1;
+ context->desc.mpeg12.f_code[1][1] = (mpeg2->f_code & 0xf) - 1;
+ context->desc.mpeg12.intra_dc_precision =
+ mpeg2->picture_coding_extension.bits.intra_dc_precision;
+ context->desc.mpeg12.picture_structure =
+ mpeg2->picture_coding_extension.bits.picture_structure;
+ context->desc.mpeg12.top_field_first =
+ mpeg2->picture_coding_extension.bits.top_field_first;
+ context->desc.mpeg12.frame_pred_frame_dct =
+ mpeg2->picture_coding_extension.bits.frame_pred_frame_dct;
+ context->desc.mpeg12.concealment_motion_vectors =
+ mpeg2->picture_coding_extension.bits.concealment_motion_vectors;
+ context->desc.mpeg12.q_scale_type =
+ mpeg2->picture_coding_extension.bits.q_scale_type;
+ context->desc.mpeg12.intra_vlc_format =
+ mpeg2->picture_coding_extension.bits.intra_vlc_format;
+ context->desc.mpeg12.alternate_scan =
+ mpeg2->picture_coding_extension.bits.alternate_scan;
+ /*repeat_first_field*/
+ /*progressive_frame*/
+ /*is_first_field*/
+}
+
+void vlVaHandleIQMatrixBufferMPEG12(vlVaContext *context, vlVaBuffer *buf)
+{
+ VAIQMatrixBufferMPEG2 *mpeg2 = buf->data;
+
+ assert(buf->size >= sizeof(VAIQMatrixBufferMPEG2) && buf->num_elements == 1);
+ if (mpeg2->load_intra_quantiser_matrix)
+ context->desc.mpeg12.intra_matrix = mpeg2->intra_quantiser_matrix;
+ else
+ context->desc.mpeg12.intra_matrix = NULL;
+
+ if (mpeg2->load_non_intra_quantiser_matrix)
+ context->desc.mpeg12.non_intra_matrix = mpeg2->non_intra_quantiser_matrix;
+ else
+ context->desc.mpeg12.non_intra_matrix = NULL;
+}
+
diff --git a/src/gallium/state_trackers/va/picture_mpeg4.c b/src/gallium/state_trackers/va/picture_mpeg4.c
new file mode 100644
index 00000000000..82659ef7b20
--- /dev/null
+++ b/src/gallium/state_trackers/va/picture_mpeg4.c
@@ -0,0 +1,209 @@
+/**************************************************************************
+ *
+ * Copyright 2014 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "va_private.h"
+
+void vlVaHandlePictureParameterBufferMPEG4(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
+{
+ static const uint8_t default_intra_quant_matrix[64] = { 0 };
+ static const uint8_t default_non_intra_quant_matrix[64] = { 0 };
+
+ VAPictureParameterBufferMPEG4 *mpeg4 = buf->data;
+ unsigned i;
+
+ assert(buf->size >= sizeof(VAPictureParameterBufferMPEG4) && buf->num_elements == 1);
+
+ context->mpeg4.pps = *mpeg4;
+
+ /* vop_width */
+ /* vop_height */
+ /* forward_reference_picture */
+ /* backward_reference_picture */
+ context->desc.mpeg4.short_video_header =
+ mpeg4->vol_fields.bits.short_video_header;
+ /* chroma_format */
+ context->desc.mpeg4.interlaced = mpeg4->vol_fields.bits.interlaced;
+ /* obmc_disable */
+ /* sprite_enable */
+ /* sprite_warping_accuracy */
+ context->desc.mpeg4.quant_type = mpeg4->vol_fields.bits.quant_type;
+ context->desc.mpeg4.quarter_sample = mpeg4->vol_fields.bits.quarter_sample;
+ /* data_partitioned */
+ /* reversible_vlc */
+ context->desc.mpeg4.resync_marker_disable =
+ mpeg4->vol_fields.bits.resync_marker_disable;
+ /* no_of_sprite_warping_points */
+ /* sprite_trajectory_du */
+ /* sprite_trajectory_dv */
+ /* quant_precision */
+ context->desc.mpeg4.vop_coding_type = mpeg4->vop_fields.bits.vop_coding_type;
+ /* backward_reference_vop_coding_type */
+ /* vop_rounding_type */
+ /* intra_dc_vlc_thr */
+ context->desc.mpeg4.top_field_first =
+ mpeg4->vop_fields.bits.top_field_first;
+ context->desc.mpeg4.alternate_vertical_scan_flag =
+ mpeg4->vop_fields.bits.alternate_vertical_scan_flag;
+ context->desc.mpeg4.vop_fcode_forward = mpeg4->vop_fcode_forward;
+ context->desc.mpeg4.vop_fcode_backward = mpeg4->vop_fcode_backward;
+ context->desc.mpeg4.vop_time_increment_resolution =
+ mpeg4->vop_time_increment_resolution;
+ /* num_gobs_in_vop */
+ /* num_macroblocks_in_gob */
+ context->desc.mpeg4.trb[0] = mpeg4->TRB;
+ context->desc.mpeg4.trb[1] = mpeg4->TRB;
+ context->desc.mpeg4.trd[0] = mpeg4->TRD;
+ context->desc.mpeg4.trd[1] = mpeg4->TRD;
+
+ /* default [non-]intra quant matrix because mpv does not set these
+ matrices */
+ if (!context->desc.mpeg4.intra_matrix)
+ context->desc.mpeg4.intra_matrix = default_intra_quant_matrix;
+ if (!context->desc.mpeg4.non_intra_matrix)
+ context->desc.mpeg4.non_intra_matrix = default_non_intra_quant_matrix;
+
+ vlVaGetReferenceFrame(drv, mpeg4->forward_reference_picture, &context->desc.mpeg4.ref[0]);
+ vlVaGetReferenceFrame(drv, mpeg4->backward_reference_picture, &context->desc.mpeg4.ref[1]);
+
+ context->mpeg4.vti_bits = 0;
+ for (i = context->desc.mpeg4.vop_time_increment_resolution; i > 0; i /= 2)
+ ++context->mpeg4.vti_bits;
+}
+
+void vlVaHandleIQMatrixBufferMPEG4(vlVaContext *context, vlVaBuffer *buf)
+{
+ VAIQMatrixBufferMPEG4 *mpeg4 = buf->data;
+
+ assert(buf->size >= sizeof(VAIQMatrixBufferMPEG4) && buf->num_elements == 1);
+ if (mpeg4->load_intra_quant_mat)
+ context->desc.mpeg4.intra_matrix = mpeg4->intra_quant_mat;
+ else
+ context->desc.mpeg4.intra_matrix = NULL;
+
+ if (mpeg4->load_non_intra_quant_mat)
+ context->desc.mpeg4.non_intra_matrix = mpeg4->non_intra_quant_mat;
+ else
+ context->desc.mpeg4.non_intra_matrix = NULL;
+}
+
+void vlVaHandleSliceParameterBufferMPEG4(vlVaContext *context, vlVaBuffer *buf)
+{
+ VASliceParameterBufferMPEG4 *mpeg4 = buf->data;
+
+ assert(buf->size >= sizeof(VASliceParameterBufferMPEG4) && buf->num_elements == 1);
+ context->mpeg4.quant_scale = mpeg4->quant_scale;
+}
+
+struct bit_stream
+{
+ uint8_t *data;
+ unsigned int length; /* bits */
+ unsigned int pos; /* bits */
+};
+
+static inline void
+write_bit(struct bit_stream *writer, unsigned int bit)
+{
+ assert(writer->length > (writer)->pos);
+ writer->data[writer->pos>>3] |= ((bit & 1)<<(7 - (writer->pos & 7)));
+ writer->pos++;
+}
+
+static inline void
+write_bits(struct bit_stream *writer, unsigned int bits, unsigned int len)
+{
+ int i;
+ assert(len <= sizeof(bits)*8);
+ for (i = len - 1; i >= 0; i--)
+ write_bit(writer, bits>>i);
+}
+
+void vlVaDecoderFixMPEG4Startcode(vlVaContext *context)
+{
+ uint8_t vop[] = { 0x00, 0x00, 0x01, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ struct bit_stream bs_vop = {vop, sizeof(vop)*8, 32};
+ unsigned int vop_time_inc;
+ int mod_time;
+ unsigned int vop_size;
+ unsigned int vop_coding_type = context->desc.mpeg4.vop_coding_type;
+
+ context->mpeg4.start_code_size = 0;
+ memset(context->mpeg4.start_code, 0, sizeof(context->mpeg4.start_code));
+ if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_I) {
+ unsigned int vop_time = context->mpeg4.frame_num/
+ context->desc.mpeg4.vop_time_increment_resolution;
+ unsigned int vop_hour = vop_time / 3600;
+ unsigned int vop_minute = (vop_time / 60) % 60;
+ unsigned int vop_second = vop_time % 60;
+ uint8_t group_of_vop[] = { 0x00, 0x00, 0x01, 0xb3, 0x00, 0x00, 0x00 };
+ struct bit_stream bs_gvop = {group_of_vop, sizeof(group_of_vop)*8, 32};
+
+ write_bits(&bs_gvop, vop_hour, 5);
+ write_bits(&bs_gvop, vop_minute, 6);
+ write_bit(&bs_gvop, 1); /* marker_bit */
+ write_bits(&bs_gvop, vop_second, 6);
+ write_bit(&bs_gvop, 0); /* closed_gov */ /* TODO replace magic */
+ write_bit(&bs_gvop, 0); /* broken_link */
+ write_bit(&bs_gvop, 0); /* padding */
+ write_bits(&bs_gvop, 7, 3); /* padding */
+
+ memcpy(context->mpeg4.start_code, group_of_vop, sizeof(group_of_vop));
+ context->mpeg4.start_code_size += sizeof(group_of_vop);
+ }
+
+ write_bits(&bs_vop, vop_coding_type, 2);
+ mod_time = context->mpeg4.frame_num %
+ context->desc.mpeg4.vop_time_increment_resolution == 0 &&
+ vop_coding_type+1 != PIPE_MPEG12_PICTURE_CODING_TYPE_I;
+ while (mod_time--)
+ write_bit(&bs_vop, 1); /* modulo_time_base */
+ write_bit(&bs_vop, 0); /* modulo_time_base */
+
+ write_bit(&bs_vop, 1); /* marker_bit */
+ vop_time_inc = context->mpeg4.frame_num %
+ context->desc.mpeg4.vop_time_increment_resolution;
+ write_bits(&bs_vop, vop_time_inc, context->mpeg4.vti_bits);
+ write_bit(&bs_vop, 1); /* marker_bit */
+ write_bit(&bs_vop, 1); /* vop_coded */
+ if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_P)
+ write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.vop_rounding_type);
+ write_bits(&bs_vop, context->mpeg4.pps.vop_fields.bits.intra_dc_vlc_thr, 3);
+ if (context->mpeg4.pps.vol_fields.bits.interlaced) {
+ write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.top_field_first);
+ write_bit(&bs_vop, context->mpeg4.pps.vop_fields.bits.alternate_vertical_scan_flag);
+ }
+
+ write_bits(&bs_vop, context->mpeg4.quant_scale, context->mpeg4.pps.quant_precision);
+ if (vop_coding_type+1 != PIPE_MPEG12_PICTURE_CODING_TYPE_I)
+ write_bits(&bs_vop, context->desc.mpeg4.vop_fcode_forward, 3);
+ if (vop_coding_type+1 == PIPE_MPEG12_PICTURE_CODING_TYPE_B)
+ write_bits(&bs_vop, context->desc.mpeg4.vop_fcode_backward, 3);
+
+ vop_size = bs_vop.pos/8;
+ memcpy(context->mpeg4.start_code + context->mpeg4.start_code_size, vop, vop_size);
+ context->mpeg4.start_code_size += vop_size;
+}
diff --git a/src/gallium/state_trackers/va/picture_vc1.c b/src/gallium/state_trackers/va/picture_vc1.c
new file mode 100644
index 00000000000..f95fd8344f5
--- /dev/null
+++ b/src/gallium/state_trackers/va/picture_vc1.c
@@ -0,0 +1,67 @@
+/**************************************************************************
+ *
+ * Copyright 2014 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "va_private.h"
+
+void vlVaHandlePictureParameterBufferVC1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
+{
+ VAPictureParameterBufferVC1 * vc1 = buf->data;
+
+ assert(buf->size >= sizeof(VAPictureParameterBufferVC1) && buf->num_elements == 1);
+ vlVaGetReferenceFrame(drv, vc1->forward_reference_picture, &context->desc.vc1.ref[0]);
+ vlVaGetReferenceFrame(drv, vc1->backward_reference_picture, &context->desc.vc1.ref[1]);
+ context->desc.vc1.picture_type = vc1->picture_fields.bits.picture_type;
+ context->desc.vc1.frame_coding_mode = vc1->picture_fields.bits.frame_coding_mode;
+ context->desc.vc1.postprocflag = vc1->post_processing != 0;
+ context->desc.vc1.pulldown = vc1->sequence_fields.bits.pulldown;
+ context->desc.vc1.interlace = vc1->sequence_fields.bits.interlace;
+ context->desc.vc1.tfcntrflag = vc1->sequence_fields.bits.tfcntrflag;
+ context->desc.vc1.finterpflag = vc1->sequence_fields.bits.finterpflag;
+ context->desc.vc1.psf = vc1->sequence_fields.bits.psf;
+ context->desc.vc1.dquant = vc1->pic_quantizer_fields.bits.dquant;
+ context->desc.vc1.panscan_flag = vc1->entrypoint_fields.bits.panscan_flag;
+ context->desc.vc1.refdist_flag =
+ vc1->reference_fields.bits.reference_distance_flag;
+ context->desc.vc1.quantizer = vc1->pic_quantizer_fields.bits.quantizer;
+ context->desc.vc1.extended_mv = vc1->mv_fields.bits.extended_mv_flag;
+ context->desc.vc1.extended_dmv = vc1->mv_fields.bits.extended_dmv_flag;
+ context->desc.vc1.overlap = vc1->sequence_fields.bits.overlap;
+ context->desc.vc1.vstransform =
+ vc1->transform_fields.bits.variable_sized_transform_flag;
+ context->desc.vc1.loopfilter = vc1->entrypoint_fields.bits.loopfilter;
+ context->desc.vc1.fastuvmc = vc1->fast_uvmc_flag;
+ context->desc.vc1.range_mapy_flag = vc1->range_mapping_fields.bits.luma_flag;
+ context->desc.vc1.range_mapy = vc1->range_mapping_fields.bits.luma;
+ context->desc.vc1.range_mapuv_flag = vc1->range_mapping_fields.bits.chroma_flag;
+ context->desc.vc1.range_mapuv = vc1->range_mapping_fields.bits.chroma;
+ context->desc.vc1.multires = vc1->sequence_fields.bits.multires;
+ context->desc.vc1.syncmarker = vc1->sequence_fields.bits.syncmarker;
+ context->desc.vc1.rangered = vc1->sequence_fields.bits.rangered;
+ context->desc.vc1.maxbframes = vc1->sequence_fields.bits.max_b_frames;
+ context->desc.vc1.deblockEnable = vc1->post_processing != 0;
+ context->desc.vc1.pquant = vc1->pic_quantizer_fields.bits.pic_quantizer_scale;
+}
diff --git a/src/gallium/state_trackers/va/postproc.c b/src/gallium/state_trackers/va/postproc.c
new file mode 100644
index 00000000000..1fdb4e79f4c
--- /dev/null
+++ b/src/gallium/state_trackers/va/postproc.c
@@ -0,0 +1,94 @@
+/**************************************************************************
+ *
+ * Copyright 2015 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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_video_codec.h"
+
+#include "util/u_handle_table.h"
+//#include "util/u_video.h"
+
+//#include "vl/vl_vlc.h"
+//#include "vl/vl_winsys.h"
+
+#include "va_private.h"
+
+VAStatus
+vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
+{
+ struct u_rect src_rect;
+ struct u_rect dst_rect;
+ vlVaSurface *src_surface;
+ VAProcPipelineParameterBuffer *pipeline_param;
+ struct pipe_surface **surfaces;
+ struct pipe_screen *screen;
+ struct pipe_surface *psurf;
+
+ if (!drv || !context)
+ return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+ if (!buf || !buf->data)
+ return VA_STATUS_ERROR_INVALID_BUFFER;
+
+ if (!context->target)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ pipeline_param = (VAProcPipelineParameterBuffer *)buf->data;
+
+ src_surface = handle_table_get(drv->htab, pipeline_param->surface);
+ if (!src_surface || !src_surface->buffer)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ surfaces = context->target->get_surfaces(context->target);
+
+ if (!surfaces || !surfaces[0])
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ screen = drv->pipe->screen;
+
+ psurf = surfaces[0];
+
+ src_rect.x0 = pipeline_param->surface_region->x;
+ src_rect.y0 = pipeline_param->surface_region->y;
+ src_rect.x1 = pipeline_param->surface_region->x + pipeline_param->surface_region->width;
+ src_rect.y1 = pipeline_param->surface_region->y + pipeline_param->surface_region->height;
+
+ dst_rect.x0 = pipeline_param->output_region->x;
+ dst_rect.y0 = pipeline_param->output_region->y;
+ dst_rect.x1 = pipeline_param->output_region->x + pipeline_param->output_region->width;
+ dst_rect.y1 = pipeline_param->output_region->y + pipeline_param->output_region->height;
+
+ vl_compositor_clear_layers(&drv->cstate);
+ vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src_surface->buffer, &src_rect, NULL, VL_COMPOSITOR_WEAVE);
+ vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dst_rect);
+ vl_compositor_render(&drv->cstate, &drv->compositor, psurf, NULL, false);
+
+ screen->fence_reference(screen, &src_surface->fence, NULL);
+ drv->pipe->flush(drv->pipe, &src_surface->fence, 0);
+
+ return VA_STATUS_SUCCESS;
+}
+
+
diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
index 2b645d08a03..6739efc8c3b 100644
--- a/src/gallium/state_trackers/va/va_private.h
+++ b/src/gallium/state_trackers/va/va_private.h
@@ -148,6 +148,13 @@ PipeToProfile(enum pipe_video_profile profile)
case PIPE_VIDEO_PROFILE_HEVC_MAIN:
return VAProfileHEVCMain;
case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
+ case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
+ case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422:
+ case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444:
+ case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
+ case PIPE_VIDEO_PROFILE_HEVC_MAIN_12:
+ case PIPE_VIDEO_PROFILE_HEVC_MAIN_STILL:
+ case PIPE_VIDEO_PROFILE_HEVC_MAIN_444:
case PIPE_VIDEO_PROFILE_UNKNOWN:
return VAProfileNone;
default:
@@ -208,7 +215,7 @@ typedef struct {
} vlVaSubpicture;
typedef struct {
- struct pipe_video_codec *decoder;
+ struct pipe_video_codec templat, *decoder;
struct pipe_video_buffer *target;
union {
struct pipe_picture_desc base;
@@ -340,4 +347,22 @@ VAStatus vlVaQueryVideoProcFilterCaps(VADriverContextP ctx, VAContextID context,
void *filter_caps, unsigned int *num_filter_caps);
VAStatus vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, VAContextID context, VABufferID *filters,
unsigned int num_filters, VAProcPipelineCaps *pipeline_cap);
+
+// internal functions
+VAStatus vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
+void vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, struct pipe_video_buffer **ref_frame);
+void vlVaHandlePictureParameterBufferMPEG12(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandleIQMatrixBufferMPEG12(vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandlePictureParameterBufferH264(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandleIQMatrixBufferH264(vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandleSliceParameterBufferH264(vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandlePictureParameterBufferVC1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandlePictureParameterBufferMPEG4(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandleIQMatrixBufferMPEG4(vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandleSliceParameterBufferMPEG4(vlVaContext *context, vlVaBuffer *buf);
+void vlVaDecoderFixMPEG4Startcode(vlVaContext *context);
+void vlVaHandlePictureParameterBufferHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandleIQMatrixBufferHEVC(vlVaContext *context, vlVaBuffer *buf);
+void vlVaHandleSliceParameterBufferHEVC(vlVaContext *context, vlVaBuffer *buf);
+
#endif //VA_PRIVATE_H
diff --git a/src/gallium/state_trackers/wgl/Makefile.sources b/src/gallium/state_trackers/wgl/Makefile.sources
index 1e00caf97b7..2630b445d54 100644
--- a/src/gallium/state_trackers/wgl/Makefile.sources
+++ b/src/gallium/state_trackers/wgl/Makefile.sources
@@ -5,6 +5,7 @@ C_SOURCES := \
stw_ext_extensionsstring.c \
stw_ext_pbuffer.c \
stw_ext_pixelformat.c \
+ stw_ext_rendertexture.c \
stw_ext_swapinterval.c \
stw_framebuffer.c \
stw_getprocaddress.c \
diff --git a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
index a8c085a1341..86b93fb2e28 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
@@ -41,6 +41,7 @@ static const char *stw_extension_string =
"WGL_ARB_multisample "
"WGL_ARB_pbuffer "
"WGL_ARB_pixel_format "
+ "WGL_ARB_render_texture "
"WGL_EXT_create_context_es_profile "
"WGL_EXT_create_context_es2_profile "
/* "WGL_EXT_swap_interval " */
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
index c99fa3e513d..d709faa60f2 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
@@ -86,6 +86,9 @@ wglCreatePbufferARB(HDC hCurrentDC,
int iDisplayablePixelFormat;
PIXELFORMATDESCRIPTOR pfd;
BOOL bRet;
+ int textureFormat = WGL_NO_TEXTURE_ARB;
+ int textureTarget = WGL_NO_TEXTURE_ARB;
+ BOOL textureMipmap = FALSE;
info = stw_pixelformat_get_info(iPixelFormat - 1);
if (!info) {
@@ -104,8 +107,38 @@ wglCreatePbufferARB(HDC hCurrentDC,
piAttrib++;
useLargest = *piAttrib;
break;
+ case WGL_TEXTURE_FORMAT_ARB:
+ /* WGL_ARB_render_texture */
+ piAttrib++;
+ textureFormat = *piAttrib;
+ if (textureFormat != WGL_TEXTURE_RGB_ARB &&
+ textureFormat != WGL_TEXTURE_RGBA_ARB &&
+ textureFormat != WGL_NO_TEXTURE_ARB) {
+ SetLastError(ERROR_INVALID_DATA);
+ return 0;
+ }
+ break;
+ case WGL_TEXTURE_TARGET_ARB:
+ /* WGL_ARB_render_texture */
+ piAttrib++;
+ textureTarget = *piAttrib;
+ if (textureTarget != WGL_TEXTURE_CUBE_MAP_ARB &&
+ textureTarget != WGL_TEXTURE_1D_ARB &&
+ textureTarget != WGL_TEXTURE_2D_ARB &&
+ textureTarget != WGL_NO_TEXTURE_ARB) {
+ SetLastError(ERROR_INVALID_DATA);
+ return 0;
+ }
+ break;
+ case WGL_MIPMAP_TEXTURE_ARB:
+ /* WGL_ARB_render_texture */
+ piAttrib++;
+ textureMipmap = !!*piAttrib;
+ break;
default:
SetLastError(ERROR_INVALID_DATA);
+ debug_printf("wgl: Unsupported attribute 0x%x in %s\n",
+ *piAttrib, __func__);
return 0;
}
}
@@ -220,6 +253,12 @@ wglCreatePbufferARB(HDC hCurrentDC,
}
fb->bPbuffer = TRUE;
+
+ /* WGL_ARB_render_texture fields */
+ fb->textureTarget = textureTarget;
+ fb->textureFormat = textureFormat;
+ fb->textureMipmap = textureMipmap;
+
iDisplayablePixelFormat = fb->iDisplayablePixelFormat;
stw_framebuffer_unlock(fb);
@@ -246,7 +285,7 @@ wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
return NULL;
}
- fb = (struct stw_framebuffer *)hPbuffer;
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
hDC = GetDC(fb->hWnd);
@@ -265,7 +304,7 @@ wglReleasePbufferDCARB(HPBUFFERARB hPbuffer,
return 0;
}
- fb = (struct stw_framebuffer *)hPbuffer;
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
return ReleaseDC(fb->hWnd, hDC);
}
@@ -281,7 +320,7 @@ wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
return FALSE;
}
- fb = (struct stw_framebuffer *)hPbuffer;
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
/* This will destroy all our data */
return DestroyWindow(fb->hWnd);
@@ -300,7 +339,7 @@ wglQueryPbufferARB(HPBUFFERARB hPbuffer,
return FALSE;
}
- fb = (struct stw_framebuffer *)hPbuffer;
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
switch (iAttribute) {
case WGL_PBUFFER_WIDTH_ARB:
@@ -313,6 +352,22 @@ wglQueryPbufferARB(HPBUFFERARB hPbuffer,
/* We assume that no content is ever lost due to display mode change */
*piValue = FALSE;
return TRUE;
+ /* WGL_ARB_render_texture */
+ case WGL_TEXTURE_TARGET_ARB:
+ *piValue = fb->textureTarget;
+ return TRUE;
+ case WGL_TEXTURE_FORMAT_ARB:
+ *piValue = fb->textureFormat;
+ return TRUE;
+ case WGL_MIPMAP_TEXTURE_ARB:
+ *piValue = fb->textureMipmap;
+ return TRUE;
+ case WGL_MIPMAP_LEVEL_ARB:
+ *piValue = fb->textureLevel;
+ return TRUE;
+ case WGL_CUBE_MAP_FACE_ARB:
+ *piValue = fb->textureFace + WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
+ return TRUE;
default:
SetLastError(ERROR_INVALID_DATA);
return FALSE;
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
index e38086e86d7..4ee4fcdd5ad 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
@@ -107,6 +107,16 @@ stw_query_attrib(
case WGL_NUMBER_UNDERLAYS_ARB:
*pvalue = 0;
return TRUE;
+
+ case WGL_BIND_TO_TEXTURE_RGB_ARB:
+ /* WGL_ARB_render_texture */
+ *pvalue = pfi->bindToTextureRGB;
+ return TRUE;
+
+ case WGL_BIND_TO_TEXTURE_RGBA_ARB:
+ /* WGL_ARB_render_texture */
+ *pvalue = pfi->bindToTextureRGBA;
+ return TRUE;
}
if (iLayerPlane != 0)
@@ -311,7 +321,11 @@ static const struct attrib_match_info attrib_match[] = {
/* WGL_ARB_multisample */
{ WGL_SAMPLE_BUFFERS_ARB, 2, FALSE },
- { WGL_SAMPLES_ARB, 2, FALSE }
+ { WGL_SAMPLES_ARB, 2, FALSE },
+
+ /* WGL_ARB_render_texture */
+ { WGL_BIND_TO_TEXTURE_RGB_ARB, 0, FALSE },
+ { WGL_BIND_TO_TEXTURE_RGBA_ARB, 0, FALSE },
};
struct stw_pixelformat_score
diff --git a/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c b/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c
new file mode 100644
index 00000000000..18df2ebd1fa
--- /dev/null
+++ b/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c
@@ -0,0 +1,252 @@
+/**************************************************************************
+ * Copyright 2015 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
+
+#define WGL_WGLEXT_PROTOTYPES
+
+#include
+#include
+
+#include "state_tracker/st_copytex.h"
+
+#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_state.h"
+
+#include "stw_icd.h"
+#include "stw_context.h"
+#include "stw_device.h"
+#include "stw_pixelformat.h"
+#include "stw_framebuffer.h"
+#include "stw_st.h"
+
+
+/** Translate a WGL buffer name to a GLenum */
+static GLenum
+translate_ibuffer(int iBuffer)
+{
+ switch (iBuffer) {
+ case WGL_FRONT_LEFT_ARB:
+ return GL_FRONT_LEFT;
+ case WGL_BACK_LEFT_ARB:
+ return GL_BACK_LEFT;
+ case WGL_FRONT_RIGHT_ARB:
+ return GL_FRONT_RIGHT;
+ case WGL_BACK_RIGHT_ARB:
+ return GL_BACK_RIGHT;
+ case WGL_AUX0_ARB:
+ return GL_AUX0;
+ default:
+ return GL_NONE;
+ }
+}
+
+
+/** Translate a WGL texture target type to a GLenum */
+static GLenum
+translate_target(unsigned textureTarget)
+{
+ switch (textureTarget) {
+ case WGL_TEXTURE_1D_ARB:
+ return GL_TEXTURE_1D;
+ case WGL_TEXTURE_2D_ARB:
+ return GL_TEXTURE_2D;
+ case WGL_TEXTURE_CUBE_MAP_ARB:
+ return GL_TEXTURE_CUBE_MAP;
+ case WGL_NO_TEXTURE_ARB:
+ default:
+ return GL_NONE;
+ }
+}
+
+
+/** Translate a WGL texture format to a GLenum */
+static GLenum
+translate_texture_format(unsigned wgl_format)
+{
+ switch (wgl_format) {
+ case WGL_TEXTURE_RGB_ARB:
+ return GL_RGB;
+ case WGL_TEXTURE_RGBA_ARB:
+ return GL_RGBA;
+ case WGL_NO_TEXTURE_ARB:
+ default:
+ return GL_NONE;
+ }
+}
+
+
+BOOL WINAPI
+wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
+{
+ HDC prevDrawable = stw_get_current_dc();
+ struct stw_context *curctx = stw_current_context();
+ struct stw_framebuffer *fb;
+ GLenum texFormat, srcBuffer, target;
+ boolean retVal;
+ int pixelFormatSave;
+
+ /*
+ * Implementation notes:
+ * Ideally, we'd implement this function with the
+ * st_context_iface::teximage() function which replaces a specific
+ * texture image with a different resource (the pbuffer).
+ * The main problem however, is the pbuffer image is upside down relative
+ * to the texture image.
+ * Window system drawing surfaces (windows & pbuffers) are "top to bottom"
+ * while OpenGL texture images are "bottom to top". One possible solution
+ * to this is to invert rendering to pbuffers (as we do for renderbuffers)
+ * but that could lead to other issues (and would require extensive
+ * testing).
+ *
+ * The simple alternative is to use a copy-based approach which copies the
+ * pbuffer image into the texture via glCopyTex[Sub]Image. That's what
+ * we do here.
+ */
+
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
+ if (!fb) {
+ debug_printf("Invalid pbuffer handle in wglBindTexImageARB()\n");
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ srcBuffer = translate_ibuffer(iBuffer);
+ if (srcBuffer == GL_NONE) {
+ debug_printf("Invalid buffer 0x%x in wglBindTexImageARB()\n", iBuffer);
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ target = translate_target(fb->textureTarget);
+ if (target == GL_NONE) {
+ debug_printf("no texture target in wglBindTexImageARB()\n");
+ return FALSE;
+ }
+
+ texFormat = translate_texture_format(fb->textureFormat);
+ if (texFormat == GL_NONE) {
+ debug_printf("no texture format in wglBindTexImageARB()\n");
+ return FALSE;
+ }
+
+ /*
+ * Bind the pbuffer surface so we can read/copy from it.
+ *
+ * Before we can call stw_make_current() we have to temporarily
+ * change the pbuffer's pixel format to match the context to avoid
+ * an error condition. After the stw_make_current() we restore the
+ * buffer's pixel format.
+ */
+ pixelFormatSave = fb->iPixelFormat;
+ fb->iPixelFormat = curctx->iPixelFormat;
+ retVal = stw_make_current(wglGetPbufferDCARB(hPbuffer), curctx->dhglrc);
+ fb->iPixelFormat = pixelFormatSave;
+ if (!retVal) {
+ debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n");
+ return FALSE;
+ }
+
+ st_copy_framebuffer_to_texture(srcBuffer, fb->width, fb->height,
+ target, fb->textureLevel,
+ fb->textureFace, texFormat);
+
+ /* rebind previous drawing surface */
+ retVal = stw_make_current(prevDrawable, curctx->dhglrc);
+ if (!retVal) {
+ debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n");
+ }
+
+ return retVal;
+}
+
+
+BOOL WINAPI
+wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
+{
+ struct stw_framebuffer *fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
+ GLenum srcBuffer;
+
+ /* nothing to do here, but we do error checking anyway */
+
+ if (!fb) {
+ debug_printf("Invalid pbuffer handle in wglReleaseTexImageARB()\n");
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ srcBuffer = translate_ibuffer(iBuffer);
+ if (srcBuffer == GL_NONE) {
+ debug_printf("Invalid buffer 0x%x in wglReleaseTexImageARB()\n", iBuffer);
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOL WINAPI
+wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int *piAttribList)
+{
+ struct stw_framebuffer *fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
+ int face, i;
+
+ if (!fb) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ for (i = 0; piAttribList[i]; i += 2) {
+ switch (piAttribList[i]) {
+ case WGL_MIPMAP_LEVEL_ARB:
+ fb->textureLevel = piAttribList[i+1];
+ break;
+ case WGL_CUBE_MAP_FACE_ARB:
+ face = piAttribList[i+1];
+ if (face >= WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ face <= WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ fb->textureFace = face - WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
+ }
+ else {
+ debug_printf("Invalid cube face 0x%x in "
+ "wglSetPbufferAttribARB()\n",
+ piAttribList[i]);
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+ break;
+ default:
+ debug_printf("Invalid attribute 0x%x in wglSetPbufferAttribARB()\n",
+ piAttribList[i]);
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h
index 109c79dd002..0e2c61ffe3e 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h
@@ -30,6 +30,9 @@
#include
+#include
+#include
+
#include "util/u_debug.h"
@@ -85,6 +88,15 @@ struct stw_framebuffer
unsigned width;
unsigned height;
+ /** WGL_ARB_render_texture - set at Pbuffer creation time */
+ unsigned textureFormat; /**< WGL_NO_TEXTURE or WGL_TEXTURE_RGB[A]_ARB */
+ unsigned textureTarget; /**< WGL_NO_TEXTURE or WGL_TEXTURE_1D/2D/
+ CUBE_MAP_ARB */
+ boolean textureMipmap; /**< TRUE/FALSE */
+ /** WGL_ARB_render_texture - set with wglSetPbufferAttribARB() */
+ unsigned textureLevel;
+ unsigned textureFace; /**< [0..6] */
+
/**
* Client area rectangle, relative to the window upper-left corner.
*
@@ -177,4 +189,19 @@ stw_framebuffer_unlock(struct stw_framebuffer *fb)
void
stw_framebuffer_cleanup(void);
+
+static inline struct stw_st_framebuffer *
+stw_st_framebuffer(struct st_framebuffer_iface *stfb)
+{
+ return (struct stw_st_framebuffer *) stfb;
+}
+
+
+static inline struct stw_framebuffer *
+stw_framebuffer_from_HPBUFFERARB(HPBUFFERARB hPbuffer)
+{
+ return (struct stw_framebuffer *) hPbuffer;
+}
+
+
#endif /* STW_FRAMEBUFFER_H */
diff --git a/src/gallium/state_trackers/wgl/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
index 28d10d2e312..66718c59eb3 100644
--- a/src/gallium/state_trackers/wgl/stw_getprocaddress.c
+++ b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
@@ -74,6 +74,11 @@ static const struct stw_extension_entry stw_extension_entries[] = {
/* WGL_ARB_create_context */
STW_EXTENSION_ENTRY( wglCreateContextAttribsARB ),
+ /* WGL_ARB_render_texture */
+ STW_EXTENSION_ENTRY( wglBindTexImageARB ),
+ STW_EXTENSION_ENTRY( wglReleaseTexImageARB ),
+ STW_EXTENSION_ENTRY( wglSetPbufferAttribARB ),
+
{ NULL, NULL }
};
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index ef6158d3645..5360a8f6036 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -205,6 +205,12 @@ stw_pixelformat_add(
pfi->stvis.samples = samples;
pfi->stvis.render_buffer = ST_ATTACHMENT_INVALID;
+ /* WGL_ARB_render_texture */
+ if (color->bits.alpha)
+ pfi->bindToTextureRGBA = TRUE;
+ else
+ pfi->bindToTextureRGB = TRUE;
+
++stw_dev->pixelformat_extended_count;
if(!extended) {
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.h b/src/gallium/state_trackers/wgl/stw_pixelformat.h
index 58ef7442ab8..06753b09e16 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.h
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.h
@@ -43,6 +43,10 @@ struct stw_pixelformat_info
PIXELFORMATDESCRIPTOR pfd;
struct st_visual stvis;
+
+ /** WGL_ARB_render_texture */
+ boolean bindToTextureRGB;
+ boolean bindToTextureRGBA;
};
void
diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c
index 78586db1969..20c2c8a09ca 100644
--- a/src/gallium/state_trackers/wgl/stw_st.c
+++ b/src/gallium/state_trackers/wgl/stw_st.c
@@ -46,11 +46,6 @@ struct stw_st_framebuffer {
unsigned texture_mask;
};
-static inline struct stw_st_framebuffer *
-stw_st_framebuffer(struct st_framebuffer_iface *stfb)
-{
- return (struct stw_st_framebuffer *) stfb;
-}
/**
diff --git a/src/gallium/state_trackers/xa/xa_tracker.c b/src/gallium/state_trackers/xa/xa_tracker.c
index faa630c144b..d57464b7d60 100644
--- a/src/gallium/state_trackers/xa/xa_tracker.c
+++ b/src/gallium/state_trackers/xa/xa_tracker.c
@@ -152,11 +152,15 @@ xa_tracker_create(int drm_fd)
struct xa_tracker *xa = calloc(1, sizeof(struct xa_tracker));
enum xa_surface_type stype;
unsigned int num_formats;
+ int fd = -1;
if (!xa)
return NULL;
- if (pipe_loader_drm_probe_fd(&xa->dev, dup(drm_fd)))
+ if (drm_fd < 0 || (fd = dup(drm_fd)) < 0)
+ goto out_no_fd;
+
+ if (pipe_loader_drm_probe_fd(&xa->dev, fd))
xa->screen = pipe_loader_create_screen(xa->dev);
if (!xa->screen)
@@ -208,6 +212,9 @@ xa_tracker_create(int drm_fd)
out_no_screen:
if (xa->dev)
pipe_loader_release(&xa->dev, 1);
+ fd = -1;
+ out_no_fd:
+ close(fd);
free(xa);
return NULL;
}
diff --git a/src/gallium/state_trackers/xvmc/tests/test_blocks.c b/src/gallium/state_trackers/xvmc/tests/test_blocks.c
index a35838f3309..53c29bc5ae1 100644
--- a/src/gallium/state_trackers/xvmc/tests/test_blocks.c
+++ b/src/gallium/state_trackers/xvmc/tests/test_blocks.c
@@ -25,6 +25,8 @@
*
**************************************************************************/
+/* Force assertions, even on release builds. */
+#undef NDEBUG
#include
#include
#include
diff --git a/src/gallium/state_trackers/xvmc/tests/test_context.c b/src/gallium/state_trackers/xvmc/tests/test_context.c
index 344ac76decc..81d26fcffd5 100644
--- a/src/gallium/state_trackers/xvmc/tests/test_context.c
+++ b/src/gallium/state_trackers/xvmc/tests/test_context.c
@@ -25,6 +25,8 @@
*
**************************************************************************/
+/* Force assertions, even on release builds. */
+#undef NDEBUG
#include
#include
#include
diff --git a/src/gallium/state_trackers/xvmc/tests/test_rendering.c b/src/gallium/state_trackers/xvmc/tests/test_rendering.c
index b3b3794810d..c5494ecc8c2 100644
--- a/src/gallium/state_trackers/xvmc/tests/test_rendering.c
+++ b/src/gallium/state_trackers/xvmc/tests/test_rendering.c
@@ -25,6 +25,8 @@
*
**************************************************************************/
+/* Force assertions, even on release builds. */
+#undef NDEBUG
#include
#include
#include
diff --git a/src/gallium/state_trackers/xvmc/tests/test_subpicture.c b/src/gallium/state_trackers/xvmc/tests/test_subpicture.c
index 57ba1c75138..006972fa8ee 100644
--- a/src/gallium/state_trackers/xvmc/tests/test_subpicture.c
+++ b/src/gallium/state_trackers/xvmc/tests/test_subpicture.c
@@ -25,6 +25,8 @@
*
**************************************************************************/
+/* Force assertions, even on release builds. */
+#undef NDEBUG
#include
#include
#include
diff --git a/src/gallium/state_trackers/xvmc/tests/test_surface.c b/src/gallium/state_trackers/xvmc/tests/test_surface.c
index 964ca82c506..d5a121d5ab0 100644
--- a/src/gallium/state_trackers/xvmc/tests/test_surface.c
+++ b/src/gallium/state_trackers/xvmc/tests/test_surface.c
@@ -25,6 +25,8 @@
*
**************************************************************************/
+/* Force assertions, even on release builds. */
+#undef NDEBUG
#include
#include
#include
diff --git a/src/gallium/targets/d3dadapter9/Makefile.am b/src/gallium/targets/d3dadapter9/Makefile.am
index d1d9829b6c5..8b279383b3c 100644
--- a/src/gallium/targets/d3dadapter9/Makefile.am
+++ b/src/gallium/targets/d3dadapter9/Makefile.am
@@ -62,7 +62,6 @@ endif # HAVE_LD_VERSION_SCRIPT
d3dadapter9_la_LIBADD = \
$(top_builddir)/src/gallium/auxiliary/libgalliumvl_stub.la \
$(top_builddir)/src/gallium/auxiliary/libgallium.la \
- $(top_builddir)/src/glsl/libnir.la \
$(top_builddir)/src/gallium/state_trackers/nine/libninetracker.la \
$(top_builddir)/src/util/libmesautil.la \
$(EXPAT_LIBS) \
@@ -87,10 +86,6 @@ include $(top_srcdir)/src/gallium/drivers/radeonsi/Automake.inc
include $(top_srcdir)/src/gallium/drivers/svga/Automake.inc
-include $(top_srcdir)/src/gallium/drivers/freedreno/Automake.inc
-
-include $(top_srcdir)/src/gallium/drivers/vc4/Automake.inc
-
include $(top_srcdir)/src/gallium/drivers/softpipe/Automake.inc
include $(top_srcdir)/src/gallium/drivers/llvmpipe/Automake.inc
diff --git a/src/gallium/targets/d3dadapter9/drm.c b/src/gallium/targets/d3dadapter9/drm.c
index ad712db05eb..5cd1ba7815c 100644
--- a/src/gallium/targets/d3dadapter9/drm.c
+++ b/src/gallium/targets/d3dadapter9/drm.c
@@ -31,6 +31,7 @@
#include "pipe/p_state.h"
#include "target-helpers/drm_helper.h"
+#include "target-helpers/sw_helper.h"
#include "state_tracker/drm_driver.h"
#include "d3dadapter/d3dadapter9.h"
diff --git a/src/gallium/targets/dri/target.c b/src/gallium/targets/dri/target.c
index d6fbd01b88f..01532e242b8 100644
--- a/src/gallium/targets/dri/target.c
+++ b/src/gallium/targets/dri/target.c
@@ -1,4 +1,5 @@
#include "target-helpers/drm_helper.h"
+#include "target-helpers/sw_helper.h"
#include "dri_screen.h"
diff --git a/src/gallium/targets/libgl-xlib/SConscript b/src/gallium/targets/libgl-xlib/SConscript
index df5a220ac25..687a8b9d3ed 100644
--- a/src/gallium/targets/libgl-xlib/SConscript
+++ b/src/gallium/targets/libgl-xlib/SConscript
@@ -46,9 +46,13 @@ if env['llvm']:
env.Append(CPPDEFINES = ['GALLIUM_LLVMPIPE'])
env.Prepend(LIBS = [llvmpipe])
-# Disallow undefined symbols
if env['platform'] != 'darwin':
- env.Append(SHLINKFLAGS = ['-Wl,-z,defs'])
+ env.Append(SHLINKFLAGS = [
+ # Disallow undefined symbols
+ '-Wl,-z,defs',
+ # Restrict exported symbols
+ '-Wl,--version-script=%s' % File("libgl-xlib.sym").srcnode().path,
+ ])
# libGL.so.1.5
libgl_1_5 = env.SharedLibrary(
diff --git a/src/gallium/targets/omx/target.c b/src/gallium/targets/omx/target.c
index 42b1346d341..308e23bb4a0 100644
--- a/src/gallium/targets/omx/target.c
+++ b/src/gallium/targets/omx/target.c
@@ -1 +1,2 @@
#include "target-helpers/drm_helper.h"
+#include "target-helpers/sw_helper.h"
diff --git a/src/gallium/targets/opencl/Makefile.am b/src/gallium/targets/opencl/Makefile.am
index 3cb29766724..08f95e8074c 100644
--- a/src/gallium/targets/opencl/Makefile.am
+++ b/src/gallium/targets/opencl/Makefile.am
@@ -20,7 +20,7 @@ lib@OPENCL_LIBNAME@_la_LIBADD = \
$(top_builddir)/src/gallium/auxiliary/libgallium.la \
$(top_builddir)/src/util/libmesautil.la \
$(ELF_LIB) \
- -ldl \
+ $(DLOPEN_LIBS) \
-lclangCodeGen \
-lclangFrontendTool \
-lclangFrontend \
diff --git a/src/gallium/targets/va/target.c b/src/gallium/targets/va/target.c
index 42b1346d341..308e23bb4a0 100644
--- a/src/gallium/targets/va/target.c
+++ b/src/gallium/targets/va/target.c
@@ -1 +1,2 @@
#include "target-helpers/drm_helper.h"
+#include "target-helpers/sw_helper.h"
diff --git a/src/gallium/targets/vdpau/target.c b/src/gallium/targets/vdpau/target.c
index 42b1346d341..308e23bb4a0 100644
--- a/src/gallium/targets/vdpau/target.c
+++ b/src/gallium/targets/vdpau/target.c
@@ -1 +1,2 @@
#include "target-helpers/drm_helper.h"
+#include "target-helpers/sw_helper.h"
diff --git a/src/gallium/targets/xa/target.c b/src/gallium/targets/xa/target.c
index 42b1346d341..308e23bb4a0 100644
--- a/src/gallium/targets/xa/target.c
+++ b/src/gallium/targets/xa/target.c
@@ -1 +1,2 @@
#include "target-helpers/drm_helper.h"
+#include "target-helpers/sw_helper.h"
diff --git a/src/gallium/targets/xvmc/target.c b/src/gallium/targets/xvmc/target.c
index 42b1346d341..308e23bb4a0 100644
--- a/src/gallium/targets/xvmc/target.c
+++ b/src/gallium/targets/xvmc/target.c
@@ -1 +1,2 @@
#include "target-helpers/drm_helper.h"
+#include "target-helpers/sw_helper.h"
diff --git a/src/gallium/winsys/amdgpu/drm/addrlib/r800/ciaddrlib.cpp b/src/gallium/winsys/amdgpu/drm/addrlib/r800/ciaddrlib.cpp
index 7393953c120..570216241d1 100644
--- a/src/gallium/winsys/amdgpu/drm/addrlib/r800/ciaddrlib.cpp
+++ b/src/gallium/winsys/amdgpu/drm/addrlib/r800/ciaddrlib.cpp
@@ -894,6 +894,49 @@ BOOL_32 CIAddrLib::HwlOverrideTileMode(
return bOverrided;
}
+/**
+***************************************************************************************************
+* CiAddrLib::GetPrtSwitchP4Threshold
+*
+* @brief
+* Return the threshold of switching to P4_* instead of P16_* for PRT resources
+***************************************************************************************************
+*/
+UINT_32 CIAddrLib::GetPrtSwitchP4Threshold() const
+{
+ UINT_32 threshold;
+
+ switch (m_pipes)
+ {
+ case 8:
+ threshold = 32;
+ break;
+ case 16:
+ if (m_settings.isFiji)
+ {
+ threshold = 16;
+ }
+ else if (m_settings.isHawaii)
+ {
+ threshold = 8;
+ }
+ else
+ {
+ ///@todo add for possible new ASICs.
+ ADDR_ASSERT_ALWAYS();
+ threshold = 16;
+ }
+ break;
+ default:
+ ///@todo add for possible new ASICs.
+ ADDR_ASSERT_ALWAYS();
+ threshold = 32;
+ break;
+ }
+
+ return threshold;
+}
+
/**
***************************************************************************************************
* CIAddrLib::HwlSetupTileInfo
@@ -1123,7 +1166,7 @@ VOID CIAddrLib::HwlSetupTileInfo(
{
UINT_32 bytesXSamples = bpp * numSamples / 8;
UINT_32 bytesXThickness = bpp * thickness / 8;
- UINT_32 switchP4Threshold = (m_pipes == 16) ? 8 : 32;
+ UINT_32 switchP4Threshold = GetPrtSwitchP4Threshold();
if ((bytesXSamples > switchP4Threshold) || (bytesXThickness > switchP4Threshold))
{
diff --git a/src/gallium/winsys/amdgpu/drm/addrlib/r800/ciaddrlib.h b/src/gallium/winsys/amdgpu/drm/addrlib/r800/ciaddrlib.h
index 451508619f9..4cbe9706baa 100644
--- a/src/gallium/winsys/amdgpu/drm/addrlib/r800/ciaddrlib.h
+++ b/src/gallium/winsys/amdgpu/drm/addrlib/r800/ciaddrlib.h
@@ -167,6 +167,8 @@ private:
VOID ReadGbMacroTileCfg(
UINT_32 regValue, ADDR_TILEINFO* pCfg) const;
+ UINT_32 GetPrtSwitchP4Threshold() const;
+
BOOL_32 InitTileSettingTable(
const UINT_32 *pSetting, UINT_32 noOfEntries);
diff --git a/src/gallium/winsys/amdgpu/drm/addrlib/r800/egbaddrlib.cpp b/src/gallium/winsys/amdgpu/drm/addrlib/r800/egbaddrlib.cpp
index b1e008b8392..088b64593ba 100644
--- a/src/gallium/winsys/amdgpu/drm/addrlib/r800/egbaddrlib.cpp
+++ b/src/gallium/winsys/amdgpu/drm/addrlib/r800/egbaddrlib.cpp
@@ -352,6 +352,7 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMicroTiled(
ComputeSurfaceAlignmentsMicroTiled(expTileMode,
pIn->bpp,
pIn->flags,
+ pIn->mipLevel,
numSamples,
&pOut->baseAlign,
&pOut->pitchAlign,
@@ -647,6 +648,7 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled(
AddrTileMode tileMode, ///< [in] tile mode
UINT_32 bpp, ///< [in] bits per pixel
ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ UINT_32 mipLevel, ///< [in] mip level
UINT_32 numSamples, ///< [in] number of samples
UINT_32* pBaseAlign, ///< [out] base address alignment in bytes
UINT_32* pPitchAlign, ///< [out] pitch alignment in pixels
@@ -669,10 +671,10 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled(
// ECR#393489
// Workaround 2 for 1D tiling - There is HW bug for Carrizo
// where it requires the following alignments for 1D tiling.
- if (flags.czDispCompatible)
+ if (flags.czDispCompatible && (mipLevel == 0))
{
*pBaseAlign = PowTwoAlign(*pBaseAlign, 4096); //Base address MOD 4096 = 0
- *pPitchAlign = PowTwoAlign(*pPitchAlign, 512 >> (BITS_TO_BYTES(bpp))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
+ *pPitchAlign = PowTwoAlign(*pPitchAlign, 512 / (BITS_TO_BYTES(bpp))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
}
// end Carrizo workaround for 1D tilling
diff --git a/src/gallium/winsys/amdgpu/drm/addrlib/r800/egbaddrlib.h b/src/gallium/winsys/amdgpu/drm/addrlib/r800/egbaddrlib.h
index 84adb66eedc..25e38964be0 100644
--- a/src/gallium/winsys/amdgpu/drm/addrlib/r800/egbaddrlib.h
+++ b/src/gallium/winsys/amdgpu/drm/addrlib/r800/egbaddrlib.h
@@ -315,7 +315,8 @@ private:
UINT_32* pBaseAlign, UINT_32* pPitchAlign, UINT_32* pHeightAlign) const;
BOOL_32 ComputeSurfaceAlignmentsMicroTiled(
- AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags, UINT_32 numSamples,
+ AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags,
+ UINT_32 mipLevel, UINT_32 numSamples,
UINT_32* pBaseAlign, UINT_32* pPitchAlign, UINT_32* pHeightAlign) const;
BOOL_32 ComputeSurfaceAlignmentsMacroTiled(
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
index 3006bd17958..4c837a8e20f 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
@@ -145,11 +145,9 @@ ADDR_HANDLE amdgpu_addr_create(struct amdgpu_winsys *ws)
regValue.backendDisables = ws->amdinfo.backend_disable[0];
regValue.pTileConfig = ws->amdinfo.gb_tile_mode;
- regValue.noOfEntries = sizeof(ws->amdinfo.gb_tile_mode) /
- sizeof(ws->amdinfo.gb_tile_mode[0]);
+ regValue.noOfEntries = ARRAY_SIZE(ws->amdinfo.gb_tile_mode);
regValue.pMacroTileConfig = ws->amdinfo.gb_macro_tile_mode;
- regValue.noOfMacroEntries = sizeof(ws->amdinfo.gb_macro_tile_mode) /
- sizeof(ws->amdinfo.gb_macro_tile_mode[0]);
+ regValue.noOfMacroEntries = ARRAY_SIZE(ws->amdinfo.gb_macro_tile_mode);
createFlags.value = 0;
createFlags.useTileIndex = 1;
diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources
index 0c9fd75d206..e64c31e17c6 100644
--- a/src/glsl/Makefile.sources
+++ b/src/glsl/Makefile.sources
@@ -160,6 +160,8 @@ LIBGLSL_FILES = \
loop_analysis.h \
loop_controls.cpp \
loop_unroll.cpp \
+ lower_buffer_access.cpp \
+ lower_buffer_access.h \
lower_clip_distance.cpp \
lower_const_arrays_to_uniforms.cpp \
lower_discard.cpp \
@@ -184,6 +186,7 @@ LIBGLSL_FILES = \
lower_vector_insert.cpp \
lower_vertex_id.cpp \
lower_output_reads.cpp \
+ lower_shared_reference.cpp \
lower_ubo_reference.cpp \
opt_algebraic.cpp \
opt_array_splitting.cpp \
diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 3bea63ea0ed..adfc7938bff 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -699,16 +699,16 @@ struct ast_type_qualifier {
bool merge_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
- ast_type_qualifier q);
+ const ast_type_qualifier &q);
bool merge_out_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
- ast_type_qualifier q,
+ const ast_type_qualifier &q,
ast_node* &node);
bool merge_in_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
- ast_type_qualifier q,
+ const ast_type_qualifier &q,
ast_node* &node);
ast_subroutine_list *subroutine_list;
@@ -1152,7 +1152,7 @@ class ast_cs_input_layout : public ast_node
{
public:
ast_cs_input_layout(const struct YYLTYPE &locp,
- ast_layout_expression **local_size)
+ ast_layout_expression *const *local_size)
{
for (int i = 0; i < 3; i++) {
this->local_size[i] = local_size[i];
@@ -1197,6 +1197,6 @@ check_builtin_array_max_size(const char *name, unsigned size,
extern void _mesa_ast_process_interface_block(YYLTYPE *locp,
_mesa_glsl_parse_state *state,
ast_interface_block *const block,
- const struct ast_type_qualifier q);
+ const struct ast_type_qualifier &q);
#endif /* AST_H */
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index 466ece67424..e32a588f091 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -143,19 +143,21 @@ verify_image_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
}
static bool
-verify_first_atomic_ssbo_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
+verify_first_atomic_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
ir_variable *var)
{
- if (!var || !var->is_in_shader_storage_block()) {
+ if (!var ||
+ (!var->is_in_shader_storage_block() &&
+ var->data.mode != ir_var_shader_shared)) {
_mesa_glsl_error(loc, state, "First argument to atomic function "
- "must be a buffer variable");
+ "must be a buffer or shared variable");
return false;
}
return true;
}
static bool
-is_atomic_ssbo_function(const char *func_name)
+is_atomic_function(const char *func_name)
{
return !strcmp(func_name, "atomicAdd") ||
!strcmp(func_name, "atomicMin") ||
@@ -276,16 +278,16 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
/* The first parameter of atomic functions must be a buffer variable */
const char *func_name = sig->function_name();
- bool is_atomic_ssbo = is_atomic_ssbo_function(func_name);
- if (is_atomic_ssbo) {
+ bool is_atomic = is_atomic_function(func_name);
+ if (is_atomic) {
const ir_rvalue *const actual = (ir_rvalue *) actual_ir_parameters.head;
const ast_expression *const actual_ast =
exec_node_data(ast_expression, actual_ast_parameters.head, link);
YYLTYPE loc = actual_ast->get_location();
- if (!verify_first_atomic_ssbo_parameter(&loc, state,
- actual->variable_referenced())) {
+ if (!verify_first_atomic_parameter(&loc, state,
+ actual->variable_referenced())) {
return false;
}
}
@@ -1737,7 +1739,7 @@ ast_function_expression::handle_method(exec_list *instructions,
result = new(ctx) ir_constant(op->type->array_size());
}
} else if (op->type->is_vector()) {
- if (state->ARB_shading_language_420pack_enable) {
+ if (state->has_420pack()) {
/* .length() returns int. */
result = new(ctx) ir_constant((int) op->type->vector_elements);
} else {
@@ -1746,7 +1748,7 @@ ast_function_expression::handle_method(exec_list *instructions,
goto fail;
}
} else if (op->type->is_matrix()) {
- if (state->ARB_shading_language_420pack_enable) {
+ if (state->has_420pack()) {
/* .length() returns int. */
result = new(ctx) ir_constant((int) op->type->matrix_columns);
} else {
@@ -2075,7 +2077,7 @@ ast_aggregate_initializer::hir(exec_list *instructions,
}
const glsl_type *const constructor_type = this->constructor_type;
- if (!state->ARB_shading_language_420pack_enable) {
+ if (!state->has_420pack()) {
_mesa_glsl_error(&loc, state, "C-style initialization requires the "
"GL_ARB_shading_language_420pack extension");
return ir_rvalue::error_value(ctx);
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 52881a4da7a..fc6bb3e31f1 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -1825,7 +1825,7 @@ ast_expression::do_hir(exec_list *instructions,
* tree. This particular use must be at location specified in the grammar
* as 'variable_identifier'.
*/
- ir_variable *var =
+ ir_variable *var =
state->symbols->get_variable(this->primary_expression.identifier);
if (var != NULL) {
@@ -2650,7 +2650,9 @@ apply_explicit_binding(struct _mesa_glsl_parse_state *state,
return;
}
- } else if (state->is_version(420, 310) && base_type->is_image()) {
+ } else if ((state->is_version(420, 310) ||
+ state->ARB_shading_language_420pack_enable) &&
+ base_type->is_image()) {
assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS);
if (max_index >= ctx->Const.MaxImageUnits) {
_mesa_glsl_error(loc, state, "Image binding %d exceeds the "
@@ -3737,7 +3739,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
* expressions. Const-qualified global variables must still be
* initialized with constant expressions.
*/
- if (!state->ARB_shading_language_420pack_enable
+ if (!state->has_420pack()
|| state->current_function == NULL) {
_mesa_glsl_error(& initializer_loc, state,
"initializer of %s variable `%s' must be a "
@@ -5366,7 +5368,7 @@ ast_jump_statement::hir(exec_list *instructions,
if (state->current_function->return_type != ret_type) {
YYLTYPE loc = this->get_location();
- if (state->ARB_shading_language_420pack_enable) {
+ if (state->has_420pack()) {
if (!apply_implicit_conversion(state->current_function->return_type,
ret, state)) {
_mesa_glsl_error(& loc, state,
@@ -5558,8 +5560,8 @@ ast_switch_statement::hir(exec_list *instructions,
/* From page 66 (page 55 of the PDF) of the GLSL 1.50 spec:
*
- * "The type of init-expression in a switch statement must be a
- * scalar integer."
+ * "The type of init-expression in a switch statement must be a
+ * scalar integer."
*/
if (!test_expression->type->is_scalar() ||
!test_expression->type->is_integer()) {
diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp
index 03ed4dcfa2a..8643b7bfb76 100644
--- a/src/glsl/ast_type.cpp
+++ b/src/glsl/ast_type.cpp
@@ -116,7 +116,7 @@ ast_type_qualifier::interpolation_string() const
bool
ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
- ast_type_qualifier q)
+ const ast_type_qualifier &q)
{
ast_type_qualifier ubo_mat_mask;
ubo_mat_mask.flags.i = 0;
@@ -293,7 +293,7 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
bool
ast_type_qualifier::merge_out_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
- ast_type_qualifier q,
+ const ast_type_qualifier &q,
ast_node* &node)
{
void *mem_ctx = state;
@@ -309,7 +309,7 @@ ast_type_qualifier::merge_out_qualifier(YYLTYPE *loc,
bool
ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
- ast_type_qualifier q,
+ const ast_type_qualifier &q,
ast_node* &node)
{
void *mem_ctx = state;
diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp
index 881ee2b6b55..9973a763087 100644
--- a/src/glsl/builtin_functions.cpp
+++ b/src/glsl/builtin_functions.cpp
@@ -478,6 +478,12 @@ compute_shader(const _mesa_glsl_parse_state *state)
return state->stage == MESA_SHADER_COMPUTE;
}
+static bool
+buffer_atomics_supported(const _mesa_glsl_parse_state *state)
+{
+ return compute_shader(state) || shader_storage_buffer_object(state);
+}
+
static bool
barrier_supported(const _mesa_glsl_parse_state *state)
{
@@ -606,8 +612,8 @@ private:
ir_expression_operation opcode,
const glsl_type *return_type,
const glsl_type *param_type);
- ir_function_signature *binop(ir_expression_operation opcode,
- builtin_available_predicate avail,
+ ir_function_signature *binop(builtin_available_predicate avail,
+ ir_expression_operation opcode,
const glsl_type *return_type,
const glsl_type *param0_type,
const glsl_type *param1_type);
@@ -774,16 +780,16 @@ private:
ir_function_signature *_atomic_counter_op(const char *intrinsic,
builtin_available_predicate avail);
- ir_function_signature *_atomic_ssbo_intrinsic2(builtin_available_predicate avail,
- const glsl_type *type);
- ir_function_signature *_atomic_ssbo_op2(const char *intrinsic,
- builtin_available_predicate avail,
- const glsl_type *type);
- ir_function_signature *_atomic_ssbo_intrinsic3(builtin_available_predicate avail,
- const glsl_type *type);
- ir_function_signature *_atomic_ssbo_op3(const char *intrinsic,
- builtin_available_predicate avail,
- const glsl_type *type);
+ ir_function_signature *_atomic_intrinsic2(builtin_available_predicate avail,
+ const glsl_type *type);
+ ir_function_signature *_atomic_op2(const char *intrinsic,
+ builtin_available_predicate avail,
+ const glsl_type *type);
+ ir_function_signature *_atomic_intrinsic3(builtin_available_predicate avail,
+ const glsl_type *type);
+ ir_function_signature *_atomic_op3(const char *intrinsic,
+ builtin_available_predicate avail,
+ const glsl_type *type);
B1(min3)
B1(max3)
@@ -930,53 +936,53 @@ builtin_builder::create_intrinsics()
_atomic_counter_intrinsic(shader_atomic_counters),
NULL);
- add_function("__intrinsic_ssbo_atomic_add",
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::int_type),
+ add_function("__intrinsic_atomic_add",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
- add_function("__intrinsic_ssbo_atomic_min",
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::int_type),
+ add_function("__intrinsic_atomic_min",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
- add_function("__intrinsic_ssbo_atomic_max",
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::int_type),
+ add_function("__intrinsic_atomic_max",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
- add_function("__intrinsic_ssbo_atomic_and",
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::int_type),
+ add_function("__intrinsic_atomic_and",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
- add_function("__intrinsic_ssbo_atomic_or",
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::int_type),
+ add_function("__intrinsic_atomic_or",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
- add_function("__intrinsic_ssbo_atomic_xor",
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::int_type),
+ add_function("__intrinsic_atomic_xor",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
- add_function("__intrinsic_ssbo_atomic_exchange",
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_intrinsic2(shader_storage_buffer_object,
- glsl_type::int_type),
+ add_function("__intrinsic_atomic_exchange",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
- add_function("__intrinsic_ssbo_atomic_comp_swap",
- _atomic_ssbo_intrinsic3(shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_intrinsic3(shader_storage_buffer_object,
- glsl_type::int_type),
+ add_function("__intrinsic_atomic_comp_swap",
+ _atomic_intrinsic3(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic3(buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_image_functions(false);
@@ -1336,7 +1342,7 @@ builtin_builder::create_builtins()
_smoothstep(fp64, glsl_type::dvec3_type, glsl_type::dvec3_type),
_smoothstep(fp64, glsl_type::dvec4_type, glsl_type::dvec4_type),
NULL);
-
+
FD130(isnan)
FD130(isinf)
@@ -1373,7 +1379,7 @@ builtin_builder::create_builtins()
FD(distance)
FD(dot)
- add_function("cross", _cross(always_available, glsl_type::vec3_type),
+ add_function("cross", _cross(always_available, glsl_type::vec3_type),
_cross(fp64, glsl_type::dvec3_type), NULL);
FD(normalize)
@@ -2682,68 +2688,68 @@ builtin_builder::create_builtins()
NULL);
add_function("atomicAdd",
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_add",
- shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_add",
- shader_storage_buffer_object,
- glsl_type::int_type),
+ _atomic_op2("__intrinsic_atomic_add",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_add",
+ buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_function("atomicMin",
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_min",
- shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_min",
- shader_storage_buffer_object,
- glsl_type::int_type),
+ _atomic_op2("__intrinsic_atomic_min",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_min",
+ buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_function("atomicMax",
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_max",
- shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_max",
- shader_storage_buffer_object,
- glsl_type::int_type),
+ _atomic_op2("__intrinsic_atomic_max",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_max",
+ buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_function("atomicAnd",
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_and",
- shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_and",
- shader_storage_buffer_object,
- glsl_type::int_type),
+ _atomic_op2("__intrinsic_atomic_and",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_and",
+ buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_function("atomicOr",
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_or",
- shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_or",
- shader_storage_buffer_object,
- glsl_type::int_type),
+ _atomic_op2("__intrinsic_atomic_or",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_or",
+ buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_function("atomicXor",
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_xor",
- shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_xor",
- shader_storage_buffer_object,
- glsl_type::int_type),
+ _atomic_op2("__intrinsic_atomic_xor",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_xor",
+ buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_function("atomicExchange",
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_exchange",
- shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_op2("__intrinsic_ssbo_atomic_exchange",
- shader_storage_buffer_object,
- glsl_type::int_type),
+ _atomic_op2("__intrinsic_atomic_exchange",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_exchange",
+ buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_function("atomicCompSwap",
- _atomic_ssbo_op3("__intrinsic_ssbo_atomic_comp_swap",
- shader_storage_buffer_object,
- glsl_type::uint_type),
- _atomic_ssbo_op3("__intrinsic_ssbo_atomic_comp_swap",
- shader_storage_buffer_object,
- glsl_type::int_type),
+ _atomic_op3("__intrinsic_atomic_comp_swap",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op3("__intrinsic_atomic_comp_swap",
+ buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_function("min3",
@@ -3114,8 +3120,8 @@ builtin_builder::_##NAME(builtin_available_predicate avail, const glsl_type *typ
}
ir_function_signature *
-builtin_builder::binop(ir_expression_operation opcode,
- builtin_available_predicate avail,
+builtin_builder::binop(builtin_available_predicate avail,
+ ir_expression_operation opcode,
const glsl_type *return_type,
const glsl_type *param0_type,
const glsl_type *param1_type)
@@ -3411,7 +3417,7 @@ builtin_builder::_atanh(const glsl_type *type)
ir_function_signature *
builtin_builder::_pow(const glsl_type *type)
{
- return binop(ir_binop_pow, always_available, type, type, type);
+ return binop(always_available, ir_binop_pow, type, type, type);
}
UNOP(exp, ir_unop_exp, always_available)
@@ -3435,7 +3441,7 @@ UNOPA(fract, ir_unop_fract)
ir_function_signature *
builtin_builder::_mod(const glsl_type *x_type, const glsl_type *y_type)
{
- return binop(ir_binop_mod, always_available, x_type, x_type, y_type);
+ return binop(always_available, ir_binop_mod, x_type, x_type, y_type);
}
ir_function_signature *
@@ -3457,14 +3463,14 @@ ir_function_signature *
builtin_builder::_min(builtin_available_predicate avail,
const glsl_type *x_type, const glsl_type *y_type)
{
- return binop(ir_binop_min, avail, x_type, x_type, y_type);
+ return binop(avail, ir_binop_min, x_type, x_type, y_type);
}
ir_function_signature *
builtin_builder::_max(builtin_available_predicate avail,
const glsl_type *x_type, const glsl_type *y_type)
{
- return binop(ir_binop_max, avail, x_type, x_type, y_type);
+ return binop(avail, ir_binop_max, x_type, x_type, y_type);
}
ir_function_signature *
@@ -3793,9 +3799,9 @@ ir_function_signature *
builtin_builder::_dot(builtin_available_predicate avail, const glsl_type *type)
{
if (type->vector_elements == 1)
- return binop(ir_binop_mul, avail, type, type, type);
+ return binop(avail, ir_binop_mul, type, type, type);
- return binop(ir_binop_dot, avail,
+ return binop(avail, ir_binop_dot,
type->get_base_type(), type, type);
}
@@ -4311,7 +4317,7 @@ ir_function_signature *
builtin_builder::_lessThan(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_less, avail,
+ return binop(avail, ir_binop_less,
glsl_type::bvec(type->vector_elements), type, type);
}
@@ -4319,7 +4325,7 @@ ir_function_signature *
builtin_builder::_lessThanEqual(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_lequal, avail,
+ return binop(avail, ir_binop_lequal,
glsl_type::bvec(type->vector_elements), type, type);
}
@@ -4327,7 +4333,7 @@ ir_function_signature *
builtin_builder::_greaterThan(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_greater, avail,
+ return binop(avail, ir_binop_greater,
glsl_type::bvec(type->vector_elements), type, type);
}
@@ -4335,7 +4341,7 @@ ir_function_signature *
builtin_builder::_greaterThanEqual(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_gequal, avail,
+ return binop(avail, ir_binop_gequal,
glsl_type::bvec(type->vector_elements), type, type);
}
@@ -4343,7 +4349,7 @@ ir_function_signature *
builtin_builder::_equal(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_equal, avail,
+ return binop(avail, ir_binop_equal,
glsl_type::bvec(type->vector_elements), type, type);
}
@@ -4351,7 +4357,7 @@ ir_function_signature *
builtin_builder::_notEqual(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_nequal, avail,
+ return binop(avail, ir_binop_nequal,
glsl_type::bvec(type->vector_elements), type, type);
}
@@ -4939,7 +4945,8 @@ builtin_builder::_fma(builtin_available_predicate avail, const glsl_type *type)
ir_function_signature *
builtin_builder::_ldexp(const glsl_type *x_type, const glsl_type *exp_type)
{
- return binop(ir_binop_ldexp, x_type->base_type == GLSL_TYPE_DOUBLE ? fp64 : gpu_shader5_or_es31, x_type, x_type, exp_type);
+ return binop(x_type->base_type == GLSL_TYPE_DOUBLE ? fp64 : gpu_shader5_or_es31,
+ ir_binop_ldexp, x_type, x_type, exp_type);
}
ir_function_signature *
@@ -5096,8 +5103,8 @@ builtin_builder::_atomic_counter_intrinsic(builtin_available_predicate avail)
}
ir_function_signature *
-builtin_builder::_atomic_ssbo_intrinsic2(builtin_available_predicate avail,
- const glsl_type *type)
+builtin_builder::_atomic_intrinsic2(builtin_available_predicate avail,
+ const glsl_type *type)
{
ir_variable *atomic = in_var(type, "atomic");
ir_variable *data = in_var(type, "data");
@@ -5106,8 +5113,8 @@ builtin_builder::_atomic_ssbo_intrinsic2(builtin_available_predicate avail,
}
ir_function_signature *
-builtin_builder::_atomic_ssbo_intrinsic3(builtin_available_predicate avail,
- const glsl_type *type)
+builtin_builder::_atomic_intrinsic3(builtin_available_predicate avail,
+ const glsl_type *type)
{
ir_variable *atomic = in_var(type, "atomic");
ir_variable *data1 = in_var(type, "data1");
@@ -5131,9 +5138,9 @@ builtin_builder::_atomic_counter_op(const char *intrinsic,
}
ir_function_signature *
-builtin_builder::_atomic_ssbo_op2(const char *intrinsic,
- builtin_available_predicate avail,
- const glsl_type *type)
+builtin_builder::_atomic_op2(const char *intrinsic,
+ builtin_available_predicate avail,
+ const glsl_type *type)
{
ir_variable *atomic = in_var(type, "atomic_var");
ir_variable *data = in_var(type, "atomic_data");
@@ -5147,9 +5154,9 @@ builtin_builder::_atomic_ssbo_op2(const char *intrinsic,
}
ir_function_signature *
-builtin_builder::_atomic_ssbo_op3(const char *intrinsic,
- builtin_available_predicate avail,
- const glsl_type *type)
+builtin_builder::_atomic_op3(const char *intrinsic,
+ builtin_available_predicate avail,
+ const glsl_type *type)
{
ir_variable *atomic = in_var(type, "atomic_var");
ir_variable *data1 = in_var(type, "atomic_data1");
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 5a8f98019d1..7eb383ac60c 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -948,7 +948,7 @@ parameter_qualifier:
if (($1.flags.q.in || $1.flags.q.out) && ($2.flags.q.in || $2.flags.q.out))
_mesa_glsl_error(&@1, state, "duplicate in/out/inout qualifier");
- if (!state->has_420pack() && $2.flags.q.constant)
+ if (!state->has_420pack_or_es31() && $2.flags.q.constant)
_mesa_glsl_error(&@1, state, "in/out/inout must come after const "
"or precise");
@@ -960,7 +960,7 @@ parameter_qualifier:
if ($2.precision != ast_precision_none)
_mesa_glsl_error(&@1, state, "duplicate precision qualifier");
- if (!(state->has_420pack() || state->is_version(420, 310)) &&
+ if (!state->has_420pack_or_es31() &&
$2.flags.i != 0)
_mesa_glsl_error(&@1, state, "precision qualifiers must come last");
@@ -1482,7 +1482,7 @@ layout_qualifier_id:
$$.index = $3;
}
- if ((state->has_420pack() ||
+ if ((state->has_420pack_or_es31() ||
state->has_atomic_counters() ||
state->has_shader_storage_buffer_objects()) &&
match_layout_qualifier("binding", $1, state) == 0) {
@@ -1714,7 +1714,7 @@ type_qualifier:
if ($2.flags.q.invariant)
_mesa_glsl_error(&@1, state, "duplicate \"invariant\" qualifier");
- if (!state->has_420pack() && $2.flags.q.precise)
+ if (!state->has_420pack_or_es31() && $2.flags.q.precise)
_mesa_glsl_error(&@1, state,
"\"invariant\" must come after \"precise\"");
@@ -1747,7 +1747,7 @@ type_qualifier:
if ($2.has_interpolation())
_mesa_glsl_error(&@1, state, "duplicate interpolation qualifier");
- if (!state->has_420pack() &&
+ if (!state->has_420pack_or_es31() &&
($2.flags.q.precise || $2.flags.q.invariant)) {
_mesa_glsl_error(&@1, state, "interpolation qualifiers must come "
"after \"precise\" or \"invariant\"");
@@ -1767,7 +1767,7 @@ type_qualifier:
* precise qualifiers since these are useful in ARB_separate_shader_objects.
* There is no clear spec guidance on this either.
*/
- if (!state->has_420pack() && $2.has_layout())
+ if (!state->has_420pack_or_es31() && $2.has_layout())
_mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
$$ = $1;
@@ -1785,7 +1785,7 @@ type_qualifier:
"duplicate auxiliary storage qualifier (centroid or sample)");
}
- if (!state->has_420pack() &&
+ if (!state->has_420pack_or_es31() &&
($2.flags.q.precise || $2.flags.q.invariant ||
$2.has_interpolation() || $2.has_layout())) {
_mesa_glsl_error(&@1, state, "auxiliary storage qualifiers must come "
@@ -1803,7 +1803,7 @@ type_qualifier:
if ($2.has_storage())
_mesa_glsl_error(&@1, state, "duplicate storage qualifier");
- if (!state->has_420pack() &&
+ if (!state->has_420pack_or_es31() &&
($2.flags.q.precise || $2.flags.q.invariant || $2.has_interpolation() ||
$2.has_layout() || $2.has_auxiliary_storage())) {
_mesa_glsl_error(&@1, state, "storage qualifiers must come after "
@@ -1819,7 +1819,7 @@ type_qualifier:
if ($2.precision != ast_precision_none)
_mesa_glsl_error(&@1, state, "duplicate precision qualifier");
- if (!(state->has_420pack() || state->is_version(420, 310)) &&
+ if (!(state->has_420pack_or_es31()) &&
$2.flags.i != 0)
_mesa_glsl_error(&@1, state, "precision qualifiers must come last");
@@ -2575,7 +2575,7 @@ interface_block:
{
ast_interface_block *block = (ast_interface_block *) $2;
- if (!state->has_420pack() && block->layout.has_layout() &&
+ if (!state->has_420pack_or_es31() && block->layout.has_layout() &&
!block->layout.is_default_qualifier) {
_mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
YYERROR;
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index b41b64af2c1..3988376ea9d 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -479,7 +479,7 @@ _mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
struct gl_context *ctx = state->ctx;
/* Report the error via GL_ARB_debug_output. */
- _mesa_shader_debug(ctx, type, &msg_id, msg, strlen(msg));
+ _mesa_shader_debug(ctx, type, &msg_id, msg);
ralloc_strcat(&state->info_log, "\n");
}
@@ -876,7 +876,7 @@ void
_mesa_ast_process_interface_block(YYLTYPE *locp,
_mesa_glsl_parse_state *state,
ast_interface_block *const block,
- const struct ast_type_qualifier q)
+ const struct ast_type_qualifier &q)
{
if (q.flags.q.buffer) {
if (!state->has_shader_storage_buffer_objects()) {
@@ -1088,7 +1088,7 @@ void
ast_compound_statement::print(void) const
{
printf("{\n");
-
+
foreach_list_typed(ast_node, ast, link, &this->statements) {
ast->print();
}
@@ -1414,7 +1414,6 @@ ast_selection_statement::print(void) const
printf("else ");
else_statement->print();
}
-
}
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 17ff0b5af79..a4bda772a0f 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -97,7 +97,7 @@ struct _mesa_glsl_parse_state {
* supports the feature.
*
* \param required_glsl_es_version is the GLSL ES version that is required
- * to support the feature, or 0 if no version of GLSL ES suports the
+ * to support the feature, or 0 if no version of GLSL ES supports the
* feature.
*/
bool is_version(unsigned required_glsl_version,
@@ -255,6 +255,11 @@ struct _mesa_glsl_parse_state {
return ARB_shading_language_420pack_enable || is_version(420, 0);
}
+ bool has_420pack_or_es31() const
+ {
+ return ARB_shading_language_420pack_enable || is_version(420, 310);
+ }
+
bool has_compute_shader() const
{
return ARB_compute_shader_enable || is_version(430, 310);
diff --git a/src/glsl/hir_field_selection.cpp b/src/glsl/hir_field_selection.cpp
index 337095b95b8..92bb4139194 100644
--- a/src/glsl/hir_field_selection.cpp
+++ b/src/glsl/hir_field_selection.cpp
@@ -57,8 +57,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
expr->primary_expression.identifier);
}
} else if (op->type->is_vector() ||
- (state->ARB_shading_language_420pack_enable &&
- op->type->is_scalar())) {
+ (state->has_420pack() && op->type->is_scalar())) {
ir_swizzle *swiz = ir_swizzle::create(op,
expr->primary_expression.identifier,
op->type->vector_elements);
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index ca520f547a1..f989e9b6dff 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1669,6 +1669,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
this->data.pixel_center_integer = false;
this->data.depth_layout = ir_depth_layout_none;
this->data.used = false;
+ this->data.always_active_io = false;
this->data.read_only = false;
this->data.centroid = false;
this->data.sample = false;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index e1109eec1d3..bdc932ef538 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -658,6 +658,13 @@ public:
*/
unsigned assigned:1;
+ /**
+ * When separate shader programs are enabled, only input/outputs between
+ * the stages of a multi-stage separate program can be safely removed
+ * from the shader interface. Other input/outputs must remains active.
+ */
+ unsigned always_active_io:1;
+
/**
* Enum indicating how the variable was declared. See
* ir_var_declaration_type.
diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp
index 67ed3605a8c..ef705851613 100644
--- a/src/glsl/ir_constant_expression.cpp
+++ b/src/glsl/ir_constant_expression.cpp
@@ -41,14 +41,6 @@
#include "glsl_types.h"
#include "program/hash_table.h"
-#if defined(__SUNPRO_CC) && !defined(isnormal)
-#include
-static int isnormal(double x)
-{
- return fpclass(x) == FP_NORMAL;
-}
-#endif
-
static float
dot_f(ir_constant *op0, ir_constant *op1)
{
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index 2fee81c09c2..dabd80a8d0d 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -124,6 +124,7 @@ bool lower_const_arrays_to_uniforms(exec_list *instructions);
bool lower_clip_distance(gl_shader *shader);
void lower_output_reads(unsigned stage, exec_list *instructions);
bool lower_packing_builtins(exec_list *instructions, int op_mask);
+void lower_shared_reference(struct gl_shader *shader, unsigned *shared_size);
void lower_ubo_reference(struct gl_shader *shader);
void lower_packed_varyings(void *mem_ctx,
unsigned locations_used, ir_variable_mode mode,
diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp
index 07720e28749..7c0af1b712f 100644
--- a/src/glsl/ir_reader.cpp
+++ b/src/glsl/ir_reader.cpp
@@ -93,7 +93,7 @@ ir_reader::read(exec_list *instructions, const char *src, bool scan_for_protos)
ir_read_error(NULL, "couldn't parse S-Expression.");
return;
}
-
+
if (scan_for_protos) {
scan_for_prototypes(instructions, expr);
if (state->error)
@@ -147,7 +147,7 @@ ir_reader::read_type(s_expression *expr)
return glsl_type::get_array_instance(base_type, s_size->value());
}
-
+
s_symbol *type_sym = SX_AS_SYMBOL(expr);
if (type_sym == NULL) {
ir_read_error(expr, "expected ");
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index c0b4b3e820c..71750d1b42b 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -766,7 +766,7 @@ public:
gl_shader_stage consumer_stage);
~varying_matches();
void record(ir_variable *producer_var, ir_variable *consumer_var);
- unsigned assign_locations(uint64_t reserved_slots);
+ unsigned assign_locations(uint64_t reserved_slots, bool separate_shader);
void store_locations() const;
private:
@@ -896,8 +896,10 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
{
assert(producer_var != NULL || consumer_var != NULL);
- if ((producer_var && !producer_var->data.is_unmatched_generic_inout)
- || (consumer_var && !consumer_var->data.is_unmatched_generic_inout)) {
+ if ((producer_var && (!producer_var->data.is_unmatched_generic_inout ||
+ producer_var->data.explicit_location)) ||
+ (consumer_var && (!consumer_var->data.is_unmatched_generic_inout ||
+ consumer_var->data.explicit_location))) {
/* Either a location already exists for this variable (since it is part
* of fixed functionality), or it has already been recorded as part of a
* previous match.
@@ -986,11 +988,36 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
* passed to varying_matches::record().
*/
unsigned
-varying_matches::assign_locations(uint64_t reserved_slots)
+varying_matches::assign_locations(uint64_t reserved_slots, bool separate_shader)
{
- /* Sort varying matches into an order that makes them easy to pack. */
- qsort(this->matches, this->num_matches, sizeof(*this->matches),
- &varying_matches::match_comparator);
+ /* We disable varying sorting for separate shader programs for the
+ * following reasons:
+ *
+ * 1/ All programs must sort the code in the same order to guarantee the
+ * interface matching. However varying_matches::record() will change the
+ * interpolation qualifier of some stages.
+ *
+ * 2/ GLSL version 4.50 removes the matching constrain on the interpolation
+ * qualifier.
+ *
+ * From Section 4.5 (Interpolation Qualifiers) of the GLSL 4.40 spec:
+ *
+ * "The type and presence of interpolation qualifiers of variables with
+ * the same name declared in all linked shaders for the same cross-stage
+ * interface must match, otherwise the link command will fail.
+ *
+ * When comparing an output from one stage to an input of a subsequent
+ * stage, the input and output don't match if their interpolation
+ * qualifiers (or lack thereof) are not the same."
+ *
+ * "It is a link-time error if, within the same stage, the interpolation
+ * qualifiers of variables of the same name do not match."
+ */
+ if (!separate_shader) {
+ /* Sort varying matches into an order that makes them easy to pack. */
+ qsort(this->matches, this->num_matches, sizeof(*this->matches),
+ &varying_matches::match_comparator);
+ }
unsigned generic_location = 0;
unsigned generic_patch_location = MAX_VARYING*4;
@@ -1590,7 +1617,8 @@ assign_varying_locations(struct gl_context *ctx,
reserved_varying_slot(producer, ir_var_shader_out) |
reserved_varying_slot(consumer, ir_var_shader_in);
- const unsigned slots_used = matches.assign_locations(reserved_slots);
+ const unsigned slots_used = matches.assign_locations(reserved_slots,
+ prog->SeparateShader);
matches.store_locations();
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 331d9a28007..a87bbb2b994 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -631,20 +631,12 @@ link_invalidate_variable_locations(exec_list *ir)
/* ir_variable::is_unmatched_generic_inout is used by the linker while
* connecting outputs from one stage to inputs of the next stage.
- *
- * There are two implicit assumptions here. First, we assume that any
- * built-in variable (i.e., non-generic in or out) will have
- * explicit_location set. Second, we assume that any generic in or out
- * will not have explicit_location set.
- *
- * This second assumption will only be valid until
- * GL_ARB_separate_shader_objects is supported. When that extension is
- * implemented, this function will need some modifications.
*/
- if (!var->data.explicit_location) {
- var->data.is_unmatched_generic_inout = 1;
- } else {
+ if (var->data.explicit_location &&
+ var->data.location < VARYING_SLOT_VAR0) {
var->data.is_unmatched_generic_inout = 0;
+ } else {
+ var->data.is_unmatched_generic_inout = 1;
}
}
}
@@ -2421,6 +2413,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
continue;
if (var->data.explicit_location) {
+ var->data.is_unmatched_generic_inout = 0;
if ((var->data.location >= (int)(max_index + generic_base))
|| (var->data.location < 0)) {
linker_error(prog,
@@ -2690,6 +2683,53 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
return true;
}
+/**
+ * Match explicit locations of outputs to inputs and deactivate the
+ * unmatch flag if found so we don't optimise them away.
+ */
+static void
+match_explicit_outputs_to_inputs(struct gl_shader_program *prog,
+ gl_shader *producer,
+ gl_shader *consumer)
+{
+ glsl_symbol_table parameters;
+ ir_variable *explicit_locations[MAX_VARYING] = { NULL };
+
+ /* Find all shader outputs in the "producer" stage.
+ */
+ foreach_in_list(ir_instruction, node, producer->ir) {
+ ir_variable *const var = node->as_variable();
+
+ if ((var == NULL) || (var->data.mode != ir_var_shader_out))
+ continue;
+
+ if (var->data.explicit_location &&
+ var->data.location >= VARYING_SLOT_VAR0) {
+ const unsigned idx = var->data.location - VARYING_SLOT_VAR0;
+ if (explicit_locations[idx] == NULL)
+ explicit_locations[idx] = var;
+ }
+ }
+
+ /* Match inputs to outputs */
+ foreach_in_list(ir_instruction, node, consumer->ir) {
+ ir_variable *const input = node->as_variable();
+
+ if ((input == NULL) || (input->data.mode != ir_var_shader_in))
+ continue;
+
+ ir_variable *output = NULL;
+ if (input->data.explicit_location
+ && input->data.location >= VARYING_SLOT_VAR0) {
+ output = explicit_locations[input->data.location - VARYING_SLOT_VAR0];
+
+ if (output != NULL){
+ input->data.is_unmatched_generic_inout = 0;
+ output->data.is_unmatched_generic_inout = 0;
+ }
+ }
+ }
+}
/**
* Demote shader inputs and outputs that are not used in other stages
@@ -3940,6 +3980,77 @@ split_ubos_and_ssbos(void *mem_ctx,
assert(*num_ubos + *num_ssbos == num_blocks);
}
+static void
+set_always_active_io(exec_list *ir, ir_variable_mode io_mode)
+{
+ assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out);
+
+ foreach_in_list(ir_instruction, node, ir) {
+ ir_variable *const var = node->as_variable();
+
+ if (var == NULL || var->data.mode != io_mode)
+ continue;
+
+ /* Don't set always active on builtins that haven't been redeclared */
+ if (var->data.how_declared == ir_var_declared_implicitly)
+ continue;
+
+ var->data.always_active_io = true;
+ }
+}
+
+/**
+ * When separate shader programs are enabled, only input/outputs between
+ * the stages of a multi-stage separate program can be safely removed
+ * from the shader interface. Other inputs/outputs must remain active.
+ */
+static void
+disable_varying_optimizations_for_sso(struct gl_shader_program *prog)
+{
+ unsigned first, last;
+ assert(prog->SeparateShader);
+
+ first = MESA_SHADER_STAGES;
+ last = 0;
+
+ /* Determine first and last stage. Excluding the compute stage */
+ for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) {
+ if (!prog->_LinkedShaders[i])
+ continue;
+ if (first == MESA_SHADER_STAGES)
+ first = i;
+ last = i;
+ }
+
+ if (first == MESA_SHADER_STAGES)
+ return;
+
+ for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
+ gl_shader *sh = prog->_LinkedShaders[stage];
+ if (!sh)
+ continue;
+
+ if (first == last) {
+ /* For a single shader program only allow inputs to the vertex shader
+ * and outputs from the fragment shader to be removed.
+ */
+ if (stage != MESA_SHADER_VERTEX)
+ set_always_active_io(sh->ir, ir_var_shader_in);
+ if (stage != MESA_SHADER_FRAGMENT)
+ set_always_active_io(sh->ir, ir_var_shader_out);
+ } else {
+ /* For multi-stage separate shader programs only allow inputs and
+ * outputs between the shader stages to be removed as well as inputs
+ * to the vertex shader and outputs from the fragment shader.
+ */
+ if (stage == first && stage != MESA_SHADER_VERTEX)
+ set_always_active_io(sh->ir, ir_var_shader_in);
+ else if (stage == last && stage != MESA_SHADER_FRAGMENT)
+ set_always_active_io(sh->ir, ir_var_shader_out);
+ }
+ }
+}
+
void
link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
{
@@ -4139,11 +4250,18 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
if (!prog->LinkStatus)
goto done;
- unsigned prev;
+ unsigned first, last, prev;
- for (prev = 0; prev <= MESA_SHADER_FRAGMENT; prev++) {
- if (prog->_LinkedShaders[prev] != NULL)
- break;
+ first = MESA_SHADER_STAGES;
+ last = 0;
+
+ /* Determine first and last stage. */
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (!prog->_LinkedShaders[i])
+ continue;
+ if (first == MESA_SHADER_STAGES)
+ first = i;
+ last = i;
}
check_explicit_uniform_locations(ctx, prog);
@@ -4157,6 +4275,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
/* Validate the inputs of each stage with the output of the preceding
* stage.
*/
+ prev = first;
for (unsigned i = prev + 1; i <= MESA_SHADER_FRAGMENT; i++) {
if (prog->_LinkedShaders[i] == NULL)
continue;
@@ -4199,6 +4318,9 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
+ if (prog->SeparateShader)
+ disable_varying_optimizations_for_sso(prog);
+
if (!interstage_cross_validate_uniform_blocks(prog))
goto done;
@@ -4250,6 +4372,16 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
+ prev = first;
+ for (unsigned i = prev + 1; i <= MESA_SHADER_FRAGMENT; i++) {
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
+
+ match_explicit_outputs_to_inputs(prog, prog->_LinkedShaders[prev],
+ prog->_LinkedShaders[i]);
+ prev = i;
+ }
+
if (!assign_attribute_or_color_locations(prog, &ctx->Const,
MESA_SHADER_VERTEX)) {
goto done;
@@ -4260,20 +4392,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
goto done;
}
- unsigned first, last;
-
- first = MESA_SHADER_STAGES;
- last = 0;
-
- /* Determine first and last stage. */
- for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
- if (!prog->_LinkedShaders[i])
- continue;
- if (first == MESA_SHADER_STAGES)
- first = i;
- last = i;
- }
-
if (num_tfeedback_decls != 0) {
/* From GL_EXT_transform_feedback:
* A program will fail to link if:
@@ -4333,13 +4451,14 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
do_dead_builtin_varyings(ctx, sh, NULL,
num_tfeedback_decls, tfeedback_decls);
- if (!prog->SeparateShader)
+ if (!prog->SeparateShader) {
demote_shader_inputs_and_outputs(sh, ir_var_shader_out);
-
- /* Eliminate code that is now dead due to unused outputs being demoted.
- */
- while (do_dead_code(sh->ir, false))
- ;
+ /* Eliminate code that is now dead due to unused outputs being
+ * demoted.
+ */
+ while (do_dead_code(sh->ir, false))
+ ;
+ }
}
else if (first == MESA_SHADER_FRAGMENT) {
/* If the program only contains a fragment shader...
@@ -4356,11 +4475,14 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
0 /* num_tfeedback_decls */,
NULL /* tfeedback_decls */))
goto done;
- } else
+ } else {
demote_shader_inputs_and_outputs(sh, ir_var_shader_in);
-
- while (do_dead_code(sh->ir, false))
- ;
+ /* Eliminate code that is now dead due to unused inputs being
+ * demoted.
+ */
+ while (do_dead_code(sh->ir, false))
+ ;
+ }
}
next = last;
@@ -4485,6 +4607,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
if (ctx->Const.ShaderCompilerOptions[i].LowerBufferInterfaceBlocks)
lower_ubo_reference(prog->_LinkedShaders[i]);
+ if (ctx->Const.ShaderCompilerOptions[i].LowerShaderSharedVariables)
+ lower_shared_reference(prog->_LinkedShaders[i],
+ &prog->Comp.SharedSize);
+
lower_vector_derefs(prog->_LinkedShaders[i]);
}
diff --git a/src/glsl/list.h b/src/glsl/list.h
index 15fcd4abd1c..a1c4d82b017 100644
--- a/src/glsl/list.h
+++ b/src/glsl/list.h
@@ -688,7 +688,7 @@ inline void exec_node::insert_before(exec_list *before)
__node = __next, __next = \
exec_node_data(__type, (__next)->__field.next, __field))
-#define foreach_list_typed_safe_reverse(__type, __node, __field, __list) \
+#define foreach_list_typed_reverse_safe(__type, __node, __field, __list) \
for (__type * __node = \
exec_node_data(__type, (__list)->tail_pred, __field), \
* __prev = \
diff --git a/src/glsl/lower_buffer_access.cpp b/src/glsl/lower_buffer_access.cpp
new file mode 100644
index 00000000000..f8c8d140ea8
--- /dev/null
+++ b/src/glsl/lower_buffer_access.cpp
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2015 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.
+ */
+
+/**
+ * \file lower_buffer_access.cpp
+ *
+ * Helper for IR lowering pass to replace dereferences of buffer object based
+ * shader variables with intrinsic function calls.
+ *
+ * This helper is used by lowering passes for UBOs, SSBOs and compute shader
+ * shared variables.
+ */
+
+#include "lower_buffer_access.h"
+#include "ir_builder.h"
+#include "main/macros.h"
+#include "util/list.h"
+#include "glsl_parser_extras.h"
+
+using namespace ir_builder;
+
+namespace lower_buffer_access {
+
+static inline int
+writemask_for_size(unsigned n)
+{
+ return ((1 << n) - 1);
+}
+
+/**
+ * Takes a deref and recursively calls itself to break the deref down to the
+ * point that the reads or writes generated are contiguous scalars or vectors.
+ */
+void
+lower_buffer_access::emit_access(void *mem_ctx,
+ bool is_write,
+ ir_dereference *deref,
+ ir_variable *base_offset,
+ unsigned int deref_offset,
+ bool row_major,
+ int matrix_columns,
+ unsigned int packing,
+ unsigned int write_mask)
+{
+ if (deref->type->is_record()) {
+ unsigned int field_offset = 0;
+
+ for (unsigned i = 0; i < deref->type->length; i++) {
+ const struct glsl_struct_field *field =
+ &deref->type->fields.structure[i];
+ ir_dereference *field_deref =
+ new(mem_ctx) ir_dereference_record(deref->clone(mem_ctx, NULL),
+ field->name);
+
+ field_offset =
+ glsl_align(field_offset,
+ field->type->std140_base_alignment(row_major));
+
+ emit_access(mem_ctx, is_write, field_deref, base_offset,
+ deref_offset + field_offset,
+ row_major, 1, packing,
+ writemask_for_size(field_deref->type->vector_elements));
+
+ field_offset += field->type->std140_size(row_major);
+ }
+ return;
+ }
+
+ if (deref->type->is_array()) {
+ unsigned array_stride = packing == GLSL_INTERFACE_PACKING_STD430 ?
+ deref->type->fields.array->std430_array_stride(row_major) :
+ glsl_align(deref->type->fields.array->std140_size(row_major), 16);
+
+ for (unsigned i = 0; i < deref->type->length; i++) {
+ ir_constant *element = new(mem_ctx) ir_constant(i);
+ ir_dereference *element_deref =
+ new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL),
+ element);
+ emit_access(mem_ctx, is_write, element_deref, base_offset,
+ deref_offset + i * array_stride,
+ row_major, 1, packing,
+ writemask_for_size(element_deref->type->vector_elements));
+ }
+ return;
+ }
+
+ if (deref->type->is_matrix()) {
+ for (unsigned i = 0; i < deref->type->matrix_columns; i++) {
+ ir_constant *col = new(mem_ctx) ir_constant(i);
+ ir_dereference *col_deref =
+ new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL), col);
+
+ if (row_major) {
+ /* For a row-major matrix, the next column starts at the next
+ * element.
+ */
+ int size_mul = deref->type->is_double() ? 8 : 4;
+ emit_access(mem_ctx, is_write, col_deref, base_offset,
+ deref_offset + i * size_mul,
+ row_major, deref->type->matrix_columns, packing,
+ writemask_for_size(col_deref->type->vector_elements));
+ } else {
+ int size_mul;
+
+ /* std430 doesn't round up vec2 size to a vec4 size */
+ if (packing == GLSL_INTERFACE_PACKING_STD430 &&
+ deref->type->vector_elements == 2 &&
+ !deref->type->is_double()) {
+ size_mul = 8;
+ } else {
+ /* std140 always rounds the stride of arrays (and matrices) to a
+ * vec4, so matrices are always 16 between columns/rows. With
+ * doubles, they will be 32 apart when there are more than 2 rows.
+ *
+ * For both std140 and std430, if the member is a
+ * three-'component vector with components consuming N basic
+ * machine units, the base alignment is 4N. For vec4, base
+ * alignment is 4N.
+ */
+ size_mul = (deref->type->is_double() &&
+ deref->type->vector_elements > 2) ? 32 : 16;
+ }
+
+ emit_access(mem_ctx, is_write, col_deref, base_offset,
+ deref_offset + i * size_mul,
+ row_major, deref->type->matrix_columns, packing,
+ writemask_for_size(col_deref->type->vector_elements));
+ }
+ }
+ return;
+ }
+
+ assert(deref->type->is_scalar() || deref->type->is_vector());
+
+ if (!row_major) {
+ ir_rvalue *offset =
+ add(base_offset, new(mem_ctx) ir_constant(deref_offset));
+ unsigned mask =
+ is_write ? write_mask : (1 << deref->type->vector_elements) - 1;
+ insert_buffer_access(mem_ctx, deref, deref->type, offset, mask, -1);
+ } else {
+ unsigned N = deref->type->is_double() ? 8 : 4;
+
+ /* We're dereffing a column out of a row-major matrix, so we
+ * gather the vector from each stored row.
+ */
+ assert(deref->type->base_type == GLSL_TYPE_FLOAT ||
+ deref->type->base_type == GLSL_TYPE_DOUBLE);
+ /* Matrices, row_major or not, are stored as if they were
+ * arrays of vectors of the appropriate size in std140.
+ * Arrays have their strides rounded up to a vec4, so the
+ * matrix stride is always 16. However a double matrix may either be 16
+ * or 32 depending on the number of columns.
+ */
+ assert(matrix_columns <= 4);
+ unsigned matrix_stride = 0;
+ /* Matrix stride for std430 mat2xY matrices are not rounded up to
+ * vec4 size. From OpenGL 4.3 spec, section 7.6.2.2 "Standard Uniform
+ * Block Layout":
+ *
+ * "2. If the member is a two- or four-component vector with components
+ * consuming N basic machine units, the base alignment is 2N or 4N,
+ * respectively." [...]
+ * "4. If the member is an array of scalars or vectors, the base alignment
+ * and array stride are set to match the base alignment of a single array
+ * element, according to rules (1), (2), and (3), and rounded up to the
+ * base alignment of a vec4." [...]
+ * "7. If the member is a row-major matrix with C columns and R rows, the
+ * matrix is stored identically to an array of R row vectors with C
+ * components each, according to rule (4)." [...]
+ * "When using the std430 storage layout, shader storage blocks will be
+ * laid out in buffer storage identically to uniform and shader storage
+ * blocks using the std140 layout, except that the base alignment and
+ * stride of arrays of scalars and vectors in rule 4 and of structures in
+ * rule 9 are not rounded up a multiple of the base alignment of a vec4."
+ */
+ if (packing == GLSL_INTERFACE_PACKING_STD430 && matrix_columns == 2)
+ matrix_stride = 2 * N;
+ else
+ matrix_stride = glsl_align(matrix_columns * N, 16);
+
+ const glsl_type *deref_type = deref->type->base_type == GLSL_TYPE_FLOAT ?
+ glsl_type::float_type : glsl_type::double_type;
+
+ for (unsigned i = 0; i < deref->type->vector_elements; i++) {
+ ir_rvalue *chan_offset =
+ add(base_offset,
+ new(mem_ctx) ir_constant(deref_offset + i * matrix_stride));
+ if (!is_write || ((1U << i) & write_mask))
+ insert_buffer_access(mem_ctx, deref, deref_type, chan_offset,
+ (1U << i), i);
+ }
+ }
+}
+
+/**
+ * Determine if a thing being dereferenced is row-major
+ *
+ * There is some trickery here.
+ *
+ * If the thing being dereferenced is a member of uniform block \b without an
+ * instance name, then the name of the \c ir_variable is the field name of an
+ * interface type. If this field is row-major, then the thing referenced is
+ * row-major.
+ *
+ * If the thing being dereferenced is a member of uniform block \b with an
+ * instance name, then the last dereference in the tree will be an
+ * \c ir_dereference_record. If that record field is row-major, then the
+ * thing referenced is row-major.
+ */
+bool
+lower_buffer_access::is_dereferenced_thing_row_major(const ir_rvalue *deref)
+{
+ bool matrix = false;
+ const ir_rvalue *ir = deref;
+
+ while (true) {
+ matrix = matrix || ir->type->without_array()->is_matrix();
+
+ switch (ir->ir_type) {
+ case ir_type_dereference_array: {
+ const ir_dereference_array *const array_deref =
+ (const ir_dereference_array *) ir;
+
+ ir = array_deref->array;
+ break;
+ }
+
+ case ir_type_dereference_record: {
+ const ir_dereference_record *const record_deref =
+ (const ir_dereference_record *) ir;
+
+ ir = record_deref->record;
+
+ const int idx = ir->type->field_index(record_deref->field);
+ assert(idx >= 0);
+
+ const enum glsl_matrix_layout matrix_layout =
+ glsl_matrix_layout(ir->type->fields.structure[idx].matrix_layout);
+
+ switch (matrix_layout) {
+ case GLSL_MATRIX_LAYOUT_INHERITED:
+ break;
+ case GLSL_MATRIX_LAYOUT_COLUMN_MAJOR:
+ return false;
+ case GLSL_MATRIX_LAYOUT_ROW_MAJOR:
+ return matrix || deref->type->without_array()->is_record();
+ }
+
+ break;
+ }
+
+ case ir_type_dereference_variable: {
+ const ir_dereference_variable *const var_deref =
+ (const ir_dereference_variable *) ir;
+
+ const enum glsl_matrix_layout matrix_layout =
+ glsl_matrix_layout(var_deref->var->data.matrix_layout);
+
+ switch (matrix_layout) {
+ case GLSL_MATRIX_LAYOUT_INHERITED: {
+ /* For interface block matrix variables we handle inherited
+ * layouts at HIR generation time, but we don't do that for shared
+ * variables, which are always column-major
+ */
+ ir_variable *var = deref->variable_referenced();
+ assert((var->is_in_buffer_block() && !matrix) ||
+ var->data.mode == ir_var_shader_shared);
+ return false;
+ }
+ case GLSL_MATRIX_LAYOUT_COLUMN_MAJOR:
+ return false;
+ case GLSL_MATRIX_LAYOUT_ROW_MAJOR:
+ return matrix || deref->type->without_array()->is_record();
+ }
+
+ unreachable("invalid matrix layout");
+ break;
+ }
+
+ default:
+ return false;
+ }
+ }
+
+ /* The tree must have ended with a dereference that wasn't an
+ * ir_dereference_variable. That is invalid, and it should be impossible.
+ */
+ unreachable("invalid dereference tree");
+ return false;
+}
+
+/**
+ * This function initializes various values that will be used later by
+ * emit_access when actually emitting loads or stores.
+ *
+ * Note: const_offset is an input as well as an output, clients must
+ * initialize it to the offset of the variable in the underlying block, and
+ * this function will adjust it by adding the constant offset of the member
+ * being accessed into that variable.
+ */
+void
+lower_buffer_access::setup_buffer_access(void *mem_ctx,
+ ir_variable *var,
+ ir_rvalue *deref,
+ ir_rvalue **offset,
+ unsigned *const_offset,
+ bool *row_major,
+ int *matrix_columns,
+ unsigned packing)
+{
+ *offset = new(mem_ctx) ir_constant(0u);
+ *row_major = is_dereferenced_thing_row_major(deref);
+ *matrix_columns = 1;
+
+ /* Calculate the offset to the start of the region of the UBO
+ * dereferenced by *rvalue. This may be a variable offset if an
+ * array dereference has a variable index.
+ */
+ while (deref) {
+ switch (deref->ir_type) {
+ case ir_type_dereference_variable: {
+ deref = NULL;
+ break;
+ }
+
+ case ir_type_dereference_array: {
+ ir_dereference_array *deref_array = (ir_dereference_array *) deref;
+ unsigned array_stride;
+ if (deref_array->array->type->is_vector()) {
+ /* We get this when storing or loading a component out of a vector
+ * with a non-constant index. This happens for v[i] = f where v is
+ * a vector (or m[i][j] = f where m is a matrix). If we don't
+ * lower that here, it gets turned into v = vector_insert(v, i,
+ * f), which loads the entire vector, modifies one component and
+ * then write the entire thing back. That breaks if another
+ * thread or SIMD channel is modifying the same vector.
+ */
+ array_stride = 4;
+ if (deref_array->array->type->is_double())
+ array_stride *= 2;
+ } else if (deref_array->array->type->is_matrix() && *row_major) {
+ /* When loading a vector out of a row major matrix, the
+ * step between the columns (vectors) is the size of a
+ * float, while the step between the rows (elements of a
+ * vector) is handled below in emit_ubo_loads.
+ */
+ array_stride = 4;
+ if (deref_array->array->type->is_double())
+ array_stride *= 2;
+ *matrix_columns = deref_array->array->type->matrix_columns;
+ } else if (deref_array->type->without_array()->is_interface()) {
+ /* We're processing an array dereference of an interface instance
+ * array. The thing being dereferenced *must* be a variable
+ * dereference because interfaces cannot be embedded in other
+ * types. In terms of calculating the offsets for the lowering
+ * pass, we don't care about the array index. All elements of an
+ * interface instance array will have the same offsets relative to
+ * the base of the block that backs them.
+ */
+ deref = deref_array->array->as_dereference();
+ break;
+ } else {
+ /* Whether or not the field is row-major (because it might be a
+ * bvec2 or something) does not affect the array itself. We need
+ * to know whether an array element in its entirety is row-major.
+ */
+ const bool array_row_major =
+ is_dereferenced_thing_row_major(deref_array);
+
+ /* The array type will give the correct interface packing
+ * information
+ */
+ if (packing == GLSL_INTERFACE_PACKING_STD430) {
+ array_stride = deref_array->type->std430_array_stride(array_row_major);
+ } else {
+ array_stride = deref_array->type->std140_size(array_row_major);
+ array_stride = glsl_align(array_stride, 16);
+ }
+ }
+
+ ir_rvalue *array_index = deref_array->array_index;
+ if (array_index->type->base_type == GLSL_TYPE_INT)
+ array_index = i2u(array_index);
+
+ ir_constant *const_index =
+ array_index->constant_expression_value(NULL);
+ if (const_index) {
+ *const_offset += array_stride * const_index->value.u[0];
+ } else {
+ *offset = add(*offset,
+ mul(array_index,
+ new(mem_ctx) ir_constant(array_stride)));
+ }
+ deref = deref_array->array->as_dereference();
+ break;
+ }
+
+ case ir_type_dereference_record: {
+ ir_dereference_record *deref_record = (ir_dereference_record *) deref;
+ const glsl_type *struct_type = deref_record->record->type;
+ unsigned intra_struct_offset = 0;
+
+ for (unsigned int i = 0; i < struct_type->length; i++) {
+ const glsl_type *type = struct_type->fields.structure[i].type;
+
+ ir_dereference_record *field_deref = new(mem_ctx)
+ ir_dereference_record(deref_record->record,
+ struct_type->fields.structure[i].name);
+ const bool field_row_major =
+ is_dereferenced_thing_row_major(field_deref);
+
+ ralloc_free(field_deref);
+
+ unsigned field_align = 0;
+
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ field_align = type->std430_base_alignment(field_row_major);
+ else
+ field_align = type->std140_base_alignment(field_row_major);
+
+ intra_struct_offset = glsl_align(intra_struct_offset, field_align);
+
+ if (strcmp(struct_type->fields.structure[i].name,
+ deref_record->field) == 0)
+ break;
+
+ if (packing == GLSL_INTERFACE_PACKING_STD430)
+ intra_struct_offset += type->std430_size(field_row_major);
+ else
+ intra_struct_offset += type->std140_size(field_row_major);
+
+ /* If the field just examined was itself a structure, apply rule
+ * #9:
+ *
+ * "The structure may have padding at the end; the base offset
+ * of the member following the sub-structure is rounded up to
+ * the next multiple of the base alignment of the structure."
+ */
+ if (type->without_array()->is_record()) {
+ intra_struct_offset = glsl_align(intra_struct_offset,
+ field_align);
+
+ }
+ }
+
+ *const_offset += intra_struct_offset;
+ deref = deref_record->record->as_dereference();
+ break;
+ }
+
+ case ir_type_swizzle: {
+ ir_swizzle *deref_swizzle = (ir_swizzle *) deref;
+
+ assert(deref_swizzle->mask.num_components == 1);
+
+ *const_offset += deref_swizzle->mask.x * sizeof(int);
+ deref = deref_swizzle->val->as_dereference();
+ break;
+ }
+
+ default:
+ assert(!"not reached");
+ deref = NULL;
+ break;
+ }
+ }
+}
+
+} /* namespace lower_buffer_access */
diff --git a/src/glsl/lower_buffer_access.h b/src/glsl/lower_buffer_access.h
new file mode 100644
index 00000000000..cc4614e9792
--- /dev/null
+++ b/src/glsl/lower_buffer_access.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015 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.
+ */
+
+/**
+ * \file lower_buffer_access.h
+ *
+ * Helper for IR lowering pass to replace dereferences of buffer object based
+ * shader variables with intrinsic function calls.
+ *
+ * This helper is used by lowering passes for UBOs, SSBOs and compute shader
+ * shared variables.
+ */
+
+#pragma once
+#ifndef LOWER_BUFFER_ACCESS_H
+#define LOWER_BUFFER_ACCESS_H
+
+#include "ir.h"
+#include "ir_rvalue_visitor.h"
+
+namespace lower_buffer_access {
+
+class lower_buffer_access : public ir_rvalue_enter_visitor {
+public:
+ virtual void
+ insert_buffer_access(void *mem_ctx, ir_dereference *deref,
+ const glsl_type *type, ir_rvalue *offset,
+ unsigned mask, int channel) = 0;
+
+ void emit_access(void *mem_ctx, bool is_write, ir_dereference *deref,
+ ir_variable *base_offset, unsigned int deref_offset,
+ bool row_major, int matrix_columns,
+ unsigned int packing, unsigned int write_mask);
+
+ bool is_dereferenced_thing_row_major(const ir_rvalue *deref);
+
+ void setup_buffer_access(void *mem_ctx, ir_variable *var, ir_rvalue *deref,
+ ir_rvalue **offset, unsigned *const_offset,
+ bool *row_major, int *matrix_columns,
+ unsigned packing);
+};
+
+} /* namespace lower_buffer_access */
+
+#endif /* LOWER_BUFFER_ACCESS_H */
diff --git a/src/glsl/lower_named_interface_blocks.cpp b/src/glsl/lower_named_interface_blocks.cpp
index 114bb5811b4..f29eba4f75f 100644
--- a/src/glsl/lower_named_interface_blocks.cpp
+++ b/src/glsl/lower_named_interface_blocks.cpp
@@ -187,6 +187,7 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
new_var->data.sample = iface_t->fields.structure[i].sample;
new_var->data.patch = iface_t->fields.structure[i].patch;
new_var->data.stream = var->data.stream;
+ new_var->data.how_declared = var->data.how_declared;
new_var->init_interface_type(iface_t);
hash_table_insert(interface_namespace, new_var,
diff --git a/src/glsl/lower_packed_varyings.cpp b/src/glsl/lower_packed_varyings.cpp
index 037c27d88ab..8d1eb1725d5 100644
--- a/src/glsl/lower_packed_varyings.cpp
+++ b/src/glsl/lower_packed_varyings.cpp
@@ -622,6 +622,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
packed_var->data.interpolation = unpacked_var->data.interpolation;
packed_var->data.location = location;
packed_var->data.precision = unpacked_var->data.precision;
+ packed_var->data.always_active_io = unpacked_var->data.always_active_io;
unpacked_var->insert_before(packed_var);
this->packed_varyings[slot] = packed_var;
} else {
diff --git a/src/glsl/lower_shared_reference.cpp b/src/glsl/lower_shared_reference.cpp
new file mode 100644
index 00000000000..533cd9202f4
--- /dev/null
+++ b/src/glsl/lower_shared_reference.cpp
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2015 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.
+ */
+
+/**
+ * \file lower_shared_reference.cpp
+ *
+ * IR lower pass to replace dereferences of compute shader shared variables
+ * with intrinsic function calls.
+ *
+ * This relieves drivers of the responsibility of allocating space for the
+ * shared variables in the shared memory region.
+ */
+
+#include "lower_buffer_access.h"
+#include "ir_builder.h"
+#include "main/macros.h"
+#include "util/list.h"
+#include "glsl_parser_extras.h"
+
+using namespace ir_builder;
+
+namespace {
+
+struct var_offset {
+ struct list_head node;
+ const ir_variable *var;
+ unsigned offset;
+};
+
+class lower_shared_reference_visitor :
+ public lower_buffer_access::lower_buffer_access {
+public:
+
+ lower_shared_reference_visitor(struct gl_shader *shader)
+ : list_ctx(ralloc_context(NULL)), shader(shader), shared_size(0u)
+ {
+ list_inithead(&var_offsets);
+ }
+
+ ~lower_shared_reference_visitor()
+ {
+ ralloc_free(list_ctx);
+ }
+
+ enum {
+ shared_load_access,
+ shared_store_access,
+ shared_atomic_access,
+ } buffer_access_type;
+
+ void insert_buffer_access(void *mem_ctx, ir_dereference *deref,
+ const glsl_type *type, ir_rvalue *offset,
+ unsigned mask, int channel);
+
+ void handle_rvalue(ir_rvalue **rvalue);
+ ir_visitor_status visit_enter(ir_assignment *ir);
+ void handle_assignment(ir_assignment *ir);
+
+ ir_call *lower_shared_atomic_intrinsic(ir_call *ir);
+ ir_call *check_for_shared_atomic_intrinsic(ir_call *ir);
+ ir_visitor_status visit_enter(ir_call *ir);
+
+ unsigned get_shared_offset(const ir_variable *);
+
+ ir_call *shared_load(void *mem_ctx, const struct glsl_type *type,
+ ir_rvalue *offset);
+ ir_call *shared_store(void *mem_ctx, ir_rvalue *deref, ir_rvalue *offset,
+ unsigned write_mask);
+
+ void *list_ctx;
+ struct gl_shader *shader;
+ struct list_head var_offsets;
+ unsigned shared_size;
+ bool progress;
+};
+
+unsigned
+lower_shared_reference_visitor::get_shared_offset(const ir_variable *var)
+{
+ list_for_each_entry(var_offset, var_entry, &var_offsets, node) {
+ if (var_entry->var == var)
+ return var_entry->offset;
+ }
+
+ struct var_offset *new_entry = rzalloc(list_ctx, struct var_offset);
+ list_add(&new_entry->node, &var_offsets);
+ new_entry->var = var;
+
+ unsigned var_align = var->type->std430_base_alignment(false);
+ new_entry->offset = glsl_align(shared_size, var_align);
+
+ unsigned var_size = var->type->std430_size(false);
+ shared_size = new_entry->offset + var_size;
+
+ return new_entry->offset;
+}
+
+void
+lower_shared_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ ir_dereference *deref = (*rvalue)->as_dereference();
+ if (!deref)
+ return;
+
+ ir_variable *var = deref->variable_referenced();
+ if (!var || var->data.mode != ir_var_shader_shared)
+ return;
+
+ buffer_access_type = shared_load_access;
+
+ void *mem_ctx = ralloc_parent(shader->ir);
+
+ ir_rvalue *offset = NULL;
+ unsigned const_offset = get_shared_offset(var);
+ bool row_major;
+ int matrix_columns;
+ assert(var->get_interface_type() == NULL);
+ const unsigned packing = GLSL_INTERFACE_PACKING_STD430;
+
+ setup_buffer_access(mem_ctx, var, deref,
+ &offset, &const_offset,
+ &row_major, &matrix_columns, packing);
+
+ /* Now that we've calculated the offset to the start of the
+ * dereference, walk over the type and emit loads into a temporary.
+ */
+ const glsl_type *type = (*rvalue)->type;
+ ir_variable *load_var = new(mem_ctx) ir_variable(type,
+ "shared_load_temp",
+ ir_var_temporary);
+ base_ir->insert_before(load_var);
+
+ ir_variable *load_offset = new(mem_ctx) ir_variable(glsl_type::uint_type,
+ "shared_load_temp_offset",
+ ir_var_temporary);
+ base_ir->insert_before(load_offset);
+ base_ir->insert_before(assign(load_offset, offset));
+
+ deref = new(mem_ctx) ir_dereference_variable(load_var);
+
+ emit_access(mem_ctx, false, deref, load_offset, const_offset, row_major,
+ matrix_columns, packing, 0);
+
+ *rvalue = deref;
+
+ progress = true;
+}
+
+void
+lower_shared_reference_visitor::handle_assignment(ir_assignment *ir)
+{
+ if (!ir || !ir->lhs)
+ return;
+
+ ir_rvalue *rvalue = ir->lhs->as_rvalue();
+ if (!rvalue)
+ return;
+
+ ir_dereference *deref = ir->lhs->as_dereference();
+ if (!deref)
+ return;
+
+ ir_variable *var = ir->lhs->variable_referenced();
+ if (!var || var->data.mode != ir_var_shader_shared)
+ return;
+
+ buffer_access_type = shared_store_access;
+
+ /* We have a write to a shared variable, so declare a temporary and rewrite
+ * the assignment so that the temporary is the LHS.
+ */
+ void *mem_ctx = ralloc_parent(shader->ir);
+
+ const glsl_type *type = rvalue->type;
+ ir_variable *store_var = new(mem_ctx) ir_variable(type,
+ "shared_store_temp",
+ ir_var_temporary);
+ base_ir->insert_before(store_var);
+ ir->lhs = new(mem_ctx) ir_dereference_variable(store_var);
+
+ ir_rvalue *offset = NULL;
+ unsigned const_offset = get_shared_offset(var);
+ bool row_major;
+ int matrix_columns;
+ assert(var->get_interface_type() == NULL);
+ const unsigned packing = GLSL_INTERFACE_PACKING_STD430;
+
+ setup_buffer_access(mem_ctx, var, deref,
+ &offset, &const_offset,
+ &row_major, &matrix_columns, packing);
+
+ deref = new(mem_ctx) ir_dereference_variable(store_var);
+
+ ir_variable *store_offset = new(mem_ctx) ir_variable(glsl_type::uint_type,
+ "shared_store_temp_offset",
+ ir_var_temporary);
+ base_ir->insert_before(store_offset);
+ base_ir->insert_before(assign(store_offset, offset));
+
+ /* Now we have to write the value assigned to the temporary back to memory */
+ emit_access(mem_ctx, true, deref, store_offset, const_offset, row_major,
+ matrix_columns, packing, ir->write_mask);
+
+ progress = true;
+}
+
+ir_visitor_status
+lower_shared_reference_visitor::visit_enter(ir_assignment *ir)
+{
+ handle_assignment(ir);
+ return rvalue_visit(ir);
+}
+
+void
+lower_shared_reference_visitor::insert_buffer_access(void *mem_ctx,
+ ir_dereference *deref,
+ const glsl_type *type,
+ ir_rvalue *offset,
+ unsigned mask,
+ int channel)
+{
+ if (buffer_access_type == shared_store_access) {
+ ir_call *store = shared_store(mem_ctx, deref, offset, mask);
+ base_ir->insert_after(store);
+ } else {
+ ir_call *load = shared_load(mem_ctx, type, offset);
+ base_ir->insert_before(load);
+ ir_rvalue *value = load->return_deref->as_rvalue()->clone(mem_ctx, NULL);
+ base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
+ value));
+ }
+}
+
+static bool
+compute_shader_enabled(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_COMPUTE;
+}
+
+ir_call *
+lower_shared_reference_visitor::shared_store(void *mem_ctx,
+ ir_rvalue *deref,
+ ir_rvalue *offset,
+ unsigned write_mask)
+{
+ exec_list sig_params;
+
+ ir_variable *offset_ref = new(mem_ctx)
+ ir_variable(glsl_type::uint_type, "offset" , ir_var_function_in);
+ sig_params.push_tail(offset_ref);
+
+ ir_variable *val_ref = new(mem_ctx)
+ ir_variable(deref->type, "value" , ir_var_function_in);
+ sig_params.push_tail(val_ref);
+
+ ir_variable *writemask_ref = new(mem_ctx)
+ ir_variable(glsl_type::uint_type, "write_mask" , ir_var_function_in);
+ sig_params.push_tail(writemask_ref);
+
+ ir_function_signature *sig = new(mem_ctx)
+ ir_function_signature(glsl_type::void_type, compute_shader_enabled);
+ assert(sig);
+ sig->replace_parameters(&sig_params);
+ sig->is_intrinsic = true;
+
+ ir_function *f = new(mem_ctx) ir_function("__intrinsic_store_shared");
+ f->add_signature(sig);
+
+ exec_list call_params;
+ call_params.push_tail(offset->clone(mem_ctx, NULL));
+ call_params.push_tail(deref->clone(mem_ctx, NULL));
+ call_params.push_tail(new(mem_ctx) ir_constant(write_mask));
+ return new(mem_ctx) ir_call(sig, NULL, &call_params);
+}
+
+ir_call *
+lower_shared_reference_visitor::shared_load(void *mem_ctx,
+ const struct glsl_type *type,
+ ir_rvalue *offset)
+{
+ exec_list sig_params;
+
+ ir_variable *offset_ref = new(mem_ctx)
+ ir_variable(glsl_type::uint_type, "offset_ref" , ir_var_function_in);
+ sig_params.push_tail(offset_ref);
+
+ ir_function_signature *sig =
+ new(mem_ctx) ir_function_signature(type, compute_shader_enabled);
+ assert(sig);
+ sig->replace_parameters(&sig_params);
+ sig->is_intrinsic = true;
+
+ ir_function *f = new(mem_ctx) ir_function("__intrinsic_load_shared");
+ f->add_signature(sig);
+
+ ir_variable *result = new(mem_ctx)
+ ir_variable(type, "shared_load_result", ir_var_temporary);
+ base_ir->insert_before(result);
+ ir_dereference_variable *deref_result = new(mem_ctx)
+ ir_dereference_variable(result);
+
+ exec_list call_params;
+ call_params.push_tail(offset->clone(mem_ctx, NULL));
+
+ return new(mem_ctx) ir_call(sig, deref_result, &call_params);
+}
+
+/* Lowers the intrinsic call to a new internal intrinsic that swaps the access
+ * to the shared variable in the first parameter by an offset. This involves
+ * creating the new internal intrinsic (i.e. the new function signature).
+ */
+ir_call *
+lower_shared_reference_visitor::lower_shared_atomic_intrinsic(ir_call *ir)
+{
+ /* Shared atomics usually have 2 parameters, the shared variable and an
+ * integer argument. The exception is CompSwap, that has an additional
+ * integer parameter.
+ */
+ int param_count = ir->actual_parameters.length();
+ assert(param_count == 2 || param_count == 3);
+
+ /* First argument must be a scalar integer shared variable */
+ exec_node *param = ir->actual_parameters.get_head();
+ ir_instruction *inst = (ir_instruction *) param;
+ assert(inst->ir_type == ir_type_dereference_variable ||
+ inst->ir_type == ir_type_dereference_array ||
+ inst->ir_type == ir_type_dereference_record ||
+ inst->ir_type == ir_type_swizzle);
+
+ ir_rvalue *deref = (ir_rvalue *) inst;
+ assert(deref->type->is_scalar() && deref->type->is_integer());
+
+ ir_variable *var = deref->variable_referenced();
+ assert(var);
+
+ /* Compute the offset to the start if the dereference
+ */
+ void *mem_ctx = ralloc_parent(shader->ir);
+
+ ir_rvalue *offset = NULL;
+ unsigned const_offset = get_shared_offset(var);
+ bool row_major;
+ int matrix_columns;
+ assert(var->get_interface_type() == NULL);
+ const unsigned packing = GLSL_INTERFACE_PACKING_STD430;
+ buffer_access_type = shared_atomic_access;
+
+ setup_buffer_access(mem_ctx, var, deref,
+ &offset, &const_offset,
+ &row_major, &matrix_columns, packing);
+
+ assert(offset);
+ assert(!row_major);
+ assert(matrix_columns == 1);
+
+ ir_rvalue *deref_offset =
+ add(offset, new(mem_ctx) ir_constant(const_offset));
+
+ /* Create the new internal function signature that will take an offset
+ * instead of a shared variable
+ */
+ exec_list sig_params;
+ ir_variable *sig_param = new(mem_ctx)
+ ir_variable(glsl_type::uint_type, "offset" , ir_var_function_in);
+ sig_params.push_tail(sig_param);
+
+ const glsl_type *type = deref->type->base_type == GLSL_TYPE_INT ?
+ glsl_type::int_type : glsl_type::uint_type;
+ sig_param = new(mem_ctx)
+ ir_variable(type, "data1", ir_var_function_in);
+ sig_params.push_tail(sig_param);
+
+ if (param_count == 3) {
+ sig_param = new(mem_ctx)
+ ir_variable(type, "data2", ir_var_function_in);
+ sig_params.push_tail(sig_param);
+ }
+
+ ir_function_signature *sig =
+ new(mem_ctx) ir_function_signature(deref->type,
+ compute_shader_enabled);
+ assert(sig);
+ sig->replace_parameters(&sig_params);
+ sig->is_intrinsic = true;
+
+ char func_name[64];
+ sprintf(func_name, "%s_shared", ir->callee_name());
+ ir_function *f = new(mem_ctx) ir_function(func_name);
+ f->add_signature(sig);
+
+ /* Now, create the call to the internal intrinsic */
+ exec_list call_params;
+ call_params.push_tail(deref_offset);
+ param = ir->actual_parameters.get_head()->get_next();
+ ir_rvalue *param_as_rvalue = ((ir_instruction *) param)->as_rvalue();
+ call_params.push_tail(param_as_rvalue->clone(mem_ctx, NULL));
+ if (param_count == 3) {
+ param = param->get_next();
+ param_as_rvalue = ((ir_instruction *) param)->as_rvalue();
+ call_params.push_tail(param_as_rvalue->clone(mem_ctx, NULL));
+ }
+ ir_dereference_variable *return_deref =
+ ir->return_deref->clone(mem_ctx, NULL);
+ return new(mem_ctx) ir_call(sig, return_deref, &call_params);
+}
+
+ir_call *
+lower_shared_reference_visitor::check_for_shared_atomic_intrinsic(ir_call *ir)
+{
+ exec_list& params = ir->actual_parameters;
+
+ if (params.length() < 2 || params.length() > 3)
+ return ir;
+
+ ir_rvalue *rvalue =
+ ((ir_instruction *) params.get_head())->as_rvalue();
+ if (!rvalue)
+ return ir;
+
+ ir_variable *var = rvalue->variable_referenced();
+ if (!var || var->data.mode != ir_var_shader_shared)
+ return ir;
+
+ const char *callee = ir->callee_name();
+ if (!strcmp("__intrinsic_atomic_add", callee) ||
+ !strcmp("__intrinsic_atomic_min", callee) ||
+ !strcmp("__intrinsic_atomic_max", callee) ||
+ !strcmp("__intrinsic_atomic_and", callee) ||
+ !strcmp("__intrinsic_atomic_or", callee) ||
+ !strcmp("__intrinsic_atomic_xor", callee) ||
+ !strcmp("__intrinsic_atomic_exchange", callee) ||
+ !strcmp("__intrinsic_atomic_comp_swap", callee)) {
+ return lower_shared_atomic_intrinsic(ir);
+ }
+
+ return ir;
+}
+
+ir_visitor_status
+lower_shared_reference_visitor::visit_enter(ir_call *ir)
+{
+ ir_call *new_ir = check_for_shared_atomic_intrinsic(ir);
+ if (new_ir != ir) {
+ progress = true;
+ base_ir->replace_with(new_ir);
+ return visit_continue_with_parent;
+ }
+
+ return rvalue_visit(ir);
+}
+
+} /* unnamed namespace */
+
+void
+lower_shared_reference(struct gl_shader *shader, unsigned *shared_size)
+{
+ if (shader->Stage != MESA_SHADER_COMPUTE)
+ return;
+
+ lower_shared_reference_visitor v(shader);
+
+ /* Loop over the instructions lowering references, because we take a deref
+ * of an shared variable array using a shared variable dereference as the
+ * index will produce a collection of instructions all of which have cloned
+ * shared variable dereferences for that array index.
+ */
+ do {
+ v.progress = false;
+ visit_list_elements(&v, shader->ir);
+ } while (v.progress);
+
+ *shared_size = v.shared_size;
+}
diff --git a/src/glsl/lower_ubo_reference.cpp b/src/glsl/lower_ubo_reference.cpp
index b74aa3d0630..a172054bac8 100644
--- a/src/glsl/lower_ubo_reference.cpp
+++ b/src/glsl/lower_ubo_reference.cpp
@@ -33,106 +33,16 @@
* their own.
*/
-#include "ir.h"
+#include "lower_buffer_access.h"
#include "ir_builder.h"
-#include "ir_rvalue_visitor.h"
#include "main/macros.h"
#include "glsl_parser_extras.h"
using namespace ir_builder;
-/**
- * Determine if a thing being dereferenced is row-major
- *
- * There is some trickery here.
- *
- * If the thing being dereferenced is a member of uniform block \b without an
- * instance name, then the name of the \c ir_variable is the field name of an
- * interface type. If this field is row-major, then the thing referenced is
- * row-major.
- *
- * If the thing being dereferenced is a member of uniform block \b with an
- * instance name, then the last dereference in the tree will be an
- * \c ir_dereference_record. If that record field is row-major, then the
- * thing referenced is row-major.
- */
-static bool
-is_dereferenced_thing_row_major(const ir_rvalue *deref)
-{
- bool matrix = false;
- const ir_rvalue *ir = deref;
-
- while (true) {
- matrix = matrix || ir->type->without_array()->is_matrix();
-
- switch (ir->ir_type) {
- case ir_type_dereference_array: {
- const ir_dereference_array *const array_deref =
- (const ir_dereference_array *) ir;
-
- ir = array_deref->array;
- break;
- }
-
- case ir_type_dereference_record: {
- const ir_dereference_record *const record_deref =
- (const ir_dereference_record *) ir;
-
- ir = record_deref->record;
-
- const int idx = ir->type->field_index(record_deref->field);
- assert(idx >= 0);
-
- const enum glsl_matrix_layout matrix_layout =
- glsl_matrix_layout(ir->type->fields.structure[idx].matrix_layout);
-
- switch (matrix_layout) {
- case GLSL_MATRIX_LAYOUT_INHERITED:
- break;
- case GLSL_MATRIX_LAYOUT_COLUMN_MAJOR:
- return false;
- case GLSL_MATRIX_LAYOUT_ROW_MAJOR:
- return matrix || deref->type->without_array()->is_record();
- }
-
- break;
- }
-
- case ir_type_dereference_variable: {
- const ir_dereference_variable *const var_deref =
- (const ir_dereference_variable *) ir;
-
- const enum glsl_matrix_layout matrix_layout =
- glsl_matrix_layout(var_deref->var->data.matrix_layout);
-
- switch (matrix_layout) {
- case GLSL_MATRIX_LAYOUT_INHERITED:
- assert(!matrix);
- return false;
- case GLSL_MATRIX_LAYOUT_COLUMN_MAJOR:
- return false;
- case GLSL_MATRIX_LAYOUT_ROW_MAJOR:
- return matrix || deref->type->without_array()->is_record();
- }
-
- unreachable("invalid matrix layout");
- break;
- }
-
- default:
- return false;
- }
- }
-
- /* The tree must have ended with a dereference that wasn't an
- * ir_dereference_variable. That is invalid, and it should be impossible.
- */
- unreachable("invalid dereference tree");
- return false;
-}
-
namespace {
-class lower_ubo_reference_visitor : public ir_rvalue_enter_visitor {
+class lower_ubo_reference_visitor :
+ public lower_buffer_access::lower_buffer_access {
public:
lower_ubo_reference_visitor(struct gl_shader *shader)
: shader(shader)
@@ -142,30 +52,38 @@ public:
void handle_rvalue(ir_rvalue **rvalue);
ir_visitor_status visit_enter(ir_assignment *ir);
- void setup_for_load_or_store(ir_variable *var,
+ void setup_for_load_or_store(void *mem_ctx,
+ ir_variable *var,
ir_rvalue *deref,
ir_rvalue **offset,
unsigned *const_offset,
bool *row_major,
int *matrix_columns,
unsigned packing);
- ir_expression *ubo_load(const struct glsl_type *type,
+ ir_expression *ubo_load(void *mem_ctx, const struct glsl_type *type,
ir_rvalue *offset);
- ir_call *ssbo_load(const struct glsl_type *type,
+ ir_call *ssbo_load(void *mem_ctx, const struct glsl_type *type,
ir_rvalue *offset);
+ bool check_for_buffer_array_copy(ir_assignment *ir);
+ bool check_for_buffer_struct_copy(ir_assignment *ir);
void check_for_ssbo_store(ir_assignment *ir);
- void write_to_memory(ir_dereference *deref,
- ir_variable *var,
- ir_variable *write_var,
- unsigned write_mask);
- ir_call *ssbo_store(ir_rvalue *deref, ir_rvalue *offset,
+ void write_to_memory(void *mem_ctx, ir_dereference *deref, ir_variable *var,
+ ir_variable *write_var, unsigned write_mask);
+ ir_call *ssbo_store(void *mem_ctx, ir_rvalue *deref, ir_rvalue *offset,
unsigned write_mask);
- void emit_access(bool is_write, ir_dereference *deref,
- ir_variable *base_offset, unsigned int deref_offset,
- bool row_major, int matrix_columns,
- unsigned packing, unsigned write_mask);
+ enum {
+ ubo_load_access,
+ ssbo_load_access,
+ ssbo_store_access,
+ ssbo_unsized_array_length_access,
+ ssbo_atomic_access,
+ } buffer_access_type;
+
+ void insert_buffer_access(void *mem_ctx, ir_dereference *deref,
+ const glsl_type *type, ir_rvalue *offset,
+ unsigned mask, int channel);
ir_visitor_status visit_enter(class ir_expression *);
ir_expression *calculate_ssbo_unsized_array_length(ir_expression *expr);
@@ -175,7 +93,7 @@ public:
ir_expression *process_ssbo_unsized_array_length(ir_rvalue **,
ir_dereference *,
ir_variable *);
- ir_expression *emit_ssbo_get_buffer_size();
+ ir_expression *emit_ssbo_get_buffer_size(void *mem_ctx);
unsigned calculate_unsized_array_stride(ir_dereference *deref,
unsigned packing);
@@ -184,12 +102,10 @@ public:
ir_call *check_for_ssbo_atomic_intrinsic(ir_call *ir);
ir_visitor_status visit_enter(ir_call *ir);
- void *mem_ctx;
struct gl_shader *shader;
struct gl_uniform_buffer_variable *ubo_var;
ir_rvalue *uniform_block;
bool progress;
- bool is_shader_storage;
};
/**
@@ -324,7 +240,8 @@ interface_field_name(void *mem_ctx, char *base_name, ir_rvalue *d,
}
void
-lower_ubo_reference_visitor::setup_for_load_or_store(ir_variable *var,
+lower_ubo_reference_visitor::setup_for_load_or_store(void *mem_ctx,
+ ir_variable *var,
ir_rvalue *deref,
ir_rvalue **offset,
unsigned *const_offset,
@@ -339,10 +256,9 @@ lower_ubo_reference_visitor::setup_for_load_or_store(ir_variable *var,
deref, &nonconst_block_index);
/* Locate the block by interface name */
- this->is_shader_storage = var->is_in_shader_storage_block();
unsigned num_blocks;
struct gl_uniform_block **blocks;
- if (this->is_shader_storage) {
+ if (this->buffer_access_type != ubo_load_access) {
num_blocks = shader->NumShaderStorageBlocks;
blocks = shader->ShaderStorageBlocks;
} else {
@@ -370,164 +286,10 @@ lower_ubo_reference_visitor::setup_for_load_or_store(ir_variable *var,
assert(this->uniform_block);
- *offset = new(mem_ctx) ir_constant(0u);
- *const_offset = 0;
- *row_major = is_dereferenced_thing_row_major(deref);
- *matrix_columns = 1;
+ *const_offset = ubo_var->Offset;
- /* Calculate the offset to the start of the region of the UBO
- * dereferenced by *rvalue. This may be a variable offset if an
- * array dereference has a variable index.
- */
- while (deref) {
- switch (deref->ir_type) {
- case ir_type_dereference_variable: {
- *const_offset += ubo_var->Offset;
- deref = NULL;
- break;
- }
-
- case ir_type_dereference_array: {
- ir_dereference_array *deref_array = (ir_dereference_array *) deref;
- unsigned array_stride;
- if (deref_array->array->type->is_vector()) {
- /* We get this when storing or loading a component out of a vector
- * with a non-constant index. This happens for v[i] = f where v is
- * a vector (or m[i][j] = f where m is a matrix). If we don't
- * lower that here, it gets turned into v = vector_insert(v, i,
- * f), which loads the entire vector, modifies one component and
- * then write the entire thing back. That breaks if another
- * thread or SIMD channel is modifying the same vector.
- */
- array_stride = 4;
- if (deref_array->array->type->is_double())
- array_stride *= 2;
- } else if (deref_array->array->type->is_matrix() && *row_major) {
- /* When loading a vector out of a row major matrix, the
- * step between the columns (vectors) is the size of a
- * float, while the step between the rows (elements of a
- * vector) is handled below in emit_ubo_loads.
- */
- array_stride = 4;
- if (deref_array->array->type->is_double())
- array_stride *= 2;
- *matrix_columns = deref_array->array->type->matrix_columns;
- } else if (deref_array->type->without_array()->is_interface()) {
- /* We're processing an array dereference of an interface instance
- * array. The thing being dereferenced *must* be a variable
- * dereference because interfaces cannot be embedded in other
- * types. In terms of calculating the offsets for the lowering
- * pass, we don't care about the array index. All elements of an
- * interface instance array will have the same offsets relative to
- * the base of the block that backs them.
- */
- deref = deref_array->array->as_dereference();
- break;
- } else {
- /* Whether or not the field is row-major (because it might be a
- * bvec2 or something) does not affect the array itself. We need
- * to know whether an array element in its entirety is row-major.
- */
- const bool array_row_major =
- is_dereferenced_thing_row_major(deref_array);
-
- /* The array type will give the correct interface packing
- * information
- */
- if (packing == GLSL_INTERFACE_PACKING_STD430) {
- array_stride = deref_array->type->std430_array_stride(array_row_major);
- } else {
- array_stride = deref_array->type->std140_size(array_row_major);
- array_stride = glsl_align(array_stride, 16);
- }
- }
-
- ir_rvalue *array_index = deref_array->array_index;
- if (array_index->type->base_type == GLSL_TYPE_INT)
- array_index = i2u(array_index);
-
- ir_constant *const_index =
- array_index->constant_expression_value(NULL);
- if (const_index) {
- *const_offset += array_stride * const_index->value.u[0];
- } else {
- *offset = add(*offset,
- mul(array_index,
- new(mem_ctx) ir_constant(array_stride)));
- }
- deref = deref_array->array->as_dereference();
- break;
- }
-
- case ir_type_dereference_record: {
- ir_dereference_record *deref_record = (ir_dereference_record *) deref;
- const glsl_type *struct_type = deref_record->record->type;
- unsigned intra_struct_offset = 0;
-
- for (unsigned int i = 0; i < struct_type->length; i++) {
- const glsl_type *type = struct_type->fields.structure[i].type;
-
- ir_dereference_record *field_deref = new(mem_ctx)
- ir_dereference_record(deref_record->record,
- struct_type->fields.structure[i].name);
- const bool field_row_major =
- is_dereferenced_thing_row_major(field_deref);
-
- ralloc_free(field_deref);
-
- unsigned field_align = 0;
-
- if (packing == GLSL_INTERFACE_PACKING_STD430)
- field_align = type->std430_base_alignment(field_row_major);
- else
- field_align = type->std140_base_alignment(field_row_major);
-
- intra_struct_offset = glsl_align(intra_struct_offset, field_align);
-
- if (strcmp(struct_type->fields.structure[i].name,
- deref_record->field) == 0)
- break;
-
- if (packing == GLSL_INTERFACE_PACKING_STD430)
- intra_struct_offset += type->std430_size(field_row_major);
- else
- intra_struct_offset += type->std140_size(field_row_major);
-
- /* If the field just examined was itself a structure, apply rule
- * #9:
- *
- * "The structure may have padding at the end; the base offset
- * of the member following the sub-structure is rounded up to
- * the next multiple of the base alignment of the structure."
- */
- if (type->without_array()->is_record()) {
- intra_struct_offset = glsl_align(intra_struct_offset,
- field_align);
-
- }
- }
-
- *const_offset += intra_struct_offset;
- deref = deref_record->record->as_dereference();
- break;
- }
-
- case ir_type_swizzle: {
- ir_swizzle *deref_swizzle = (ir_swizzle *) deref;
-
- assert(deref_swizzle->mask.num_components == 1);
-
- *const_offset += deref_swizzle->mask.x * sizeof(int);
- deref = deref_swizzle->val->as_dereference();
- break;
- }
-
- default:
- assert(!"not reached");
- deref = NULL;
- break;
- }
- }
+ setup_buffer_access(mem_ctx, var, deref, offset, const_offset, row_major,
+ matrix_columns, packing);
}
void
@@ -544,7 +306,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
if (!var || !var->is_in_buffer_block())
return;
- mem_ctx = ralloc_parent(shader->ir);
+ void *mem_ctx = ralloc_parent(shader->ir);
ir_rvalue *offset = NULL;
unsigned const_offset;
@@ -552,10 +314,14 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
int matrix_columns;
unsigned packing = var->get_interface_type()->interface_packing;
+ this->buffer_access_type =
+ var->is_in_shader_storage_block() ?
+ ssbo_load_access : ubo_load_access;
+
/* Compute the offset to the start if the dereference as well as other
* information we need to configure the write
*/
- setup_for_load_or_store(var, deref,
+ setup_for_load_or_store(mem_ctx, var, deref,
&offset, &const_offset,
&row_major, &matrix_columns,
packing);
@@ -577,7 +343,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
base_ir->insert_before(assign(load_offset, offset));
deref = new(mem_ctx) ir_dereference_variable(load_var);
- emit_access(false, deref, load_offset, const_offset,
+ emit_access(mem_ctx, false, deref, load_offset, const_offset,
row_major, matrix_columns, packing, 0);
*rvalue = deref;
@@ -585,7 +351,8 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
}
ir_expression *
-lower_ubo_reference_visitor::ubo_load(const glsl_type *type,
+lower_ubo_reference_visitor::ubo_load(void *mem_ctx,
+ const glsl_type *type,
ir_rvalue *offset)
{
ir_rvalue *block_ref = this->uniform_block->clone(mem_ctx, NULL);
@@ -604,7 +371,8 @@ shader_storage_buffer_object(const _mesa_glsl_parse_state *state)
}
ir_call *
-lower_ubo_reference_visitor::ssbo_store(ir_rvalue *deref,
+lower_ubo_reference_visitor::ssbo_store(void *mem_ctx,
+ ir_rvalue *deref,
ir_rvalue *offset,
unsigned write_mask)
{
@@ -644,7 +412,8 @@ lower_ubo_reference_visitor::ssbo_store(ir_rvalue *deref,
}
ir_call *
-lower_ubo_reference_visitor::ssbo_load(const struct glsl_type *type,
+lower_ubo_reference_visitor::ssbo_load(void *mem_ctx,
+ const struct glsl_type *type,
ir_rvalue *offset)
{
exec_list sig_params;
@@ -679,208 +448,46 @@ lower_ubo_reference_visitor::ssbo_load(const struct glsl_type *type,
return new(mem_ctx) ir_call(sig, deref_result, &call_params);
}
-static inline int
-writemask_for_size(unsigned n)
-{
- return ((1 << n) - 1);
-}
-
-/**
- * Takes a deref and recursively calls itself to break the deref down to the
- * point that the reads or writes generated are contiguous scalars or vectors.
- */
void
-lower_ubo_reference_visitor::emit_access(bool is_write,
- ir_dereference *deref,
- ir_variable *base_offset,
- unsigned int deref_offset,
- bool row_major,
- int matrix_columns,
- unsigned packing,
- unsigned write_mask)
+lower_ubo_reference_visitor::insert_buffer_access(void *mem_ctx,
+ ir_dereference *deref,
+ const glsl_type *type,
+ ir_rvalue *offset,
+ unsigned mask,
+ int channel)
{
- if (deref->type->is_record()) {
- unsigned int field_offset = 0;
-
- for (unsigned i = 0; i < deref->type->length; i++) {
- const struct glsl_struct_field *field =
- &deref->type->fields.structure[i];
- ir_dereference *field_deref =
- new(mem_ctx) ir_dereference_record(deref->clone(mem_ctx, NULL),
- field->name);
-
- field_offset =
- glsl_align(field_offset,
- field->type->std140_base_alignment(row_major));
-
- emit_access(is_write, field_deref, base_offset,
- deref_offset + field_offset,
- row_major, 1, packing,
- writemask_for_size(field_deref->type->vector_elements));
-
- field_offset += field->type->std140_size(row_major);
- }
- return;
+ switch (this->buffer_access_type) {
+ case ubo_load_access:
+ base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
+ ubo_load(mem_ctx, type, offset),
+ mask));
+ break;
+ case ssbo_load_access: {
+ ir_call *load_ssbo = ssbo_load(mem_ctx, type, offset);
+ base_ir->insert_before(load_ssbo);
+ ir_rvalue *value = load_ssbo->return_deref->as_rvalue()->clone(mem_ctx, NULL);
+ ir_assignment *assignment =
+ assign(deref->clone(mem_ctx, NULL), value, mask);
+ base_ir->insert_before(assignment);
+ break;
}
-
- if (deref->type->is_array()) {
- unsigned array_stride = packing == GLSL_INTERFACE_PACKING_STD430 ?
- deref->type->fields.array->std430_array_stride(row_major) :
- glsl_align(deref->type->fields.array->std140_size(row_major), 16);
-
- for (unsigned i = 0; i < deref->type->length; i++) {
- ir_constant *element = new(mem_ctx) ir_constant(i);
- ir_dereference *element_deref =
- new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL),
- element);
- emit_access(is_write, element_deref, base_offset,
- deref_offset + i * array_stride,
- row_major, 1, packing,
- writemask_for_size(element_deref->type->vector_elements));
- }
- return;
- }
-
- if (deref->type->is_matrix()) {
- for (unsigned i = 0; i < deref->type->matrix_columns; i++) {
- ir_constant *col = new(mem_ctx) ir_constant(i);
- ir_dereference *col_deref =
- new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL), col);
-
- if (row_major) {
- /* For a row-major matrix, the next column starts at the next
- * element.
- */
- int size_mul = deref->type->is_double() ? 8 : 4;
- emit_access(is_write, col_deref, base_offset,
- deref_offset + i * size_mul,
- row_major, deref->type->matrix_columns, packing,
- writemask_for_size(col_deref->type->vector_elements));
- } else {
- int size_mul;
-
- /* std430 doesn't round up vec2 size to a vec4 size */
- if (packing == GLSL_INTERFACE_PACKING_STD430 &&
- deref->type->vector_elements == 2 &&
- !deref->type->is_double()) {
- size_mul = 8;
- } else {
- /* std140 always rounds the stride of arrays (and matrices) to a
- * vec4, so matrices are always 16 between columns/rows. With
- * doubles, they will be 32 apart when there are more than 2 rows.
- *
- * For both std140 and std430, if the member is a
- * three-'component vector with components consuming N basic
- * machine units, the base alignment is 4N. For vec4, base
- * alignment is 4N.
- */
- size_mul = (deref->type->is_double() &&
- deref->type->vector_elements > 2) ? 32 : 16;
- }
-
- emit_access(is_write, col_deref, base_offset,
- deref_offset + i * size_mul,
- row_major, deref->type->matrix_columns, packing,
- writemask_for_size(col_deref->type->vector_elements));
- }
- }
- return;
- }
-
- assert(deref->type->is_scalar() || deref->type->is_vector());
-
- if (!row_major) {
- ir_rvalue *offset =
- add(base_offset, new(mem_ctx) ir_constant(deref_offset));
- if (is_write)
- base_ir->insert_after(ssbo_store(deref, offset, write_mask));
- else {
- if (!this->is_shader_storage) {
- base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
- ubo_load(deref->type, offset)));
- } else {
- ir_call *load_ssbo = ssbo_load(deref->type, offset);
- base_ir->insert_before(load_ssbo);
- ir_rvalue *value = load_ssbo->return_deref->as_rvalue()->clone(mem_ctx, NULL);
- base_ir->insert_before(assign(deref->clone(mem_ctx, NULL), value));
- }
- }
- } else {
- unsigned N = deref->type->is_double() ? 8 : 4;
-
- /* We're dereffing a column out of a row-major matrix, so we
- * gather the vector from each stored row.
- */
- assert(deref->type->base_type == GLSL_TYPE_FLOAT ||
- deref->type->base_type == GLSL_TYPE_DOUBLE);
- /* Matrices, row_major or not, are stored as if they were
- * arrays of vectors of the appropriate size in std140.
- * Arrays have their strides rounded up to a vec4, so the
- * matrix stride is always 16. However a double matrix may either be 16
- * or 32 depending on the number of columns.
- */
- assert(matrix_columns <= 4);
- unsigned matrix_stride = 0;
- /* Matrix stride for std430 mat2xY matrices are not rounded up to
- * vec4 size. From OpenGL 4.3 spec, section 7.6.2.2 "Standard Uniform
- * Block Layout":
- *
- * "2. If the member is a two- or four-component vector with components
- * consuming N basic machine units, the base alignment is 2N or 4N,
- * respectively." [...]
- * "4. If the member is an array of scalars or vectors, the base alignment
- * and array stride are set to match the base alignment of a single array
- * element, according to rules (1), (2), and (3), and rounded up to the
- * base alignment of a vec4." [...]
- * "7. If the member is a row-major matrix with C columns and R rows, the
- * matrix is stored identically to an array of R row vectors with C
- * components each, according to rule (4)." [...]
- * "When using the std430 storage layout, shader storage blocks will be
- * laid out in buffer storage identically to uniform and shader storage
- * blocks using the std140 layout, except that the base alignment and
- * stride of arrays of scalars and vectors in rule 4 and of structures in
- * rule 9 are not rounded up a multiple of the base alignment of a vec4."
- */
- if (packing == GLSL_INTERFACE_PACKING_STD430 && matrix_columns == 2)
- matrix_stride = 2 * N;
- else
- matrix_stride = glsl_align(matrix_columns * N, 16);
-
- const glsl_type *deref_type = deref->type->base_type == GLSL_TYPE_FLOAT ?
- glsl_type::float_type : glsl_type::double_type;
-
- for (unsigned i = 0; i < deref->type->vector_elements; i++) {
- ir_rvalue *chan_offset =
- add(base_offset,
- new(mem_ctx) ir_constant(deref_offset + i * matrix_stride));
- if (is_write) {
- /* If the component is not in the writemask, then don't
- * store any value.
- */
- if (!((1 << i) & write_mask))
- continue;
-
- base_ir->insert_after(ssbo_store(swizzle(deref, i, 1), chan_offset, 1));
- } else {
- if (!this->is_shader_storage) {
- base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
- ubo_load(deref_type, chan_offset),
- (1U << i)));
- } else {
- ir_call *load_ssbo = ssbo_load(deref_type, chan_offset);
- base_ir->insert_before(load_ssbo);
- ir_rvalue *value = load_ssbo->return_deref->as_rvalue()->clone(mem_ctx, NULL);
- base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
- value,
- (1U << i)));
- }
- }
+ case ssbo_store_access:
+ if (channel >= 0) {
+ base_ir->insert_after(ssbo_store(mem_ctx,
+ swizzle(deref, channel, 1),
+ offset, 1));
+ } else {
+ base_ir->insert_after(ssbo_store(mem_ctx, deref, offset, mask));
}
+ break;
+ default:
+ unreachable("invalid buffer_access_type in insert_buffer_access");
}
}
void
-lower_ubo_reference_visitor::write_to_memory(ir_dereference *deref,
+lower_ubo_reference_visitor::write_to_memory(void *mem_ctx,
+ ir_dereference *deref,
ir_variable *var,
ir_variable *write_var,
unsigned write_mask)
@@ -891,10 +498,12 @@ lower_ubo_reference_visitor::write_to_memory(ir_dereference *deref,
int matrix_columns;
unsigned packing = var->get_interface_type()->interface_packing;
+ this->buffer_access_type = ssbo_store_access;
+
/* Compute the offset to the start if the dereference as well as other
* information we need to configure the write
*/
- setup_for_load_or_store(var, deref,
+ setup_for_load_or_store(mem_ctx, var, deref,
&offset, &const_offset,
&row_major, &matrix_columns,
packing);
@@ -910,7 +519,7 @@ lower_ubo_reference_visitor::write_to_memory(ir_dereference *deref,
base_ir->insert_before(assign(write_offset, offset));
deref = new(mem_ctx) ir_dereference_variable(write_var);
- emit_access(true, deref, write_offset, const_offset,
+ emit_access(mem_ctx, true, deref, write_offset, const_offset,
row_major, matrix_columns, packing, write_mask);
}
@@ -985,7 +594,7 @@ lower_ubo_reference_visitor::check_ssbo_unsized_array_length_assignment(ir_assig
}
ir_expression *
-lower_ubo_reference_visitor::emit_ssbo_get_buffer_size()
+lower_ubo_reference_visitor::emit_ssbo_get_buffer_size(void *mem_ctx)
{
ir_rvalue *block_ref = this->uniform_block->clone(mem_ctx, NULL);
return new(mem_ctx) ir_expression(ir_unop_get_buffer_size,
@@ -1059,7 +668,7 @@ lower_ubo_reference_visitor::process_ssbo_unsized_array_length(ir_rvalue **rvalu
ir_dereference *deref,
ir_variable *var)
{
- mem_ctx = ralloc_parent(*rvalue);
+ void *mem_ctx = ralloc_parent(*rvalue);
ir_rvalue *base_offset = NULL;
unsigned const_offset;
@@ -1068,17 +677,19 @@ lower_ubo_reference_visitor::process_ssbo_unsized_array_length(ir_rvalue **rvalu
unsigned packing = var->get_interface_type()->interface_packing;
int unsized_array_stride = calculate_unsized_array_stride(deref, packing);
+ this->buffer_access_type = ssbo_unsized_array_length_access;
+
/* Compute the offset to the start if the dereference as well as other
* information we need to calculate the length.
*/
- setup_for_load_or_store(var, deref,
+ setup_for_load_or_store(mem_ctx, var, deref,
&base_offset, &const_offset,
&row_major, &matrix_columns,
packing);
/* array.length() =
* max((buffer_object_size - offset_of_array) / stride_of_array, 0)
*/
- ir_expression *buffer_size = emit_ssbo_get_buffer_size();
+ ir_expression *buffer_size = emit_ssbo_get_buffer_size(mem_ctx);
ir_expression *offset_of_array = new(mem_ctx)
ir_expression(ir_binop_add, base_offset,
@@ -1112,13 +723,13 @@ lower_ubo_reference_visitor::check_for_ssbo_store(ir_assignment *ir)
return;
ir_variable *var = ir->lhs->variable_referenced();
- if (!var || !var->is_in_buffer_block())
+ if (!var || !var->is_in_shader_storage_block())
return;
/* We have a write to a buffer variable, so declare a temporary and rewrite
* the assignment so that the temporary is the LHS.
*/
- mem_ctx = ralloc_parent(shader->ir);
+ void *mem_ctx = ralloc_parent(shader->ir);
const glsl_type *type = rvalue->type;
ir_variable *write_var = new(mem_ctx) ir_variable(type,
@@ -1128,14 +739,131 @@ lower_ubo_reference_visitor::check_for_ssbo_store(ir_assignment *ir)
ir->lhs = new(mem_ctx) ir_dereference_variable(write_var);
/* Now we have to write the value assigned to the temporary back to memory */
- write_to_memory(deref, var, write_var, ir->write_mask);
+ write_to_memory(mem_ctx, deref, var, write_var, ir->write_mask);
progress = true;
}
+static bool
+is_buffer_backed_variable(ir_variable *var)
+{
+ return var->is_in_buffer_block() ||
+ var->data.mode == ir_var_shader_shared;
+}
+
+bool
+lower_ubo_reference_visitor::check_for_buffer_array_copy(ir_assignment *ir)
+{
+ if (!ir || !ir->lhs || !ir->rhs)
+ return false;
+
+ /* LHS and RHS must be arrays
+ * FIXME: arrays of arrays?
+ */
+ if (!ir->lhs->type->is_array() || !ir->rhs->type->is_array())
+ return false;
+
+ /* RHS must be a buffer-backed variable. This is what can cause the problem
+ * since it would lead to a series of loads that need to live until we
+ * see the writes to the LHS.
+ */
+ ir_variable *rhs_var = ir->rhs->variable_referenced();
+ if (!rhs_var || !is_buffer_backed_variable(rhs_var))
+ return false;
+
+ /* Split the array copy into individual element copies to reduce
+ * register pressure
+ */
+ ir_dereference *rhs_deref = ir->rhs->as_dereference();
+ if (!rhs_deref)
+ return false;
+
+ ir_dereference *lhs_deref = ir->lhs->as_dereference();
+ if (!lhs_deref)
+ return false;
+
+ assert(lhs_deref->type->length == rhs_deref->type->length);
+ void *mem_ctx = ralloc_parent(shader->ir);
+
+ for (unsigned i = 0; i < lhs_deref->type->length; i++) {
+ ir_dereference *lhs_i =
+ new(mem_ctx) ir_dereference_array(lhs_deref->clone(mem_ctx, NULL),
+ new(mem_ctx) ir_constant(i));
+
+ ir_dereference *rhs_i =
+ new(mem_ctx) ir_dereference_array(rhs_deref->clone(mem_ctx, NULL),
+ new(mem_ctx) ir_constant(i));
+ ir->insert_after(assign(lhs_i, rhs_i));
+ }
+
+ ir->remove();
+ progress = true;
+ return true;
+}
+
+bool
+lower_ubo_reference_visitor::check_for_buffer_struct_copy(ir_assignment *ir)
+{
+ if (!ir || !ir->lhs || !ir->rhs)
+ return false;
+
+ /* LHS and RHS must be records */
+ if (!ir->lhs->type->is_record() || !ir->rhs->type->is_record())
+ return false;
+
+ /* RHS must be a buffer-backed variable. This is what can cause the problem
+ * since it would lead to a series of loads that need to live until we
+ * see the writes to the LHS.
+ */
+ ir_variable *rhs_var = ir->rhs->variable_referenced();
+ if (!rhs_var || !is_buffer_backed_variable(rhs_var))
+ return false;
+
+ /* Split the struct copy into individual element copies to reduce
+ * register pressure
+ */
+ ir_dereference *rhs_deref = ir->rhs->as_dereference();
+ if (!rhs_deref)
+ return false;
+
+ ir_dereference *lhs_deref = ir->lhs->as_dereference();
+ if (!lhs_deref)
+ return false;
+
+ assert(lhs_deref->type->record_compare(rhs_deref->type));
+ void *mem_ctx = ralloc_parent(shader->ir);
+
+ for (unsigned i = 0; i < lhs_deref->type->length; i++) {
+ const char *field_name = lhs_deref->type->fields.structure[i].name;
+ ir_dereference *lhs_field =
+ new(mem_ctx) ir_dereference_record(lhs_deref->clone(mem_ctx, NULL),
+ field_name);
+ ir_dereference *rhs_field =
+ new(mem_ctx) ir_dereference_record(rhs_deref->clone(mem_ctx, NULL),
+ field_name);
+ ir->insert_after(assign(lhs_field, rhs_field));
+ }
+
+ ir->remove();
+ progress = true;
+ return true;
+}
ir_visitor_status
lower_ubo_reference_visitor::visit_enter(ir_assignment *ir)
{
+ /* Array and struct copies could involve large amounts of load/store
+ * operations. To improve register pressure we want to special-case
+ * these and split them into individual element copies.
+ * This way we avoid emitting all the loads for the RHS first and
+ * all the writes for the LHS second and register usage is more
+ * efficient.
+ */
+ if (check_for_buffer_array_copy(ir))
+ return visit_continue_with_parent;
+
+ if (check_for_buffer_struct_copy(ir))
+ return visit_continue_with_parent;
+
check_ssbo_unsized_array_length_assignment(ir);
check_for_ssbo_store(ir);
return rvalue_visit(ir);
@@ -1173,7 +901,7 @@ lower_ubo_reference_visitor::lower_ssbo_atomic_intrinsic(ir_call *ir)
/* Compute the offset to the start if the dereference and the
* block index
*/
- mem_ctx = ralloc_parent(shader->ir);
+ void *mem_ctx = ralloc_parent(shader->ir);
ir_rvalue *offset = NULL;
unsigned const_offset;
@@ -1181,7 +909,9 @@ lower_ubo_reference_visitor::lower_ssbo_atomic_intrinsic(ir_call *ir)
int matrix_columns;
unsigned packing = var->get_interface_type()->interface_packing;
- setup_for_load_or_store(var, deref,
+ this->buffer_access_type = ssbo_atomic_access;
+
+ setup_for_load_or_store(mem_ctx, var, deref,
&offset, &const_offset,
&row_major, &matrix_columns,
packing);
@@ -1225,7 +955,7 @@ lower_ubo_reference_visitor::lower_ssbo_atomic_intrinsic(ir_call *ir)
sig->is_intrinsic = true;
char func_name[64];
- sprintf(func_name, "%s_internal", ir->callee_name());
+ sprintf(func_name, "%s_ssbo", ir->callee_name());
ir_function *f = new(mem_ctx) ir_function(func_name);
f->add_signature(sig);
@@ -1249,15 +979,29 @@ lower_ubo_reference_visitor::lower_ssbo_atomic_intrinsic(ir_call *ir)
ir_call *
lower_ubo_reference_visitor::check_for_ssbo_atomic_intrinsic(ir_call *ir)
{
+ exec_list& params = ir->actual_parameters;
+
+ if (params.length() < 2 || params.length() > 3)
+ return ir;
+
+ ir_rvalue *rvalue =
+ ((ir_instruction *) params.get_head())->as_rvalue();
+ if (!rvalue)
+ return ir;
+
+ ir_variable *var = rvalue->variable_referenced();
+ if (!var || !var->is_in_shader_storage_block())
+ return ir;
+
const char *callee = ir->callee_name();
- if (!strcmp("__intrinsic_ssbo_atomic_add", callee) ||
- !strcmp("__intrinsic_ssbo_atomic_min", callee) ||
- !strcmp("__intrinsic_ssbo_atomic_max", callee) ||
- !strcmp("__intrinsic_ssbo_atomic_and", callee) ||
- !strcmp("__intrinsic_ssbo_atomic_or", callee) ||
- !strcmp("__intrinsic_ssbo_atomic_xor", callee) ||
- !strcmp("__intrinsic_ssbo_atomic_exchange", callee) ||
- !strcmp("__intrinsic_ssbo_atomic_comp_swap", callee)) {
+ if (!strcmp("__intrinsic_atomic_add", callee) ||
+ !strcmp("__intrinsic_atomic_min", callee) ||
+ !strcmp("__intrinsic_atomic_max", callee) ||
+ !strcmp("__intrinsic_atomic_and", callee) ||
+ !strcmp("__intrinsic_atomic_or", callee) ||
+ !strcmp("__intrinsic_atomic_xor", callee) ||
+ !strcmp("__intrinsic_atomic_exchange", callee) ||
+ !strcmp("__intrinsic_atomic_comp_swap", callee)) {
return lower_ssbo_atomic_intrinsic(ir);
}
diff --git a/src/glsl/lower_variable_index_to_cond_assign.cpp b/src/glsl/lower_variable_index_to_cond_assign.cpp
index 1ab3afecc7e..a1ba9345e32 100644
--- a/src/glsl/lower_variable_index_to_cond_assign.cpp
+++ b/src/glsl/lower_variable_index_to_cond_assign.cpp
@@ -378,6 +378,9 @@ public:
case ir_var_shader_storage:
return this->lower_uniforms;
+ case ir_var_shader_shared:
+ return false;
+
case ir_var_function_in:
case ir_var_const_in:
return this->lower_temps;
diff --git a/src/glsl/nir/builtin_type_macros.h b/src/glsl/nir/builtin_type_macros.h
index 8e16ae45489..7bd2e4e6558 100644
--- a/src/glsl/nir/builtin_type_macros.h
+++ b/src/glsl/nir/builtin_type_macros.h
@@ -28,8 +28,6 @@
* language version or extension might provide them.
*/
-#include "glsl_types.h"
-
DECL_TYPE(error, GL_INVALID_ENUM, GLSL_TYPE_ERROR, 0, 0)
DECL_TYPE(void, GL_INVALID_ENUM, GLSL_TYPE_VOID, 0, 0)
diff --git a/src/glsl/nir/glsl_to_nir.cpp b/src/glsl/nir/glsl_to_nir.cpp
index a26300d1d26..9a25f2fc905 100644
--- a/src/glsl/nir/glsl_to_nir.cpp
+++ b/src/glsl/nir/glsl_to_nir.cpp
@@ -691,15 +691,15 @@ nir_visitor::visit(ir_call *ir)
op = nir_intrinsic_store_ssbo;
} else if (strcmp(ir->callee_name(), "__intrinsic_load_ssbo") == 0) {
op = nir_intrinsic_load_ssbo;
- } else if (strcmp(ir->callee_name(), "__intrinsic_ssbo_atomic_add_internal") == 0) {
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_add_ssbo") == 0) {
op = nir_intrinsic_ssbo_atomic_add;
- } else if (strcmp(ir->callee_name(), "__intrinsic_ssbo_atomic_and_internal") == 0) {
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_and_ssbo") == 0) {
op = nir_intrinsic_ssbo_atomic_and;
- } else if (strcmp(ir->callee_name(), "__intrinsic_ssbo_atomic_or_internal") == 0) {
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_or_ssbo") == 0) {
op = nir_intrinsic_ssbo_atomic_or;
- } else if (strcmp(ir->callee_name(), "__intrinsic_ssbo_atomic_xor_internal") == 0) {
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_xor_ssbo") == 0) {
op = nir_intrinsic_ssbo_atomic_xor;
- } else if (strcmp(ir->callee_name(), "__intrinsic_ssbo_atomic_min_internal") == 0) {
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_min_ssbo") == 0) {
assert(ir->return_deref);
if (ir->return_deref->type == glsl_type::int_type)
op = nir_intrinsic_ssbo_atomic_imin;
@@ -707,7 +707,7 @@ nir_visitor::visit(ir_call *ir)
op = nir_intrinsic_ssbo_atomic_umin;
else
unreachable("Invalid type");
- } else if (strcmp(ir->callee_name(), "__intrinsic_ssbo_atomic_max_internal") == 0) {
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_max_ssbo") == 0) {
assert(ir->return_deref);
if (ir->return_deref->type == glsl_type::int_type)
op = nir_intrinsic_ssbo_atomic_imax;
@@ -715,9 +715,9 @@ nir_visitor::visit(ir_call *ir)
op = nir_intrinsic_ssbo_atomic_umax;
else
unreachable("Invalid type");
- } else if (strcmp(ir->callee_name(), "__intrinsic_ssbo_atomic_exchange_internal") == 0) {
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_exchange_ssbo") == 0) {
op = nir_intrinsic_ssbo_atomic_exchange;
- } else if (strcmp(ir->callee_name(), "__intrinsic_ssbo_atomic_comp_swap_internal") == 0) {
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_comp_swap_ssbo") == 0) {
op = nir_intrinsic_ssbo_atomic_comp_swap;
} else if (strcmp(ir->callee_name(), "__intrinsic_shader_clock") == 0) {
op = nir_intrinsic_shader_clock;
@@ -731,6 +731,38 @@ nir_visitor::visit(ir_call *ir)
op = nir_intrinsic_memory_barrier_image;
} else if (strcmp(ir->callee_name(), "__intrinsic_memory_barrier_shared") == 0) {
op = nir_intrinsic_memory_barrier_shared;
+ } else if (strcmp(ir->callee_name(), "__intrinsic_load_shared") == 0) {
+ op = nir_intrinsic_load_shared;
+ } else if (strcmp(ir->callee_name(), "__intrinsic_store_shared") == 0) {
+ op = nir_intrinsic_store_shared;
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_add_shared") == 0) {
+ op = nir_intrinsic_shared_atomic_add;
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_and_shared") == 0) {
+ op = nir_intrinsic_shared_atomic_and;
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_or_shared") == 0) {
+ op = nir_intrinsic_shared_atomic_or;
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_xor_shared") == 0) {
+ op = nir_intrinsic_shared_atomic_xor;
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_min_shared") == 0) {
+ assert(ir->return_deref);
+ if (ir->return_deref->type == glsl_type::int_type)
+ op = nir_intrinsic_shared_atomic_imin;
+ else if (ir->return_deref->type == glsl_type::uint_type)
+ op = nir_intrinsic_shared_atomic_umin;
+ else
+ unreachable("Invalid type");
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_max_shared") == 0) {
+ assert(ir->return_deref);
+ if (ir->return_deref->type == glsl_type::int_type)
+ op = nir_intrinsic_shared_atomic_imax;
+ else if (ir->return_deref->type == glsl_type::uint_type)
+ op = nir_intrinsic_shared_atomic_umax;
+ else
+ unreachable("Invalid type");
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_exchange_shared") == 0) {
+ op = nir_intrinsic_shared_atomic_exchange;
+ } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_comp_swap_shared") == 0) {
+ op = nir_intrinsic_shared_atomic_comp_swap;
} else {
unreachable("not reached");
}
@@ -857,24 +889,12 @@ nir_visitor::visit(ir_call *ir)
ir_constant *write_mask = ((ir_instruction *)param)->as_constant();
assert(write_mask);
- /* Check if we need the indirect version */
- ir_constant *const_offset = offset->as_constant();
- if (!const_offset) {
- op = nir_intrinsic_store_ssbo_indirect;
- ralloc_free(instr);
- instr = nir_intrinsic_instr_create(shader, op);
- instr->src[2] = nir_src_for_ssa(evaluate_rvalue(offset));
- instr->const_index[0] = 0;
- } else {
- instr->const_index[0] = const_offset->value.u[0];
- }
-
- instr->const_index[1] = write_mask->value.u[0];
-
instr->src[0] = nir_src_for_ssa(evaluate_rvalue(val));
+ instr->src[1] = nir_src_for_ssa(evaluate_rvalue(block));
+ instr->src[2] = nir_src_for_ssa(evaluate_rvalue(offset));
+ instr->const_index[0] = write_mask->value.u[0];
instr->num_components = val->type->vector_elements;
- instr->src[1] = nir_src_for_ssa(evaluate_rvalue(block));
nir_builder_instr_insert(&b, &instr->instr);
break;
}
@@ -885,20 +905,8 @@ nir_visitor::visit(ir_call *ir)
param = param->get_next();
ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();
- /* Check if we need the indirect version */
- ir_constant *const_offset = offset->as_constant();
- if (!const_offset) {
- op = nir_intrinsic_load_ssbo_indirect;
- ralloc_free(instr);
- instr = nir_intrinsic_instr_create(shader, op);
- instr->src[1] = nir_src_for_ssa(evaluate_rvalue(offset));
- instr->const_index[0] = 0;
- dest = &instr->dest;
- } else {
- instr->const_index[0] = const_offset->value.u[0];
- }
-
instr->src[0] = nir_src_for_ssa(evaluate_rvalue(block));
+ instr->src[1] = nir_src_for_ssa(evaluate_rvalue(offset));
const glsl_type *type = ir->return_deref->var->type;
instr->num_components = type->vector_elements;
@@ -978,6 +986,84 @@ nir_visitor::visit(ir_call *ir)
nir_builder_instr_insert(&b, &instr->instr);
break;
}
+ case nir_intrinsic_load_shared: {
+ exec_node *param = ir->actual_parameters.get_head();
+ ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();
+
+ instr->const_index[0] = 0;
+ instr->src[0] = nir_src_for_ssa(evaluate_rvalue(offset));
+
+ const glsl_type *type = ir->return_deref->var->type;
+ instr->num_components = type->vector_elements;
+
+ /* Setup destination register */
+ nir_ssa_dest_init(&instr->instr, &instr->dest,
+ type->vector_elements, NULL);
+
+ nir_builder_instr_insert(&b, &instr->instr);
+ break;
+ }
+ case nir_intrinsic_store_shared: {
+ exec_node *param = ir->actual_parameters.get_head();
+ ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();
+
+ param = param->get_next();
+ ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
+
+ param = param->get_next();
+ ir_constant *write_mask = ((ir_instruction *)param)->as_constant();
+ assert(write_mask);
+
+ instr->const_index[0] = 0;
+ instr->src[1] = nir_src_for_ssa(evaluate_rvalue(offset));
+
+ instr->const_index[1] = write_mask->value.u[0];
+
+ instr->src[0] = nir_src_for_ssa(evaluate_rvalue(val));
+ instr->num_components = val->type->vector_elements;
+
+ nir_builder_instr_insert(&b, &instr->instr);
+ break;
+ }
+ case nir_intrinsic_shared_atomic_add:
+ case nir_intrinsic_shared_atomic_imin:
+ case nir_intrinsic_shared_atomic_umin:
+ case nir_intrinsic_shared_atomic_imax:
+ case nir_intrinsic_shared_atomic_umax:
+ case nir_intrinsic_shared_atomic_and:
+ case nir_intrinsic_shared_atomic_or:
+ case nir_intrinsic_shared_atomic_xor:
+ case nir_intrinsic_shared_atomic_exchange:
+ case nir_intrinsic_shared_atomic_comp_swap: {
+ int param_count = ir->actual_parameters.length();
+ assert(param_count == 2 || param_count == 3);
+
+ /* Offset */
+ exec_node *param = ir->actual_parameters.get_head();
+ ir_instruction *inst = (ir_instruction *) param;
+ instr->src[0] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue()));
+
+ /* data1 parameter (this is always present) */
+ param = param->get_next();
+ inst = (ir_instruction *) param;
+ instr->src[1] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue()));
+
+ /* data2 parameter (only with atomic_comp_swap) */
+ if (param_count == 3) {
+ assert(op == nir_intrinsic_shared_atomic_comp_swap);
+ param = param->get_next();
+ inst = (ir_instruction *) param;
+ instr->src[2] =
+ nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue()));
+ }
+
+ /* Atomic result */
+ assert(ir->return_deref);
+ nir_ssa_dest_init(&instr->instr, &instr->dest,
+ ir->return_deref->type->vector_elements, NULL);
+ nir_builder_instr_insert(&b, &instr->instr);
+ break;
+ }
default:
unreachable("not reached");
}
@@ -1178,21 +1264,11 @@ nir_visitor::visit(ir_expression *ir)
/* Some special cases */
switch (ir->operation) {
case ir_binop_ubo_load: {
- ir_constant *const_index = ir->operands[1]->as_constant();
-
- nir_intrinsic_op op;
- if (const_index) {
- op = nir_intrinsic_load_ubo;
- } else {
- op = nir_intrinsic_load_ubo_indirect;
- }
-
- nir_intrinsic_instr *load = nir_intrinsic_instr_create(this->shader, op);
+ nir_intrinsic_instr *load =
+ nir_intrinsic_instr_create(this->shader, nir_intrinsic_load_ubo);
load->num_components = ir->type->vector_elements;
- load->const_index[0] = const_index ? const_index->value.u[0] : 0; /* base offset */
load->src[0] = nir_src_for_ssa(evaluate_rvalue(ir->operands[0]));
- if (!const_index)
- load->src[1] = nir_src_for_ssa(evaluate_rvalue(ir->operands[1]));
+ load->src[1] = nir_src_for_ssa(evaluate_rvalue(ir->operands[1]));
add_instr(&load->instr, ir->type->vector_elements);
/*
diff --git a/src/glsl/nir/glsl_types.cpp b/src/glsl/nir/glsl_types.cpp
index 64b5c0cb106..bc8677ba6fc 100644
--- a/src/glsl/nir/glsl_types.cpp
+++ b/src/glsl/nir/glsl_types.cpp
@@ -22,7 +22,7 @@
*/
#include
-#include "main/core.h" /* for Elements, MAX2 */
+#include "main/macros.h"
#include "glsl_parser_extras.h"
#include "glsl_types.h"
#include "util/hash_table.h"
diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
index 79df6d3df94..94bb76034a2 100644
--- a/src/glsl/nir/nir.c
+++ b/src/glsl/nir/nir.c
@@ -1382,13 +1382,13 @@ static inline bool
foreach_if(nir_if *if_stmt, nir_foreach_block_cb cb, bool reverse, void *state)
{
if (reverse) {
- foreach_list_typed_safe_reverse(nir_cf_node, node, node,
+ foreach_list_typed_reverse_safe(nir_cf_node, node, node,
&if_stmt->else_list) {
if (!foreach_cf_node(node, cb, reverse, state))
return false;
}
- foreach_list_typed_safe_reverse(nir_cf_node, node, node,
+ foreach_list_typed_reverse_safe(nir_cf_node, node, node,
&if_stmt->then_list) {
if (!foreach_cf_node(node, cb, reverse, state))
return false;
@@ -1412,7 +1412,7 @@ static inline bool
foreach_loop(nir_loop *loop, nir_foreach_block_cb cb, bool reverse, void *state)
{
if (reverse) {
- foreach_list_typed_safe_reverse(nir_cf_node, node, node, &loop->body) {
+ foreach_list_typed_reverse_safe(nir_cf_node, node, node, &loop->body) {
if (!foreach_cf_node(node, cb, reverse, state))
return false;
}
@@ -1472,7 +1472,7 @@ nir_foreach_block_reverse(nir_function_impl *impl, nir_foreach_block_cb cb,
if (!cb(impl->end_block, state))
return false;
- foreach_list_typed_safe_reverse(nir_cf_node, node, node, &impl->body) {
+ foreach_list_typed_reverse_safe(nir_cf_node, node, node, &impl->body) {
if (!foreach_cf_node(node, cb, true, state))
return false;
}
diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
index b7374e17407..021c4280557 100644
--- a/src/glsl/nir/nir.h
+++ b/src/glsl/nir/nir.h
@@ -1309,8 +1309,8 @@ nir_block_last_instr(nir_block *block)
foreach_list_typed_reverse(nir_instr, instr, node, &(block)->instr_list)
#define nir_foreach_instr_safe(block, instr) \
foreach_list_typed_safe(nir_instr, instr, node, &(block)->instr_list)
-#define nir_foreach_instr_safe_reverse(block, instr) \
- foreach_list_typed_safe_reverse(nir_instr, instr, node, &(block)->instr_list)
+#define nir_foreach_instr_reverse_safe(block, instr) \
+ foreach_list_typed_reverse_safe(nir_instr, instr, node, &(block)->instr_list)
typedef struct nir_if {
nir_cf_node cf_node;
@@ -2018,7 +2018,7 @@ void nir_assign_var_locations(struct exec_list *var_list,
void nir_lower_io(nir_shader *shader,
nir_variable_mode mode,
int (*type_size)(const struct glsl_type *));
-nir_src *nir_get_io_indirect_src(nir_intrinsic_instr *instr);
+nir_src *nir_get_io_offset_src(nir_intrinsic_instr *instr);
nir_src *nir_get_io_vertex_index_src(nir_intrinsic_instr *instr);
void nir_lower_vars_to_ssa(nir_shader *shader);
diff --git a/src/glsl/nir/nir_constant_expressions.py b/src/glsl/nir/nir_constant_expressions.py
index b16ef503c92..32784f6398d 100644
--- a/src/glsl/nir/nir_constant_expressions.py
+++ b/src/glsl/nir/nir_constant_expressions.py
@@ -32,14 +32,6 @@ template = """\
#include "util/half_float.h"
#include "nir_constant_expressions.h"
-#if defined(__SUNPRO_CC)
-#include
-static int isnormal(double x)
-{
- return fpclass(x) == FP_NORMAL;
-}
-#endif
-
/**
* Evaluate one component of packSnorm4x8.
*/
diff --git a/src/glsl/nir/nir_intrinsics.h b/src/glsl/nir/nir_intrinsics.h
index de30db61eea..5086e297e8e 100644
--- a/src/glsl/nir/nir_intrinsics.h
+++ b/src/glsl/nir/nir_intrinsics.h
@@ -222,6 +222,33 @@ INTRINSIC(ssbo_atomic_xor, 3, ARR(1, 1, 1), true, 1, 0, 0, 0)
INTRINSIC(ssbo_atomic_exchange, 3, ARR(1, 1, 1), true, 1, 0, 0, 0)
INTRINSIC(ssbo_atomic_comp_swap, 4, ARR(1, 1, 1, 1), true, 1, 0, 0, 0)
+/*
+ * CS shared variable atomic intrinsics
+ *
+ * All of the shared variable atomic memory operations read a value from
+ * memory, compute a new value using one of the operations below, write the
+ * new value to memory, and return the original value read.
+ *
+ * All operations take 2 sources except CompSwap that takes 3. These
+ * sources represent:
+ *
+ * 0: The offset into the shared variable storage region that the atomic
+ * operation will operate on.
+ * 1: The data parameter to the atomic function (i.e. the value to add
+ * in shared_atomic_add, etc).
+ * 2: For CompSwap only: the second data parameter.
+ */
+INTRINSIC(shared_atomic_add, 2, ARR(1, 1), true, 1, 0, 0, 0)
+INTRINSIC(shared_atomic_imin, 2, ARR(1, 1), true, 1, 0, 0, 0)
+INTRINSIC(shared_atomic_umin, 2, ARR(1, 1), true, 1, 0, 0, 0)
+INTRINSIC(shared_atomic_imax, 2, ARR(1, 1), true, 1, 0, 0, 0)
+INTRINSIC(shared_atomic_umax, 2, ARR(1, 1), true, 1, 0, 0, 0)
+INTRINSIC(shared_atomic_and, 2, ARR(1, 1), true, 1, 0, 0, 0)
+INTRINSIC(shared_atomic_or, 2, ARR(1, 1), true, 1, 0, 0, 0)
+INTRINSIC(shared_atomic_xor, 2, ARR(1, 1), true, 1, 0, 0, 0)
+INTRINSIC(shared_atomic_exchange, 2, ARR(1, 1), true, 1, 0, 0, 0)
+INTRINSIC(shared_atomic_comp_swap, 3, ARR(1, 1, 1), true, 1, 0, 0, 0)
+
#define SYSTEM_VALUE(name, components, num_indices) \
INTRINSIC(load_##name, 0, ARR(), true, components, 0, num_indices, \
NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
@@ -247,56 +274,62 @@ SYSTEM_VALUE(num_work_groups, 3, 0)
SYSTEM_VALUE(helper_invocation, 1, 0)
/*
- * The format of the indices depends on the type of the load. For uniforms,
- * the first index is the base address and the second index is an offset that
- * should be added to the base address. (This way you can determine in the
- * back-end which variable is being accessed even in an array.) For inputs,
- * the one and only index corresponds to the attribute slot. UBO loads
- * have two indices the first of which is the descriptor set and the second
- * is the base address to load from.
+ * Load operations pull data from some piece of GPU memory. All load
+ * operations operate in terms of offsets into some piece of theoretical
+ * memory. Loads from externally visible memory (UBO and SSBO) simply take a
+ * byte offset as a source. Loads from opaque memory (uniforms, inputs, etc.)
+ * take a base+offset pair where the base (const_index[0]) gives the location
+ * of the start of the variable being loaded and and the offset source is a
+ * offset into that variable.
*
- * UBO loads have a (possibly constant) source which is the UBO buffer index.
- * For each type of load, the _indirect variant has one additional source
- * (the second in the case of UBO's) that is the is an indirect to be added to
- * the constant address or base offset to compute the final offset.
+ * Some load operations such as UBO/SSBO load and per_vertex loads take an
+ * additional source to specify which UBO/SSBO/vertex to load from.
*
- * For vector backends, the address is in terms of one vec4, and so each array
- * element is +4 scalar components from the previous array element. For scalar
- * backends, the address is in terms of a single 4-byte float/int and arrays
- * elements begin immediately after the previous array element.
+ * The exact address type depends on the lowering pass that generates the
+ * load/store intrinsics. Typically, this is vec4 units for things such as
+ * varying slots and float units for fragment shader inputs. UBO and SSBO
+ * offsets are always in bytes.
*/
-#define LOAD(name, extra_srcs, indices, flags) \
- INTRINSIC(load_##name, extra_srcs, ARR(1), true, 0, 0, indices, flags) \
- INTRINSIC(load_##name##_indirect, extra_srcs + 1, ARR(1, 1), \
- true, 0, 0, indices, flags)
+#define LOAD(name, srcs, indices, flags) \
+ INTRINSIC(load_##name, srcs, ARR(1, 1, 1, 1), true, 0, 0, indices, flags)
-LOAD(uniform, 0, 2, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
-LOAD(ubo, 1, 2, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
-LOAD(input, 0, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
-LOAD(per_vertex_input, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
-LOAD(ssbo, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE)
-LOAD(output, 0, 1, NIR_INTRINSIC_CAN_ELIMINATE)
-LOAD(per_vertex_output, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE)
-LOAD(push_constant, 0, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+/* src[] = { offset }. const_index[] = { base } */
+LOAD(uniform, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+/* src[] = { buffer_index, offset }. No const_index */
+LOAD(ubo, 2, 0, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+/* src[] = { offset }. const_index[] = { base } */
+LOAD(input, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+/* src[] = { vertex, offset }. const_index[] = { base } */
+LOAD(per_vertex_input, 2, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+/* src[] = { buffer_index, offset }. No const_index */
+LOAD(ssbo, 2, 0, NIR_INTRINSIC_CAN_ELIMINATE)
+/* src[] = { offset }. const_index[] = { base } */
+LOAD(output, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE)
+/* src[] = { vertex, offset }. const_index[] = { base } */
+LOAD(per_vertex_output, 2, 1, NIR_INTRINSIC_CAN_ELIMINATE)
+/* src[] = { offset }. const_index[] = { base } */
+LOAD(shared, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE)
+/* src[] = { offset }. const_index[] = { base, size } */
+LOAD(push_constant, 1, 2, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
/*
- * Stores work the same way as loads, except now the first register input is
- * the value or array to store and the optional second input is the indirect
- * offset. SSBO stores are similar, but they accept an extra source for the
- * block index and an extra index with the writemask to use.
+ * Stores work the same way as loads, except now the first source is the value
+ * to store and the second (and possibly third) source specify where to store
+ * the value. SSBO and shared memory stores also have a write mask as
+ * const_index[0].
*/
-#define STORE(name, extra_srcs, extra_srcs_size, extra_indices, flags) \
- INTRINSIC(store_##name, 1 + extra_srcs, \
- ARR(0, extra_srcs_size, extra_srcs_size, extra_srcs_size), \
- false, 0, 0, 1 + extra_indices, flags) \
- INTRINSIC(store_##name##_indirect, 2 + extra_srcs, \
- ARR(0, 1, extra_srcs_size, extra_srcs_size), \
- false, 0, 0, 1 + extra_indices, flags)
+#define STORE(name, srcs, indices, flags) \
+ INTRINSIC(store_##name, srcs, ARR(0, 1, 1, 1), false, 0, 0, indices, flags)
-STORE(output, 0, 0, 0, 0)
-STORE(per_vertex_output, 1, 1, 0, 0)
-STORE(ssbo, 1, 1, 1, 0)
+/* src[] = { value, offset }. const_index[] = { base } */
+STORE(output, 2, 1, 0)
+/* src[] = { value, vertex, offset }. const_index[] = { base } */
+STORE(per_vertex_output, 3, 1, 0)
+/* src[] = { value, block_index, offset }. const_index[] = { write_mask } */
+STORE(ssbo, 3, 1, 0)
+/* src[] = { value, offset }. const_index[] = { base, write_mask } */
+STORE(shared, 2, 1, 0)
-LAST_INTRINSIC(store_ssbo_indirect)
+LAST_INTRINSIC(store_shared)
diff --git a/src/glsl/nir/nir_lower_clip.c b/src/glsl/nir/nir_lower_clip.c
index c58c7785b3f..e2a2bb689a8 100644
--- a/src/glsl/nir/nir_lower_clip.c
+++ b/src/glsl/nir/nir_lower_clip.c
@@ -74,6 +74,7 @@ store_clipdist_output(nir_builder *b, nir_variable *out, nir_ssa_def **val)
store->const_index[0] = out->data.driver_location;
store->src[0].ssa = nir_vec4(b, val[0], val[1], val[2], val[3]);
store->src[0].is_ssa = true;
+ store->src[1] = nir_src_for_ssa(nir_imm_int(b, 0));
nir_builder_instr_insert(b, &store->instr);
}
@@ -85,6 +86,7 @@ load_clipdist_input(nir_builder *b, nir_variable *in, nir_ssa_def **val)
load = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_input);
load->num_components = 4;
load->const_index[0] = in->data.driver_location;
+ load->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
nir_builder_instr_insert(b, &load->instr);
@@ -112,6 +114,7 @@ find_output_in_block(nir_block *block, void *void_state)
intr->const_index[0] == state->drvloc) {
assert(state->def == NULL);
assert(intr->src[0].is_ssa);
+ assert(nir_src_as_const_value(intr->src[1]));
state->def = intr->src[0].ssa;
#if !defined(DEBUG)
diff --git a/src/glsl/nir/nir_lower_io.c b/src/glsl/nir/nir_lower_io.c
index 5683e69d865..ec6d09d5b6d 100644
--- a/src/glsl/nir/nir_lower_io.c
+++ b/src/glsl/nir/nir_lower_io.c
@@ -86,18 +86,11 @@ is_per_vertex_output(struct lower_io_state *state, nir_variable *var)
stage == MESA_SHADER_TESS_CTRL;
}
-static unsigned
-get_io_offset(nir_deref_var *deref, nir_instr *instr,
+static nir_ssa_def *
+get_io_offset(nir_builder *b, nir_deref_var *deref,
nir_ssa_def **vertex_index,
- nir_ssa_def **out_indirect,
- struct lower_io_state *state)
+ int (*type_size)(const struct glsl_type *))
{
- nir_ssa_def *indirect = NULL;
- unsigned base_offset = 0;
-
- nir_builder *b = &state->builder;
- b->cursor = nir_before_instr(instr);
-
nir_deref *tail = &deref->deref;
/* For per-vertex input arrays (i.e. geometry shader inputs), keep the
@@ -115,64 +108,57 @@ get_io_offset(nir_deref_var *deref, nir_instr *instr,
*vertex_index = vtx;
}
+ /* Just emit code and let constant-folding go to town */
+ nir_ssa_def *offset = nir_imm_int(b, 0);
+
while (tail->child != NULL) {
const struct glsl_type *parent_type = tail->type;
tail = tail->child;
if (tail->deref_type == nir_deref_type_array) {
nir_deref_array *deref_array = nir_deref_as_array(tail);
- unsigned size = state->type_size(tail->type);
+ unsigned size = type_size(tail->type);
- base_offset += size * deref_array->base_offset;
+ offset = nir_iadd(b, offset,
+ nir_imm_int(b, size * deref_array->base_offset));
if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
nir_ssa_def *mul =
nir_imul(b, nir_imm_int(b, size),
nir_ssa_for_src(b, deref_array->indirect, 1));
- indirect = indirect ? nir_iadd(b, indirect, mul) : mul;
+ offset = nir_iadd(b, offset, mul);
}
} else if (tail->deref_type == nir_deref_type_struct) {
nir_deref_struct *deref_struct = nir_deref_as_struct(tail);
+ unsigned field_offset = 0;
for (unsigned i = 0; i < deref_struct->index; i++) {
- base_offset +=
- state->type_size(glsl_get_struct_field(parent_type, i));
+ field_offset += type_size(glsl_get_struct_field(parent_type, i));
}
+ offset = nir_iadd(b, offset, nir_imm_int(b, field_offset));
}
}
- *out_indirect = indirect;
- return base_offset;
+ return offset;
}
static nir_intrinsic_op
load_op(struct lower_io_state *state,
- nir_variable_mode mode, bool per_vertex, bool has_indirect)
+ nir_variable_mode mode, bool per_vertex)
{
nir_intrinsic_op op;
switch (mode) {
case nir_var_shader_in:
- if (per_vertex) {
- op = has_indirect ? nir_intrinsic_load_per_vertex_input_indirect :
- nir_intrinsic_load_per_vertex_input;
- } else {
- op = has_indirect ? nir_intrinsic_load_input_indirect :
- nir_intrinsic_load_input;
- }
+ op = per_vertex ? nir_intrinsic_load_per_vertex_input :
+ nir_intrinsic_load_input;
break;
case nir_var_shader_out:
- if (per_vertex) {
- op = has_indirect ? nir_intrinsic_load_per_vertex_output_indirect :
- nir_intrinsic_load_per_vertex_output;
- } else {
- op = has_indirect ? nir_intrinsic_load_output_indirect :
- nir_intrinsic_load_output;
- }
+ op = per_vertex ? nir_intrinsic_load_per_vertex_output :
+ nir_intrinsic_load_output;
break;
case nir_var_uniform:
- op = has_indirect ? nir_intrinsic_load_uniform_indirect :
- nir_intrinsic_load_uniform;
+ op = nir_intrinsic_load_uniform;
break;
default:
unreachable("Unknown variable mode");
@@ -185,6 +171,8 @@ nir_lower_io_block(nir_block *block, void *void_state)
{
struct lower_io_state *state = void_state;
+ nir_builder *b = &state->builder;
+
nir_foreach_instr_safe(block, instr) {
if (instr->type != nir_instr_type_intrinsic)
continue;
@@ -205,38 +193,33 @@ nir_lower_io_block(nir_block *block, void *void_state)
mode != nir_var_uniform)
continue;
+ b->cursor = nir_before_instr(instr);
+
switch (intrin->intrinsic) {
case nir_intrinsic_load_var: {
bool per_vertex =
is_per_vertex_input(state, intrin->variables[0]->var) ||
is_per_vertex_output(state, intrin->variables[0]->var);
- nir_ssa_def *indirect;
+ nir_ssa_def *offset;
nir_ssa_def *vertex_index;
- unsigned offset = get_io_offset(intrin->variables[0], &intrin->instr,
- per_vertex ? &vertex_index : NULL,
- &indirect, state);
+ offset = get_io_offset(b, intrin->variables[0],
+ per_vertex ? &vertex_index : NULL,
+ state->type_size);
nir_intrinsic_instr *load =
nir_intrinsic_instr_create(state->mem_ctx,
- load_op(state, mode, per_vertex,
- indirect));
+ load_op(state, mode, per_vertex));
load->num_components = intrin->num_components;
- unsigned location = intrin->variables[0]->var->data.driver_location;
- if (mode == nir_var_uniform) {
- load->const_index[0] = location;
- load->const_index[1] = offset;
- } else {
- load->const_index[0] = location + offset;
- }
+ load->const_index[0] =
+ intrin->variables[0]->var->data.driver_location;
if (per_vertex)
load->src[0] = nir_src_for_ssa(vertex_index);
- if (indirect)
- load->src[per_vertex ? 1 : 0] = nir_src_for_ssa(indirect);
+ load->src[per_vertex ? 1 : 0] = nir_src_for_ssa(offset);
if (intrin->dest.is_ssa) {
nir_ssa_dest_init(&load->instr, &load->dest,
@@ -255,38 +238,33 @@ nir_lower_io_block(nir_block *block, void *void_state)
case nir_intrinsic_store_var: {
assert(mode == nir_var_shader_out);
- nir_ssa_def *indirect;
+ nir_ssa_def *offset;
nir_ssa_def *vertex_index;
bool per_vertex =
is_per_vertex_output(state, intrin->variables[0]->var);
- unsigned offset = get_io_offset(intrin->variables[0], &intrin->instr,
- per_vertex ? &vertex_index : NULL,
- &indirect, state);
- offset += intrin->variables[0]->var->data.driver_location;
+ offset = get_io_offset(b, intrin->variables[0],
+ per_vertex ? &vertex_index : NULL,
+ state->type_size);
- nir_intrinsic_op store_op;
- if (per_vertex) {
- store_op = indirect ? nir_intrinsic_store_per_vertex_output_indirect
- : nir_intrinsic_store_per_vertex_output;
- } else {
- store_op = indirect ? nir_intrinsic_store_output_indirect
- : nir_intrinsic_store_output;
- }
+ nir_intrinsic_op store_op =
+ per_vertex ? nir_intrinsic_store_per_vertex_output :
+ nir_intrinsic_store_output;
nir_intrinsic_instr *store = nir_intrinsic_instr_create(state->mem_ctx,
store_op);
store->num_components = intrin->num_components;
- store->const_index[0] = offset;
nir_src_copy(&store->src[0], &intrin->src[0], store);
+ store->const_index[0] =
+ intrin->variables[0]->var->data.driver_location;
+
if (per_vertex)
store->src[1] = nir_src_for_ssa(vertex_index);
- if (indirect)
- store->src[per_vertex ? 2 : 1] = nir_src_for_ssa(indirect);
+ store->src[per_vertex ? 2 : 1] = nir_src_for_ssa(offset);
nir_instr_insert_before(&intrin->instr, &store->instr);
nir_instr_remove(&intrin->instr);
@@ -330,21 +308,24 @@ nir_lower_io(nir_shader *shader, nir_variable_mode mode,
}
/**
- * Return the indirect source for a load/store indirect intrinsic.
+ * Return the offset soruce for a load/store intrinsic.
*/
nir_src *
-nir_get_io_indirect_src(nir_intrinsic_instr *instr)
+nir_get_io_offset_src(nir_intrinsic_instr *instr)
{
switch (instr->intrinsic) {
- case nir_intrinsic_load_input_indirect:
- case nir_intrinsic_load_output_indirect:
- case nir_intrinsic_load_uniform_indirect:
+ case nir_intrinsic_load_input:
+ case nir_intrinsic_load_output:
+ case nir_intrinsic_load_uniform:
return &instr->src[0];
- case nir_intrinsic_load_per_vertex_input_indirect:
- case nir_intrinsic_load_per_vertex_output_indirect:
- case nir_intrinsic_store_output_indirect:
+ case nir_intrinsic_load_ubo:
+ case nir_intrinsic_load_ssbo:
+ case nir_intrinsic_load_per_vertex_input:
+ case nir_intrinsic_load_per_vertex_output:
+ case nir_intrinsic_store_output:
return &instr->src[1];
- case nir_intrinsic_store_per_vertex_output_indirect:
+ case nir_intrinsic_store_ssbo:
+ case nir_intrinsic_store_per_vertex_output:
return &instr->src[2];
default:
return NULL;
@@ -360,11 +341,8 @@ nir_get_io_vertex_index_src(nir_intrinsic_instr *instr)
switch (instr->intrinsic) {
case nir_intrinsic_load_per_vertex_input:
case nir_intrinsic_load_per_vertex_output:
- case nir_intrinsic_load_per_vertex_input_indirect:
- case nir_intrinsic_load_per_vertex_output_indirect:
return &instr->src[0];
case nir_intrinsic_store_per_vertex_output:
- case nir_intrinsic_store_per_vertex_output_indirect:
return &instr->src[1];
default:
return NULL;
diff --git a/src/glsl/nir/nir_lower_phis_to_scalar.c b/src/glsl/nir/nir_lower_phis_to_scalar.c
index aa124d9e6cc..2f5927f6406 100644
--- a/src/glsl/nir/nir_lower_phis_to_scalar.c
+++ b/src/glsl/nir/nir_lower_phis_to_scalar.c
@@ -91,13 +91,9 @@ is_phi_src_scalarizable(nir_phi_src *src,
case nir_intrinsic_interp_var_at_sample:
case nir_intrinsic_interp_var_at_offset:
case nir_intrinsic_load_uniform:
- case nir_intrinsic_load_uniform_indirect:
case nir_intrinsic_load_ubo:
- case nir_intrinsic_load_ubo_indirect:
case nir_intrinsic_load_ssbo:
- case nir_intrinsic_load_ssbo_indirect:
case nir_intrinsic_load_input:
- case nir_intrinsic_load_input_indirect:
return true;
default:
break;
diff --git a/src/glsl/nir/nir_lower_samplers.c b/src/glsl/nir/nir_lower_samplers.c
index 19deafab37a..858088237e3 100644
--- a/src/glsl/nir/nir_lower_samplers.c
+++ b/src/glsl/nir/nir_lower_samplers.c
@@ -25,7 +25,6 @@
#include "nir.h"
#include "nir_builder.h"
-#include "../program.h"
#include "program/hash_table.h"
#include "ir_uniform.h"
diff --git a/src/glsl/nir/nir_lower_two_sided_color.c b/src/glsl/nir/nir_lower_two_sided_color.c
index 6995b9d6bc1..7df12e070f1 100644
--- a/src/glsl/nir/nir_lower_two_sided_color.c
+++ b/src/glsl/nir/nir_lower_two_sided_color.c
@@ -73,6 +73,7 @@ load_input(nir_builder *b, nir_variable *in)
load = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_input);
load->num_components = 4;
load->const_index[0] = in->data.driver_location;
+ load->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
nir_builder_instr_insert(b, &load->instr);
@@ -151,6 +152,7 @@ nir_lower_two_sided_color_block(nir_block *block, void *void_state)
unsigned drvloc =
state->colors[idx].front->data.driver_location;
if (intr->const_index[0] == drvloc) {
+ assert(nir_src_as_const_value(intr->src[0]));
break;
}
}
diff --git a/src/glsl/nir/nir_opt_algebraic.py b/src/glsl/nir/nir_opt_algebraic.py
index 30ede52b146..3843f21c0ee 100644
--- a/src/glsl/nir/nir_opt_algebraic.py
+++ b/src/glsl/nir/nir_opt_algebraic.py
@@ -185,8 +185,10 @@ optimizations = [
(('fsqrt', a), ('frcp', ('frsq', a)), 'options->lower_fsqrt'),
(('frcp', ('frsq', a)), ('fsqrt', a), '!options->lower_fsqrt'),
# Boolean simplifications
- (('ine', 'a@bool', 0), 'a'),
- (('ieq', 'a@bool', 0), ('inot', 'a')),
+ (('ieq', 'a@bool', True), a),
+ (('ine', 'a@bool', True), ('inot', a)),
+ (('ine', 'a@bool', False), a),
+ (('ieq', 'a@bool', False), ('inot', 'a')),
(('bcsel', a, True, False), ('ine', a, 0)),
(('bcsel', a, False, True), ('ieq', a, 0)),
(('bcsel', True, b, c), b),
diff --git a/src/glsl/nir/nir_print.c b/src/glsl/nir/nir_print.c
index 76bfc47c2a0..10f46cef1de 100644
--- a/src/glsl/nir/nir_print.c
+++ b/src/glsl/nir/nir_print.c
@@ -439,21 +439,15 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state)
switch (instr->intrinsic) {
case nir_intrinsic_load_uniform:
- case nir_intrinsic_load_uniform_indirect:
var_list = &state->shader->uniforms;
break;
case nir_intrinsic_load_input:
- case nir_intrinsic_load_input_indirect:
case nir_intrinsic_load_per_vertex_input:
- case nir_intrinsic_load_per_vertex_input_indirect:
var_list = &state->shader->inputs;
break;
case nir_intrinsic_load_output:
- case nir_intrinsic_load_output_indirect:
case nir_intrinsic_store_output:
- case nir_intrinsic_store_output_indirect:
case nir_intrinsic_store_per_vertex_output:
- case nir_intrinsic_store_per_vertex_output_indirect:
var_list = &state->shader->outputs;
break;
default:
diff --git a/src/glsl/nir/spirv_to_nir.c b/src/glsl/nir/spirv_to_nir.c
index d014f3cd811..68edea09309 100644
--- a/src/glsl/nir/spirv_to_nir.c
+++ b/src/glsl/nir/spirv_to_nir.c
@@ -1112,8 +1112,7 @@ nir_vulkan_resource_index(nir_builder *b, unsigned set, unsigned binding,
static struct vtn_ssa_value *
_vtn_block_load(struct vtn_builder *b, nir_intrinsic_op op,
unsigned set, unsigned binding, nir_variable_mode mode,
- nir_ssa_def *index, unsigned offset, nir_ssa_def *indirect,
- struct vtn_type *type)
+ nir_ssa_def *index, nir_ssa_def *offset, struct vtn_type *type)
{
struct vtn_ssa_value *val = ralloc(b, struct vtn_ssa_value);
val->type = type->type;
@@ -1121,26 +1120,20 @@ _vtn_block_load(struct vtn_builder *b, nir_intrinsic_op op,
if (glsl_type_is_vector_or_scalar(type->type)) {
nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, op);
load->num_components = glsl_get_vector_elements(type->type);
- load->const_index[0] = offset;
switch (op) {
- case nir_intrinsic_load_ubo_indirect:
- case nir_intrinsic_load_ssbo_indirect:
- load->src[1] = nir_src_for_ssa(indirect);
- /* fall through */
case nir_intrinsic_load_ubo:
case nir_intrinsic_load_ssbo: {
nir_ssa_def *res_index = nir_vulkan_resource_index(&b->nb,
set, binding,
mode, index);
load->src[0] = nir_src_for_ssa(res_index);
+ load->src[1] = nir_src_for_ssa(offset);
break;
}
case nir_intrinsic_load_push_constant:
- break; /* Nothing to do */
- case nir_intrinsic_load_push_constant_indirect:
- load->src[0] = nir_src_for_ssa(indirect);
+ load->src[0] = nir_src_for_ssa(offset);
break;
default:
@@ -1155,15 +1148,17 @@ _vtn_block_load(struct vtn_builder *b, nir_intrinsic_op op,
val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
if (glsl_type_is_struct(type->type)) {
for (unsigned i = 0; i < elems; i++) {
+ nir_ssa_def *child_offset =
+ nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, type->offsets[i]));
val->elems[i] = _vtn_block_load(b, op, set, binding, mode, index,
- offset + type->offsets[i],
- indirect, type->members[i]);
+ child_offset, type->members[i]);
}
} else {
for (unsigned i = 0; i < elems; i++) {
+ nir_ssa_def *child_offset =
+ nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, i * type->stride));
val->elems[i] = _vtn_block_load(b, op, set, binding, mode, index,
- offset + i * type->stride,
- indirect, type->array_element);
+ child_offset,type->array_element);
}
}
}
@@ -1174,8 +1169,7 @@ _vtn_block_load(struct vtn_builder *b, nir_intrinsic_op op,
static void
vtn_block_get_offset(struct vtn_builder *b, nir_deref_var *src,
struct vtn_type **type, nir_deref *src_tail,
- nir_ssa_def **index,
- unsigned *offset, nir_ssa_def **indirect)
+ nir_ssa_def **index, nir_ssa_def **offset)
{
nir_deref *deref = &src->deref;
@@ -1191,27 +1185,30 @@ vtn_block_get_offset(struct vtn_builder *b, nir_deref_var *src,
*index = nir_imm_int(&b->nb, 0);
}
- *offset = 0;
- *indirect = NULL;
+ *offset = nir_imm_int(&b->nb, 0);
while (deref != src_tail) {
deref = deref->child;
switch (deref->deref_type) {
case nir_deref_type_array: {
nir_deref_array *deref_array = nir_deref_as_array(deref);
- if (deref_array->deref_array_type == nir_deref_array_type_direct) {
- *offset += (*type)->stride * deref_array->base_offset;
- } else {
- nir_ssa_def *off = nir_imul(&b->nb, deref_array->indirect.ssa,
- nir_imm_int(&b->nb, (*type)->stride));
- *indirect = *indirect ? nir_iadd(&b->nb, *indirect, off) : off;
- }
+ nir_ssa_def *off = nir_imm_int(&b->nb, deref_array->base_offset);
+
+ if (deref_array->deref_array_type == nir_deref_array_type_indirect)
+ off = nir_iadd(&b->nb, off, deref_array->indirect.ssa);
+
+ off = nir_imul(&b->nb, off, nir_imm_int(&b->nb, (*type)->stride));
+ *offset = nir_iadd(&b->nb, *offset, off);
+
*type = (*type)->array_element;
break;
}
case nir_deref_type_struct: {
nir_deref_struct *deref_struct = nir_deref_as_struct(deref);
- *offset += (*type)->offsets[deref_struct->index];
+
+ unsigned elem_off = (*type)->offsets[deref_struct->index];
+ *offset = nir_iadd(&b->nb, *offset, nir_imm_int(&b->nb, elem_off));
+
*type = (*type)->members[deref_struct->index];
break;
}
@@ -1227,9 +1224,8 @@ vtn_block_load(struct vtn_builder *b, nir_deref_var *src,
struct vtn_type *type, nir_deref *src_tail)
{
nir_ssa_def *index;
- unsigned offset;
- nir_ssa_def *indirect;
- vtn_block_get_offset(b, src, &type, src_tail, &index, &offset, &indirect);
+ nir_ssa_def *offset;
+ vtn_block_get_offset(b, src, &type, src_tail, &index, &offset);
nir_intrinsic_op op;
if (src->var->data.mode == nir_var_uniform) {
@@ -1237,25 +1233,22 @@ vtn_block_load(struct vtn_builder *b, nir_deref_var *src,
/* UBO load */
assert(src->var->data.binding >= 0);
- op = indirect ? nir_intrinsic_load_ubo_indirect
- : nir_intrinsic_load_ubo;
+ op = nir_intrinsic_load_ubo;
} else {
/* Push constant load */
assert(src->var->data.descriptor_set == -1 &&
src->var->data.binding == -1);
- op = indirect ? nir_intrinsic_load_push_constant_indirect
- : nir_intrinsic_load_push_constant;
+ op = nir_intrinsic_load_push_constant;
}
} else {
assert(src->var->data.mode == nir_var_shader_storage);
- op = indirect ? nir_intrinsic_load_ssbo_indirect
- : nir_intrinsic_load_ssbo;
+ op = nir_intrinsic_load_ssbo;
}
return _vtn_block_load(b, op, src->var->data.descriptor_set,
src->var->data.binding, src->var->data.mode,
- index, offset, indirect, type);
+ index, offset, type);
}
/*
@@ -1319,14 +1312,13 @@ vtn_variable_load(struct vtn_builder *b, nir_deref_var *src,
static void
_vtn_block_store(struct vtn_builder *b, nir_intrinsic_op op,
struct vtn_ssa_value *src, unsigned set, unsigned binding,
- nir_variable_mode mode, nir_ssa_def *index, unsigned offset,
- nir_ssa_def *indirect, struct vtn_type *type)
+ nir_variable_mode mode, nir_ssa_def *index,
+ nir_ssa_def *offset, struct vtn_type *type)
{
assert(src->type == type->type);
if (glsl_type_is_vector_or_scalar(type->type)) {
nir_intrinsic_instr *store = nir_intrinsic_instr_create(b->shader, op);
store->num_components = glsl_get_vector_elements(type->type);
- store->const_index[0] = offset;
store->const_index[1] = (1 << store->num_components) - 1;
store->src[0] = nir_src_for_ssa(src->def);
@@ -1334,24 +1326,24 @@ _vtn_block_store(struct vtn_builder *b, nir_intrinsic_op op,
set, binding,
mode, index);
store->src[1] = nir_src_for_ssa(res_index);
-
- if (op == nir_intrinsic_store_ssbo_indirect)
- store->src[2] = nir_src_for_ssa(indirect);
+ store->src[2] = nir_src_for_ssa(offset);
nir_builder_instr_insert(&b->nb, &store->instr);
} else {
unsigned elems = glsl_get_length(type->type);
if (glsl_type_is_struct(type->type)) {
for (unsigned i = 0; i < elems; i++) {
+ nir_ssa_def *child_offset =
+ nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, type->offsets[i]));
_vtn_block_store(b, op, src->elems[i], set, binding, mode,
- index, offset + type->offsets[i], indirect,
- type->members[i]);
+ index, child_offset, type->members[i]);
}
} else {
for (unsigned i = 0; i < elems; i++) {
+ nir_ssa_def *child_offset =
+ nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, i * type->stride));
_vtn_block_store(b, op, src->elems[i], set, binding, mode,
- index, offset + i * type->stride, indirect,
- type->array_element);
+ index, child_offset, type->array_element);
}
}
}
@@ -1363,16 +1355,14 @@ vtn_block_store(struct vtn_builder *b, struct vtn_ssa_value *src,
nir_deref *dest_tail)
{
nir_ssa_def *index;
- unsigned offset;
- nir_ssa_def *indirect;
- vtn_block_get_offset(b, dest, &type, dest_tail, &index, &offset, &indirect);
+ nir_ssa_def *offset;
+ vtn_block_get_offset(b, dest, &type, dest_tail, &index, &offset);
- nir_intrinsic_op op = indirect ? nir_intrinsic_store_ssbo_indirect
- : nir_intrinsic_store_ssbo;
+ nir_intrinsic_op op = nir_intrinsic_store_ssbo;
return _vtn_block_store(b, op, src, dest->var->data.descriptor_set,
dest->var->data.binding, dest->var->data.mode,
- index, offset, indirect, type);
+ index, offset, type);
}
static nir_ssa_def * vtn_vector_insert(struct vtn_builder *b,
@@ -1545,7 +1535,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
/* We have exactly one push constant block */
assert(b->shader->num_uniforms == 0);
- b->shader->num_uniforms = vtn_type_block_size(type);
+ b->shader->num_uniforms = vtn_type_block_size(type) * 4;
break;
case SpvStorageClassInput:
var->data.mode = nir_var_shader_in;
diff --git a/src/glsl/opt_array_splitting.cpp b/src/glsl/opt_array_splitting.cpp
index 9e73f3c44bb..89ce76bed2b 100644
--- a/src/glsl/opt_array_splitting.cpp
+++ b/src/glsl/opt_array_splitting.cpp
@@ -188,6 +188,10 @@ ir_array_reference_visitor::visit_enter(ir_dereference_array *ir)
if (entry && !ir->array_index->as_constant())
entry->split = false;
+ /* If the index is also array dereference, visit index. */
+ if (ir->array_index->as_dereference_array())
+ visit_enter(ir->array_index->as_dereference_array());
+
return visit_continue_with_parent;
}
diff --git a/src/glsl/opt_constant_propagation.cpp b/src/glsl/opt_constant_propagation.cpp
index 184aaa1c297..fb24a4fad04 100644
--- a/src/glsl/opt_constant_propagation.cpp
+++ b/src/glsl/opt_constant_propagation.cpp
@@ -500,7 +500,8 @@ ir_constant_propagation_visitor::add_constant(ir_assignment *ir)
* the variable value isn't modified between this assignment and the next
* instruction where its value is read.
*/
- if (deref->var->data.mode == ir_var_shader_storage)
+ if (deref->var->data.mode == ir_var_shader_storage ||
+ deref->var->data.mode == ir_var_shader_shared)
return;
entry = new(this->mem_ctx) acp_entry(deref->var, ir->write_mask, constant);
diff --git a/src/glsl/opt_constant_variable.cpp b/src/glsl/opt_constant_variable.cpp
index cdfbc340243..56f6a819e1e 100644
--- a/src/glsl/opt_constant_variable.cpp
+++ b/src/glsl/opt_constant_variable.cpp
@@ -120,7 +120,8 @@ ir_constant_variable_visitor::visit_enter(ir_assignment *ir)
* and we can't be sure that this variable won't be written by another
* thread.
*/
- if (var->data.mode == ir_var_shader_storage)
+ if (var->data.mode == ir_var_shader_storage ||
+ var->data.mode == ir_var_shader_shared)
return visit_continue;
constval = ir->rhs->constant_expression_value();
diff --git a/src/glsl/opt_copy_propagation.cpp b/src/glsl/opt_copy_propagation.cpp
index f20699563fd..5d4cb4fe613 100644
--- a/src/glsl/opt_copy_propagation.cpp
+++ b/src/glsl/opt_copy_propagation.cpp
@@ -330,7 +330,8 @@ ir_copy_propagation_visitor::add_copy(ir_assignment *ir)
*/
ir->condition = new(ralloc_parent(ir)) ir_constant(false);
this->progress = true;
- } else if (lhs_var->data.mode != ir_var_shader_storage) {
+ } else if (lhs_var->data.mode != ir_var_shader_storage &&
+ lhs_var->data.mode != ir_var_shader_shared) {
entry = new(this->acp) acp_entry(lhs_var, rhs_var);
this->acp->push_tail(entry);
}
diff --git a/src/glsl/opt_dead_builtin_varyings.cpp b/src/glsl/opt_dead_builtin_varyings.cpp
index 68b70eedf92..53871130e12 100644
--- a/src/glsl/opt_dead_builtin_varyings.cpp
+++ b/src/glsl/opt_dead_builtin_varyings.cpp
@@ -85,7 +85,7 @@ public:
{
ir_variable *var = ir->variable_referenced();
- if (!var || var->data.mode != this->mode)
+ if (!var || var->data.mode != this->mode || !var->type->is_array())
return visit_continue;
if (this->find_frag_outputs && var->data.location == FRAG_RESULT_DATA0) {
diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp
index c5be166e75a..c2ce0b94ece 100644
--- a/src/glsl/opt_dead_code.cpp
+++ b/src/glsl/opt_dead_code.cpp
@@ -75,6 +75,20 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
|| !entry->declaration)
continue;
+ /* Section 7.4.1 (Shader Interface Matching) of the OpenGL 4.5
+ * (Core Profile) spec says:
+ *
+ * "With separable program objects, interfaces between shader
+ * stages may involve the outputs from one program object and the
+ * inputs from a second program object. For such interfaces, it is
+ * not possible to detect mismatches at link time, because the
+ * programs are linked separately. When each such program is
+ * linked, all inputs or outputs interfacing with another program
+ * stage are treated as active."
+ */
+ if (entry->var->data.always_active_io)
+ continue;
+
if (!entry->assign_list.is_empty()) {
/* Remove all the dead assignments to the variable we found.
* Don't do so if it's a shader or function output, though.
diff --git a/src/glsl/standalone_scaffolding.cpp b/src/glsl/standalone_scaffolding.cpp
index 7d59c787aed..84266b0cb58 100644
--- a/src/glsl/standalone_scaffolding.cpp
+++ b/src/glsl/standalone_scaffolding.cpp
@@ -69,7 +69,7 @@ _mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
void
_mesa_shader_debug(struct gl_context *, GLenum, GLuint *,
- const char *, int)
+ const char *)
{
}
diff --git a/src/glsl/standalone_scaffolding.h b/src/glsl/standalone_scaffolding.h
index a9ca5e4e3d3..f853a187bf4 100644
--- a/src/glsl/standalone_scaffolding.h
+++ b/src/glsl/standalone_scaffolding.h
@@ -52,7 +52,7 @@ _mesa_clear_shader_program_data(struct gl_shader_program *);
extern "C" void
_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id,
- const char *msg, int len);
+ const char *msg);
static inline gl_shader_stage
_mesa_shader_enum_to_shader_stage(GLenum v)
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 27ea9521e50..651915aed71 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -1289,7 +1289,7 @@ dri2CreateScreen(int screen, struct glx_display * priv)
__glXEnableDirectExtension(&psc->base, "GLX_OML_sync_control");
}
- /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
+ /* DRI2 supports SubBuffer through DRI2CopyRegion, so it's always
* available.*/
psp->copySubBuffer = dri2CopySubBuffer;
__glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
diff --git a/src/mapi/glapi/gen/AMD_performance_monitor.xml b/src/mapi/glapi/gen/AMD_performance_monitor.xml
index 41b52083883..b29dc5d9036 100644
--- a/src/mapi/glapi/gen/AMD_performance_monitor.xml
+++ b/src/mapi/glapi/gen/AMD_performance_monitor.xml
@@ -78,7 +78,7 @@
-
+
diff --git a/src/mapi/glapi/gen/ARB_direct_state_access.xml b/src/mapi/glapi/gen/ARB_direct_state_access.xml
index 4c8f73ede7d..293d7164680 100644
--- a/src/mapi/glapi/gen/ARB_direct_state_access.xml
+++ b/src/mapi/glapi/gen/ARB_direct_state_access.xml
@@ -5,7 +5,6 @@
-
diff --git a/src/mapi/glapi/gen/ARB_geometry_shader4.xml b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
deleted file mode 100644
index 280e7a07599..00000000000
--- a/src/mapi/glapi/gen/ARB_geometry_shader4.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/mapi/glapi/gen/EXT_framebuffer_object.xml b/src/mapi/glapi/gen/EXT_framebuffer_object.xml
index 9ae02915232..310e8ee9569 100644
--- a/src/mapi/glapi/gen/EXT_framebuffer_object.xml
+++ b/src/mapi/glapi/gen/EXT_framebuffer_object.xml
@@ -8,7 +8,6 @@
-
@@ -52,13 +51,11 @@
-
-
diff --git a/src/mapi/glapi/gen/GL3x.xml b/src/mapi/glapi/gen/GL3x.xml
index 7919d657774..7241c667873 100644
--- a/src/mapi/glapi/gen/GL3x.xml
+++ b/src/mapi/glapi/gen/GL3x.xml
@@ -21,8 +21,6 @@
-
-
diff --git a/src/mapi/glapi/gen/KHR_debug.xml b/src/mapi/glapi/gen/KHR_debug.xml
index e4a5a5b01e6..50daba3d49c 100644
--- a/src/mapi/glapi/gen/KHR_debug.xml
+++ b/src/mapi/glapi/gen/KHR_debug.xml
@@ -146,7 +146,7 @@
-
+
@@ -155,7 +155,7 @@
-
+
@@ -164,12 +164,12 @@
-
+
-
+
@@ -181,23 +181,28 @@
-
+
+
+
+
+
+
-
+
-
+
-
+
@@ -205,13 +210,13 @@
-
+
-
+
diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am
index a5a26a652ee..2da8f7ddd9d 100644
--- a/src/mapi/glapi/gen/Makefile.am
+++ b/src/mapi/glapi/gen/Makefile.am
@@ -133,7 +133,6 @@ API_XML = \
ARB_ES3_compatibility.xml \
ARB_framebuffer_no_attachments.xml \
ARB_framebuffer_object.xml \
- ARB_geometry_shader4.xml \
ARB_get_program_binary.xml \
ARB_get_texture_sub_image.xml \
ARB_gpu_shader_fp64.xml \
@@ -271,8 +270,8 @@ $(MESA_GLAPI_DIR)/glapi_sparc.S: gl_SPARC_asm.py $(COMMON)
######################################################################
-$(MESA_DIR)/main/enums.c: gl_enums.py $(COMMON)
- $(PYTHON_GEN) $(srcdir)/gl_enums.py -f $(srcdir)/gl_and_es_API.xml > $@
+$(MESA_DIR)/main/enums.c: gl_enums.py $(srcdir)/../registry/gl.xml
+ $(PYTHON_GEN) $(srcdir)/gl_enums.py -f $(srcdir)/../registry/gl.xml > $@
$(MESA_DIR)/main/api_exec.c: gl_genexec.py apiexec.py $(COMMON)
$(PYTHON_GEN) $(srcdir)/gl_genexec.py -f $(srcdir)/gl_and_es_API.xml > $@
diff --git a/src/mapi/glapi/gen/SConscript b/src/mapi/glapi/gen/SConscript
index b9cdbbf363f..ff0df745c2c 100644
--- a/src/mapi/glapi/gen/SConscript
+++ b/src/mapi/glapi/gen/SConscript
@@ -51,7 +51,7 @@ env.CodeGenerate(
env.CodeGenerate(
target = '../../../mesa/main/enums.c',
script = 'gl_enums.py',
- source = sources,
+ source = '../registry/gl.xml',
command = python_cmd + ' $SCRIPT -f $SOURCE > $TARGET'
)
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index ec83cd43d16..21f6293bb6c 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -3139,7 +3139,6 @@
-
@@ -7975,7 +7974,7 @@
-
+
@@ -9687,11 +9686,11 @@
-
+
-
+
diff --git a/src/mapi/glapi/gen/gl_XML.py b/src/mapi/glapi/gen/gl_XML.py
index 67aba81a74e..2e7123ec406 100644
--- a/src/mapi/glapi/gen/gl_XML.py
+++ b/src/mapi/glapi/gen/gl_XML.py
@@ -183,7 +183,7 @@ class gl_print_base(object):
The name is also added to the file's undef_list.
"""
self.undef_list.append("PURE")
- print """# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+ print """# if defined(__GNUC__)
# define PURE __attribute__((pure))
# else
# define PURE
@@ -223,7 +223,7 @@ class gl_print_base(object):
"""
self.undef_list.append(S)
- print """# if (defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590) && defined(__ELF__))
+ print """# if defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
# define %s __attribute__((visibility("%s")))
# else
# define %s
@@ -243,7 +243,7 @@ class gl_print_base(object):
"""
self.undef_list.append("NOINLINE")
- print """# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+ print """# if defined(__GNUC__)
# define NOINLINE __attribute__((noinline))
# else
# define NOINLINE
diff --git a/src/mapi/glapi/gen/gl_enums.py b/src/mapi/glapi/gen/gl_enums.py
index 041c2f8ddb8..62cc1b36300 100644
--- a/src/mapi/glapi/gen/gl_enums.py
+++ b/src/mapi/glapi/gen/gl_enums.py
@@ -1,8 +1,8 @@
#!/usr/bin/python2
-# -*- Mode: Python; py-indent-offset: 8 -*-
# (C) Copyright Zack Rusin 2005. All Rights Reserved.
# Copyright (C) 2015 Intel Corporation
+# Copyright (C) 2015 Broadcom Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@@ -30,7 +30,9 @@ import argparse
import license
import gl_XML
+import xml.etree.ElementTree as ET
import sys, getopt
+import re
class PrintGlEnums(gl_XML.gl_print_base):
@@ -40,7 +42,10 @@ class PrintGlEnums(gl_XML.gl_print_base):
self.name = "gl_enums.py (from Mesa)"
self.license = license.bsd_license_template % ( \
"""Copyright (C) 1999-2005 Brian Paul All Rights Reserved.""", "BRIAN PAUL")
+ # Mapping from enum value to (name, priority) tuples.
self.enum_table = {}
+ # Mapping from enum name to value
+ self.string_to_int = {}
def printRealHeader(self):
@@ -50,7 +55,7 @@ class PrintGlEnums(gl_XML.gl_print_base):
print '#include "main/mtypes.h"'
print ''
print 'typedef struct PACKED {'
- print ' uint16_t offset;'
+ print ' uint32_t offset;'
print ' int n;'
print '} enum_elt;'
print ''
@@ -82,8 +87,6 @@ const char *_mesa_enum_to_string( int nr )
{
enum_elt *elt;
- STATIC_ASSERT(sizeof(enum_string_table) < (1 << 16));
-
elt = bsearch(& nr, enum_string_table_offsets,
ARRAY_SIZE(enum_string_table_offsets),
sizeof(enum_string_table_offsets[0]),
@@ -141,23 +144,10 @@ _mesa_lookup_prim_by_nr(GLuint nr)
return
- def printBody(self, api_list):
- self.enum_table = {}
- for api in api_list:
- self.process_enums( api )
-
- enum_table = []
-
- for enum in sorted(self.enum_table.keys()):
- low_pri = 9
- best_name = ''
- for [name, pri] in self.enum_table[ enum ]:
- if pri < low_pri:
- low_pri = pri
- best_name = name
-
- enum_table.append((enum, best_name))
+ def printBody(self, xml):
+ self.process_enums(xml)
+ sorted_enum_values = sorted(self.enum_table.keys())
string_offsets = {}
i = 0;
print '#if defined(__GNUC__)'
@@ -166,19 +156,28 @@ _mesa_lookup_prim_by_nr(GLuint nr)
print '# define LONGSTRING'
print '#endif'
print ''
- print 'LONGSTRING static const char enum_string_table[] = '
- for enum, name in enum_table:
- print ' "%s\\0"' % (name)
+ print 'LONGSTRING static const char enum_string_table[] = {'
+ # We express the very long concatenation of enum strings as an array
+ # of characters rather than as a string literal to work-around MSVC's
+ # 65535 character limit.
+ for enum in sorted_enum_values:
+ (name, pri) = self.enum_table[enum]
+ print " ",
+ for ch in name:
+ print "'%c'," % ch,
+ print "'\\0',"
+
string_offsets[ enum ] = i
i += len(name) + 1
- print ' ;'
+ print '};'
print ''
- print 'static const enum_elt enum_string_table_offsets[%u] =' % (len(enum_table))
+ print 'static const enum_elt enum_string_table_offsets[%u] =' % (len(self.enum_table))
print '{'
- for enum, name in enum_table:
+ for enum in sorted_enum_values:
+ (name, pri) = self.enum_table[enum]
print ' { %5u, 0x%08X }, /* %s */' % (string_offsets[enum], enum, name)
print '};'
print ''
@@ -186,22 +185,86 @@ _mesa_lookup_prim_by_nr(GLuint nr)
self.print_code()
return
+ def add_enum_provider(self, name, priority):
+ value = self.string_to_int[name]
- def process_enums(self, api):
- for obj in api.enumIterateByName():
- if obj.value not in self.enum_table:
- self.enum_table[ obj.value ] = []
+ # We don't want the weird GL_SKIP_COMPONENTS1_NV enums.
+ if value < 0:
+ return
+ # We don't want the 64-bit GL_TIMEOUT_IGNORED "enums"
+ if value > 0xffffffff:
+ return
+ # We don't want bitfields in the enum-to-string table --
+ # individual bits have so many names, it's pointless. Note
+ # that we check for power-of-two, since some getters have
+ # "_BITS" in their name, but none have a power-of-two enum
+ # number.
+ if not (value & (value - 1)) and '_BIT' in name:
+ return
- enum = self.enum_table[ obj.value ]
- name = "GL_" + obj.name
- priority = obj.priority()
- already_in = False;
- for n, p in enum:
- if n == name:
- already_in = True
- if not already_in:
- enum.append( [name, priority] )
+ # Also drop the GL_*_ATTRIB_BITS bitmasks.
+ if value == 0xffffffff:
+ return
+
+ if value in self.enum_table:
+ (n, p) = self.enum_table[value]
+ if priority < p:
+ self.enum_table[value] = (name, priority)
+ else:
+ self.enum_table[value] = (name, priority)
+
+ def process_extension(self, extension):
+ if extension.get('name').startswith('GL_ARB_'):
+ extension_prio = 400
+ elif extension.get('name').startswith('GL_EXT_'):
+ extension_prio = 600
+ else:
+ extension_prio = 800
+
+ for enum in extension.findall('require/enum'):
+ self.add_enum_provider(enum.get('name'), extension_prio)
+
+ def process_enums(self, xml):
+ # First, process the XML entries that define the hex values
+ # for all of the enum names.
+ for enum in xml.findall('enums/enum'):
+ name = enum.get('name')
+ value = int(enum.get('value'), base=16)
+
+ # If the same name ever maps to multiple values, that can
+ # confuse us. GL_ACTIVE_PROGRAM_EXT is OK to lose because
+ # we choose GL_ACTIVE PROGRAM instead.
+ if name in self.string_to_int and name != "GL_ACTIVE_PROGRAM_EXT":
+ print "#error Renumbering {0} from {1} to {2}".format(name, self.string_to_int[name], value)
+
+ self.string_to_int[name] = value
+
+ # Now, process all of the API versions and extensions that
+ # provide enums, so we can decide what name to call any hex
+ # value.
+ for feature in xml.findall('feature'):
+ feature_name = feature.get('name')
+
+ # When an enum gets renamed in a newer version (generally
+ # because of some generalization of the functionality),
+ # prefer the newer name. Also, prefer desktop GL names to
+ # ES.
+ m = re.match('GL_VERSION_([0-9])_([0-9])', feature_name)
+ if m:
+ feature_prio = 100 - int(m.group(1) + m.group(2))
+ else:
+ m = re.match('GL_ES_VERSION_([0-9])_([0-9])', feature_name)
+ if m:
+ feature_prio = 200 - int(m.group(1) + m.group(2))
+ else:
+ feature_prio = 200
+
+ for enum in feature.findall('require/enum'):
+ self.add_enum_provider(enum.get('name'), feature_prio)
+
+ for extension in xml.findall('extensions/extension'):
+ self.process_extension(extension)
def _parser():
@@ -214,10 +277,10 @@ def _parser():
def main():
args = _parser()
- api_list = [gl_XML.parse_GL_API(args.input_file)]
+ xml = ET.parse(args.input_file)
printer = PrintGlEnums()
- printer.Print(api_list)
+ printer.Print(xml)
if __name__ == '__main__':
diff --git a/src/mapi/glapi/glapi.h b/src/mapi/glapi/glapi.h
index 673295bca46..f269b1701bc 100644
--- a/src/mapi/glapi/glapi.h
+++ b/src/mapi/glapi/glapi.h
@@ -61,7 +61,7 @@ extern "C" {
# else
# define _GLAPI_EXPORT __declspec(dllimport)
# endif
-# elif defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+# elif defined(__GNUC__)
# define _GLAPI_EXPORT __attribute__((visibility("default")))
# else
# define _GLAPI_EXPORT
diff --git a/src/mapi/glapi/registry/gl.xml b/src/mapi/glapi/registry/gl.xml
new file mode 100755
index 00000000000..0e12acc9b54
--- /dev/null
+++ b/src/mapi/glapi/registry/gl.xml
@@ -0,0 +1,45348 @@
+
+
+
+Copyright (c) 2013-2014 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are 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 Materials.
+
+THE MATERIALS ARE 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
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+------------------------------------------------------------------------
+
+This file, gl.xml, is the OpenGL and OpenGL API Registry. The older
+".spec" file format has been retired and will no longer be updated with
+new extensions and API versions. The canonical version of the registry,
+together with documentation, schema, and Python generator scripts used
+to generate C header files for OpenGL and OpenGL ES, can always be found
+in the Khronos Registry at
+ http://www.opengl.org/registry/
+
+
+
+
+
+ #include <stddef.h>
+ #include <KHR/khrplatform.h>
+ #ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glxext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GL_EXT_timer_query extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(__sun__) || defined(__digital__)
+#include <inttypes.h>
+#if defined(__STDC__)
+#if defined(__arch64__) || defined(_LP64)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS ) || defined(__sgi)
+#include <inttypes.h>
+#elif defined(__SCO__) || defined(__USLC__)
+#include <stdint.h>
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/* Fallback if nothing above works */
+#include <inttypes.h>
+#endif
+#endif
+
+ typedef unsigned int GLenum ;
+ typedef unsigned char GLboolean ;
+ typedef unsigned int GLbitfield ;
+ typedef void GLvoid ;
+ typedef signed char GLbyte ;
+ typedef short GLshort ;
+ typedef int GLint ;
+ typedef int GLclampx ;
+ typedef unsigned char GLubyte ;
+ typedef unsigned short GLushort ;
+ typedef unsigned int GLuint ;
+ typedef int GLsizei ;
+ typedef float GLfloat ;
+ typedef float GLclampf ;
+ typedef double GLdouble ;
+ typedef double GLclampd ;
+ typedef void *GLeglImageOES ;
+ typedef char GLchar ;
+ typedef char GLcharARB ;
+ #ifdef __APPLE__
+typedef void *GLhandleARB;
+#else
+typedef unsigned int GLhandleARB;
+#endif
+ typedef unsigned short GLhalfARB ;
+ typedef unsigned short GLhalf ;
+ typedef GLint GLfixed ;
+ typedef ptrdiff_t GLintptr ;
+ typedef ptrdiff_t GLsizeiptr ;
+ typedef int64_t GLint64 ;
+ typedef uint64_t GLuint64 ;
+ typedef ptrdiff_t GLintptrARB ;
+ typedef ptrdiff_t GLsizeiptrARB ;
+ typedef int64_t GLint64EXT ;
+ typedef uint64_t GLuint64EXT ;
+ typedef struct __GLsync *GLsync ;
+ struct _cl_context ;
+ struct _cl_event ;
+ typedef void ( *GLDEBUGPROC )(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+ typedef void ( *GLDEBUGPROCARB )(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+ typedef void ( *GLDEBUGPROCKHR )(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+
+ typedef khronos_int32_t GLclampx ;
+
+ typedef khronos_int8_t GLbyte ;
+ typedef khronos_uint8_t GLubyte ;
+ typedef khronos_float_t GLfloat ;
+ typedef khronos_float_t GLclampf ;
+ typedef khronos_int32_t GLfixed ;
+ typedef khronos_int64_t GLint64 ;
+ typedef khronos_uint64_t GLuint64 ;
+ typedef khronos_intptr_t GLintptr ;
+ typedef khronos_ssize_t GLsizeiptr ;
+
+ typedef khronos_int8_t GLbyte ;
+ typedef khronos_uint8_t GLubyte ;
+ typedef khronos_float_t GLfloat ;
+ typedef khronos_float_t GLclampf ;
+ typedef khronos_int32_t GLfixed ;
+ typedef khronos_int64_t GLint64 ;
+ typedef khronos_uint64_t GLuint64 ;
+ typedef khronos_int64_t GLint64EXT ;
+ typedef khronos_uint64_t GLuint64EXT ;
+ typedef khronos_intptr_t GLintptr ;
+ typedef khronos_ssize_t GLsizeiptr ;
+
+
+ typedef void ( *GLDEBUGPROCAMD )(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
+ typedef unsigned short GLhalfNV ;
+ typedef GLintptr GLvdpauSurfaceNV ;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ void glAccum
+ GLenum op
+ GLfloat value
+
+
+
+ void glAccumxOES
+ GLenum op
+ GLfixed value
+
+
+ void glActiveProgramEXT
+ GLuint program
+
+
+ void glActiveShaderProgram
+ GLuint pipeline
+ GLuint program
+
+
+ void glActiveShaderProgramEXT
+ GLuint pipeline
+ GLuint program
+
+
+ void glActiveStencilFaceEXT
+ GLenum face
+
+
+
+ void glActiveTexture
+ GLenum texture
+
+
+
+ void glActiveTextureARB
+ GLenum texture
+
+
+
+
+ void glActiveVaryingNV
+ GLuint program
+ const GLchar *name
+
+
+ void glAlphaFragmentOp1ATI
+ GLenum op
+ GLuint dst
+ GLuint dstMod
+ GLuint arg1
+ GLuint arg1Rep
+ GLuint arg1Mod
+
+
+ void glAlphaFragmentOp2ATI
+ GLenum op
+ GLuint dst
+ GLuint dstMod
+ GLuint arg1
+ GLuint arg1Rep
+ GLuint arg1Mod
+ GLuint arg2
+ GLuint arg2Rep
+ GLuint arg2Mod
+
+
+ void glAlphaFragmentOp3ATI
+ GLenum op
+ GLuint dst
+ GLuint dstMod
+ GLuint arg1
+ GLuint arg1Rep
+ GLuint arg1Mod
+ GLuint arg2
+ GLuint arg2Rep
+ GLuint arg2Mod
+ GLuint arg3
+ GLuint arg3Rep
+ GLuint arg3Mod
+
+
+ void glAlphaFunc
+ GLenum func
+ GLfloat ref
+
+
+
+ void glAlphaFuncQCOM
+ GLenum func
+ GLclampf ref
+
+
+ void glAlphaFuncx
+ GLenum func
+ GLfixed ref
+
+
+ void glAlphaFuncxOES
+ GLenum func
+ GLfixed ref
+
+
+ void glApplyTextureEXT
+ GLenum mode
+
+
+ GLboolean glAreProgramsResidentNV
+ GLsizei n
+ const GLuint *programs
+ GLboolean *residences
+
+
+
+ GLboolean glAreTexturesResident
+ GLsizei n
+ const GLuint *textures
+ GLboolean *residences
+
+
+
+ GLboolean glAreTexturesResidentEXT
+ GLsizei n
+ const GLuint *textures
+ GLboolean *residences
+
+
+
+ void glArrayElement
+ GLint i
+
+
+ void glArrayElementEXT
+ GLint i
+
+
+
+ void glArrayObjectATI
+ GLenum array
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLuint buffer
+ GLuint offset
+
+
+ void glAsyncMarkerSGIX
+ GLuint marker
+
+
+ void glAttachObjectARB
+ GLhandleARB containerObj
+ GLhandleARB obj
+
+
+
+ void glAttachShader
+ GLuint program
+ GLuint shader
+
+
+ void glBegin
+ GLenum mode
+
+
+
+ void glBeginConditionalRender
+ GLuint id
+ GLenum mode
+
+
+ void glBeginConditionalRenderNV
+ GLuint id
+ GLenum mode
+
+
+
+
+ void glBeginConditionalRenderNVX
+ GLuint id
+
+
+ void glBeginFragmentShaderATI
+
+
+ void glBeginOcclusionQueryNV
+ GLuint id
+
+
+ void glBeginPerfMonitorAMD
+ GLuint monitor
+
+
+ void glBeginPerfQueryINTEL
+ GLuint queryHandle
+
+
+ void glBeginQuery
+ GLenum target
+ GLuint id
+
+
+
+ void glBeginQueryARB
+ GLenum target
+ GLuint id
+
+
+
+ void glBeginQueryEXT
+ GLenum target
+ GLuint id
+
+
+ void glBeginQueryIndexed
+ GLenum target
+ GLuint index
+ GLuint id
+
+
+ void glBeginTransformFeedback
+ GLenum primitiveMode
+
+
+ void glBeginTransformFeedbackEXT
+ GLenum primitiveMode
+
+
+
+ void glBeginTransformFeedbackNV
+ GLenum primitiveMode
+
+
+
+ void glBeginVertexShaderEXT
+
+
+ void glBeginVideoCaptureNV
+ GLuint video_capture_slot
+
+
+ void glBindAttribLocation
+ GLuint program
+ GLuint index
+ const GLchar *name
+
+
+ void glBindAttribLocationARB
+ GLhandleARB programObj
+ GLuint index
+ const GLcharARB *name
+
+
+
+ void glBindBuffer
+ GLenum target
+ GLuint buffer
+
+
+ void glBindBufferARB
+ GLenum target
+ GLuint buffer
+
+
+
+ void glBindBufferBase
+ GLenum target
+ GLuint index
+ GLuint buffer
+
+
+ void glBindBufferBaseEXT
+ GLenum target
+ GLuint index
+ GLuint buffer
+
+
+
+ void glBindBufferBaseNV
+ GLenum target
+ GLuint index
+ GLuint buffer
+
+
+
+ void glBindBufferOffsetEXT
+ GLenum target
+ GLuint index
+ GLuint buffer
+ GLintptr offset
+
+
+ void glBindBufferOffsetNV
+ GLenum target
+ GLuint index
+ GLuint buffer
+ GLintptr offset
+
+
+
+ void glBindBufferRange
+ GLenum target
+ GLuint index
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+
+
+ void glBindBufferRangeEXT
+ GLenum target
+ GLuint index
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+
+
+
+ void glBindBufferRangeNV
+ GLenum target
+ GLuint index
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+
+
+
+ void glBindBuffersBase
+ GLenum target
+ GLuint first
+ GLsizei count
+ const GLuint *buffers
+
+
+ void glBindBuffersRange
+ GLenum target
+ GLuint first
+ GLsizei count
+ const GLuint *buffers
+ const GLintptr *offsets
+ const GLsizeiptr *sizes
+
+
+ void glBindFragDataLocation
+ GLuint program
+ GLuint color
+ const GLchar *name
+
+
+ void glBindFragDataLocationEXT
+ GLuint program
+ GLuint color
+ const GLchar *name
+
+
+
+ void glBindFragDataLocationIndexed
+ GLuint program
+ GLuint colorNumber
+ GLuint index
+ const GLchar *name
+
+
+ void glBindFragmentShaderATI
+ GLuint id
+
+
+ void glBindFramebuffer
+ GLenum target
+ GLuint framebuffer
+
+
+
+ void glBindFramebufferEXT
+ GLenum target
+ GLuint framebuffer
+
+
+
+ void glBindFramebufferOES
+ GLenum target
+ GLuint framebuffer
+
+
+ void glBindImageTexture
+ GLuint unit
+ GLuint texture
+ GLint level
+ GLboolean layered
+ GLint layer
+ GLenum access
+ GLenum format
+
+
+ void glBindImageTextureEXT
+ GLuint index
+ GLuint texture
+ GLint level
+ GLboolean layered
+ GLint layer
+ GLenum access
+ GLint format
+
+
+ void glBindImageTextures
+ GLuint first
+ GLsizei count
+ const GLuint *textures
+
+
+ GLuint glBindLightParameterEXT
+ GLenum light
+ GLenum value
+
+
+ GLuint glBindMaterialParameterEXT
+ GLenum face
+ GLenum value
+
+
+ void glBindMultiTextureEXT
+ GLenum texunit
+ GLenum target
+ GLuint texture
+
+
+ GLuint glBindParameterEXT
+ GLenum value
+
+
+ void glBindProgramARB
+ GLenum target
+ GLuint program
+
+
+
+ void glBindProgramNV
+ GLenum target
+ GLuint id
+
+
+
+
+ void glBindProgramPipeline
+ GLuint pipeline
+
+
+ void glBindProgramPipelineEXT
+ GLuint pipeline
+
+
+ void glBindRenderbuffer
+ GLenum target
+ GLuint renderbuffer
+
+
+
+ void glBindRenderbufferEXT
+ GLenum target
+ GLuint renderbuffer
+
+
+
+ void glBindRenderbufferOES
+ GLenum target
+ GLuint renderbuffer
+
+
+ void glBindSampler
+ GLuint unit
+ GLuint sampler
+
+
+ void glBindSamplers
+ GLuint first
+ GLsizei count
+ const GLuint *samplers
+
+
+ GLuint glBindTexGenParameterEXT
+ GLenum unit
+ GLenum coord
+ GLenum value
+
+
+ void glBindTexture
+ GLenum target
+ GLuint texture
+
+
+
+ void glBindTextureEXT
+ GLenum target
+ GLuint texture
+
+
+
+
+ void glBindTextureUnit
+ GLuint unit
+ GLuint texture
+
+
+ GLuint glBindTextureUnitParameterEXT
+ GLenum unit
+ GLenum value
+
+
+ void glBindTextures
+ GLuint first
+ GLsizei count
+ const GLuint *textures
+
+
+ void glBindTransformFeedback
+ GLenum target
+ GLuint id
+
+
+ void glBindTransformFeedbackNV
+ GLenum target
+ GLuint id
+
+
+ void glBindVertexArray
+ GLuint array
+
+
+
+ void glBindVertexArrayAPPLE
+ GLuint array
+
+
+ void glBindVertexArrayOES
+ GLuint array
+
+
+
+ void glBindVertexBuffer
+ GLuint bindingindex
+ GLuint buffer
+ GLintptr offset
+ GLsizei stride
+
+
+ void glBindVertexBuffers
+ GLuint first
+ GLsizei count
+ const GLuint *buffers
+ const GLintptr *offsets
+ const GLsizei *strides
+
+
+ void glBindVertexShaderEXT
+ GLuint id
+
+
+ void glBindVideoCaptureStreamBufferNV
+ GLuint video_capture_slot
+ GLuint stream
+ GLenum frame_region
+ GLintptrARB offset
+
+
+ void glBindVideoCaptureStreamTextureNV
+ GLuint video_capture_slot
+ GLuint stream
+ GLenum frame_region
+ GLenum target
+ GLuint texture
+
+
+ void glBinormal3bEXT
+ GLbyte bx
+ GLbyte by
+ GLbyte bz
+
+
+
+ void glBinormal3bvEXT
+ const GLbyte *v
+
+
+ void glBinormal3dEXT
+ GLdouble bx
+ GLdouble by
+ GLdouble bz
+
+
+
+ void glBinormal3dvEXT
+ const GLdouble *v
+
+
+ void glBinormal3fEXT
+ GLfloat bx
+ GLfloat by
+ GLfloat bz
+
+
+
+ void glBinormal3fvEXT
+ const GLfloat *v
+
+
+ void glBinormal3iEXT
+ GLint bx
+ GLint by
+ GLint bz
+
+
+
+ void glBinormal3ivEXT
+ const GLint *v
+
+
+ void glBinormal3sEXT
+ GLshort bx
+ GLshort by
+ GLshort bz
+
+
+
+ void glBinormal3svEXT
+ const GLshort *v
+
+
+ void glBinormalPointerEXT
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glBitmap
+ GLsizei width
+ GLsizei height
+ GLfloat xorig
+ GLfloat yorig
+ GLfloat xmove
+ GLfloat ymove
+ const GLubyte *bitmap
+
+
+
+
+ void glBitmapxOES
+ GLsizei width
+ GLsizei height
+ GLfixed xorig
+ GLfixed yorig
+ GLfixed xmove
+ GLfixed ymove
+ const GLubyte *bitmap
+
+
+ void glBlendBarrierKHR
+
+
+ void glBlendBarrierNV
+
+
+ void glBlendColor
+ GLfloat red
+ GLfloat green
+ GLfloat blue
+ GLfloat alpha
+
+
+
+ void glBlendColorEXT
+ GLfloat red
+ GLfloat green
+ GLfloat blue
+ GLfloat alpha
+
+
+
+
+ void glBlendColorxOES
+ GLfixed red
+ GLfixed green
+ GLfixed blue
+ GLfixed alpha
+
+
+ void glBlendEquation
+ GLenum mode
+
+
+
+ void glBlendEquationEXT
+ GLenum mode
+
+
+
+
+ void glBlendEquationIndexedAMD
+ GLuint buf
+ GLenum mode
+
+
+
+ void glBlendEquationOES
+ GLenum mode
+
+
+ void glBlendEquationSeparate
+ GLenum modeRGB
+ GLenum modeAlpha
+
+
+
+ void glBlendEquationSeparateEXT
+ GLenum modeRGB
+ GLenum modeAlpha
+
+
+
+
+ void glBlendEquationSeparateIndexedAMD
+ GLuint buf
+ GLenum modeRGB
+ GLenum modeAlpha
+
+
+
+ void glBlendEquationSeparateOES
+ GLenum modeRGB
+ GLenum modeAlpha
+
+
+ void glBlendEquationSeparatei
+ GLuint buf
+ GLenum modeRGB
+ GLenum modeAlpha
+
+
+ void glBlendEquationSeparateiARB
+ GLuint buf
+ GLenum modeRGB
+ GLenum modeAlpha
+
+
+
+ void glBlendEquationSeparateiEXT
+ GLuint buf
+ GLenum modeRGB
+ GLenum modeAlpha
+
+
+
+ void glBlendEquationSeparateiOES
+ GLuint buf
+ GLenum modeRGB
+ GLenum modeAlpha
+
+
+
+ void glBlendEquationi
+ GLuint buf
+ GLenum mode
+
+
+ void glBlendEquationiARB
+ GLuint buf
+ GLenum mode
+
+
+
+ void glBlendEquationiEXT
+ GLuint buf
+ GLenum mode
+
+
+
+ void glBlendEquationiOES
+ GLuint buf
+ GLenum mode
+
+
+
+ void glBlendFunc
+ GLenum sfactor
+ GLenum dfactor
+
+
+
+ void glBlendFuncIndexedAMD
+ GLuint buf
+ GLenum src
+ GLenum dst
+
+
+
+ void glBlendFuncSeparate
+ GLenum sfactorRGB
+ GLenum dfactorRGB
+ GLenum sfactorAlpha
+ GLenum dfactorAlpha
+
+
+
+ void glBlendFuncSeparateEXT
+ GLenum sfactorRGB
+ GLenum dfactorRGB
+ GLenum sfactorAlpha
+ GLenum dfactorAlpha
+
+
+
+
+ void glBlendFuncSeparateINGR
+ GLenum sfactorRGB
+ GLenum dfactorRGB
+ GLenum sfactorAlpha
+ GLenum dfactorAlpha
+
+
+
+
+ void glBlendFuncSeparateIndexedAMD
+ GLuint buf
+ GLenum srcRGB
+ GLenum dstRGB
+ GLenum srcAlpha
+ GLenum dstAlpha
+
+
+
+ void glBlendFuncSeparateOES
+ GLenum srcRGB
+ GLenum dstRGB
+ GLenum srcAlpha
+ GLenum dstAlpha
+
+
+ void glBlendFuncSeparatei
+ GLuint buf
+ GLenum srcRGB
+ GLenum dstRGB
+ GLenum srcAlpha
+ GLenum dstAlpha
+
+
+ void glBlendFuncSeparateiARB
+ GLuint buf
+ GLenum srcRGB
+ GLenum dstRGB
+ GLenum srcAlpha
+ GLenum dstAlpha
+
+
+
+ void glBlendFuncSeparateiEXT
+ GLuint buf
+ GLenum srcRGB
+ GLenum dstRGB
+ GLenum srcAlpha
+ GLenum dstAlpha
+
+
+
+ void glBlendFuncSeparateiOES
+ GLuint buf
+ GLenum srcRGB
+ GLenum dstRGB
+ GLenum srcAlpha
+ GLenum dstAlpha
+
+
+
+ void glBlendFunci
+ GLuint buf
+ GLenum src
+ GLenum dst
+
+
+ void glBlendFunciARB
+ GLuint buf
+ GLenum src
+ GLenum dst
+
+
+
+ void glBlendFunciEXT
+ GLuint buf
+ GLenum src
+ GLenum dst
+
+
+
+ void glBlendFunciOES
+ GLuint buf
+ GLenum src
+ GLenum dst
+
+
+
+ void glBlendParameteriNV
+ GLenum pname
+ GLint value
+
+
+ void glBlitFramebuffer
+ GLint srcX0
+ GLint srcY0
+ GLint srcX1
+ GLint srcY1
+ GLint dstX0
+ GLint dstY0
+ GLint dstX1
+ GLint dstY1
+ GLbitfield mask
+ GLenum filter
+
+
+
+ void glBlitFramebufferANGLE
+ GLint srcX0
+ GLint srcY0
+ GLint srcX1
+ GLint srcY1
+ GLint dstX0
+ GLint dstY0
+ GLint dstX1
+ GLint dstY1
+ GLbitfield mask
+ GLenum filter
+
+
+ void glBlitFramebufferEXT
+ GLint srcX0
+ GLint srcY0
+ GLint srcX1
+ GLint srcY1
+ GLint dstX0
+ GLint dstY0
+ GLint dstX1
+ GLint dstY1
+ GLbitfield mask
+ GLenum filter
+
+
+
+
+ void glBlitFramebufferNV
+ GLint srcX0
+ GLint srcY0
+ GLint srcX1
+ GLint srcY1
+ GLint dstX0
+ GLint dstY0
+ GLint dstX1
+ GLint dstY1
+ GLbitfield mask
+ GLenum filter
+
+
+
+ void glBlitNamedFramebuffer
+ GLuint readFramebuffer
+ GLuint drawFramebuffer
+ GLint srcX0
+ GLint srcY0
+ GLint srcX1
+ GLint srcY1
+ GLint dstX0
+ GLint dstY0
+ GLint dstX1
+ GLint dstY1
+ GLbitfield mask
+ GLenum filter
+
+
+ void glBufferAddressRangeNV
+ GLenum pname
+ GLuint index
+ GLuint64EXT address
+ GLsizeiptr length
+
+
+ void glBufferData
+ GLenum target
+ GLsizeiptr size
+ const void *data
+ GLenum usage
+
+
+ void glBufferDataARB
+ GLenum target
+ GLsizeiptrARB size
+ const void *data
+ GLenum usage
+
+
+
+ void glBufferPageCommitmentARB
+ GLenum target
+ GLintptr offset
+ GLsizeiptr size
+ GLboolean commit
+
+
+ void glBufferParameteriAPPLE
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+ void glBufferStorage
+ GLenum target
+ GLsizeiptr size
+ const void *data
+ GLbitfield flags
+
+
+ void glBufferStorageEXT
+ GLenum target
+ GLsizeiptr size
+ const void *data
+ GLbitfield flags
+
+
+
+ void glBufferSubData
+ GLenum target
+ GLintptr offset
+ GLsizeiptr size
+ const void *data
+
+
+ void glBufferSubDataARB
+ GLenum target
+ GLintptrARB offset
+ GLsizeiptrARB size
+ const void *data
+
+
+
+ void glCallCommandListNV
+ GLuint list
+
+
+ void glCallList
+ GLuint list
+
+
+
+ void glCallLists
+ GLsizei n
+ GLenum type
+ const void *lists
+
+
+
+ GLenum glCheckFramebufferStatus
+ GLenum target
+
+
+
+ GLenum glCheckFramebufferStatusEXT
+ GLenum target
+
+
+
+
+ GLenum glCheckFramebufferStatusOES
+ GLenum target
+
+
+ GLenum glCheckNamedFramebufferStatus
+ GLuint framebuffer
+ GLenum target
+
+
+ GLenum glCheckNamedFramebufferStatusEXT
+ GLuint framebuffer
+ GLenum target
+
+
+ void glClampColor
+ GLenum target
+ GLenum clamp
+
+
+
+ void glClampColorARB
+ GLenum target
+ GLenum clamp
+
+
+
+
+ void glClear
+ GLbitfield mask
+
+
+
+ void glClearAccum
+ GLfloat red
+ GLfloat green
+ GLfloat blue
+ GLfloat alpha
+
+
+
+ void glClearAccumxOES
+ GLfixed red
+ GLfixed green
+ GLfixed blue
+ GLfixed alpha
+
+
+ void glClearBufferData
+ GLenum target
+ GLenum internalformat
+ GLenum format
+ GLenum type
+ const void *data
+
+
+ void glClearBufferSubData
+ GLenum target
+ GLenum internalformat
+ GLintptr offset
+ GLsizeiptr size
+ GLenum format
+ GLenum type
+ const void *data
+
+
+ void glClearBufferfi
+ GLenum buffer
+ GLint drawbuffer
+ GLfloat depth
+ GLint stencil
+
+
+ void glClearBufferfv
+ GLenum buffer
+ GLint drawbuffer
+ const GLfloat *value
+
+
+ void glClearBufferiv
+ GLenum buffer
+ GLint drawbuffer
+ const GLint *value
+
+
+ void glClearBufferuiv
+ GLenum buffer
+ GLint drawbuffer
+ const GLuint *value
+
+
+ void glClearColor
+ GLfloat red
+ GLfloat green
+ GLfloat blue
+ GLfloat alpha
+
+
+
+ void glClearColorIiEXT
+ GLint red
+ GLint green
+ GLint blue
+ GLint alpha
+
+
+
+ void glClearColorIuiEXT
+ GLuint red
+ GLuint green
+ GLuint blue
+ GLuint alpha
+
+
+
+ void glClearColorx
+ GLfixed red
+ GLfixed green
+ GLfixed blue
+ GLfixed alpha
+
+
+ void glClearColorxOES
+ GLfixed red
+ GLfixed green
+ GLfixed blue
+ GLfixed alpha
+
+
+ void glClearDepth
+ GLdouble depth
+
+
+
+ void glClearDepthdNV
+ GLdouble depth
+
+
+
+ void glClearDepthf
+ GLfloat d
+
+
+ void glClearDepthfOES
+ GLclampf depth
+
+
+
+
+ void glClearDepthx
+ GLfixed depth
+
+
+ void glClearDepthxOES
+ GLfixed depth
+
+
+ void glClearIndex
+ GLfloat c
+
+
+
+ void glClearNamedBufferData
+ GLuint buffer
+ GLenum internalformat
+ GLenum format
+ GLenum type
+ const void *data
+
+
+ void glClearNamedBufferDataEXT
+ GLuint buffer
+ GLenum internalformat
+ GLenum format
+ GLenum type
+ const void *data
+
+
+ void glClearNamedBufferSubData
+ GLuint buffer
+ GLenum internalformat
+ GLintptr offset
+ GLsizeiptr size
+ GLenum format
+ GLenum type
+ const void *data
+
+
+ void glClearNamedBufferSubDataEXT
+ GLuint buffer
+ GLenum internalformat
+ GLsizeiptr offset
+ GLsizeiptr size
+ GLenum format
+ GLenum type
+ const void *data
+
+
+ void glClearNamedFramebufferfi
+ GLuint framebuffer
+ GLenum buffer
+ const GLfloat depth
+ GLint stencil
+
+
+ void glClearNamedFramebufferfv
+ GLuint framebuffer
+ GLenum buffer
+ GLint drawbuffer
+ const GLfloat *value
+
+
+ void glClearNamedFramebufferiv
+ GLuint framebuffer
+ GLenum buffer
+ GLint drawbuffer
+ const GLint *value
+
+
+ void glClearNamedFramebufferuiv
+ GLuint framebuffer
+ GLenum buffer
+ GLint drawbuffer
+ const GLuint *value
+
+
+ void glClearStencil
+ GLint s
+
+
+
+ void glClearTexImage
+ GLuint texture
+ GLint level
+ GLenum format
+ GLenum type
+ const void *data
+
+
+ void glClearTexSubImage
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLenum type
+ const void *data
+
+
+ void glClientActiveTexture
+ GLenum texture
+
+
+ void glClientActiveTextureARB
+ GLenum texture
+
+
+
+ void glClientActiveVertexStreamATI
+ GLenum stream
+
+
+ void glClientAttribDefaultEXT
+ GLbitfield mask
+
+
+ GLenum glClientWaitSync
+ GLsync sync
+ GLbitfield flags
+ GLuint64 timeout
+
+
+ GLenum glClientWaitSyncAPPLE
+ GLsync sync
+ GLbitfield flags
+ GLuint64 timeout
+
+
+
+ void glClipControl
+ GLenum origin
+ GLenum depth
+
+
+ void glClipPlane
+ GLenum plane
+ const GLdouble *equation
+
+
+
+ void glClipPlanef
+ GLenum p
+ const GLfloat *eqn
+
+
+ void glClipPlanefIMG
+ GLenum p
+ const GLfloat *eqn
+
+
+ void glClipPlanefOES
+ GLenum plane
+ const GLfloat *equation
+
+
+
+ void glClipPlanex
+ GLenum plane
+ const GLfixed *equation
+
+
+ void glClipPlanexIMG
+ GLenum p
+ const GLfixed *eqn
+
+
+ void glClipPlanexOES
+ GLenum plane
+ const GLfixed *equation
+
+
+ void glColor3b
+ GLbyte red
+ GLbyte green
+ GLbyte blue
+
+
+
+ void glColor3bv
+ const GLbyte *v
+
+
+
+ void glColor3d
+ GLdouble red
+ GLdouble green
+ GLdouble blue
+
+
+
+ void glColor3dv
+ const GLdouble *v
+
+
+
+ void glColor3f
+ GLfloat red
+ GLfloat green
+ GLfloat blue
+
+
+
+ void glColor3fVertex3fSUN
+ GLfloat r
+ GLfloat g
+ GLfloat b
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glColor3fVertex3fvSUN
+ const GLfloat *c
+ const GLfloat *v
+
+
+ void glColor3fv
+ const GLfloat *v
+
+
+
+ void glColor3hNV
+ GLhalfNV red
+ GLhalfNV green
+ GLhalfNV blue
+
+
+
+ void glColor3hvNV
+ const GLhalfNV *v
+
+
+
+ void glColor3i
+ GLint red
+ GLint green
+ GLint blue
+
+
+
+ void glColor3iv
+ const GLint *v
+
+
+
+ void glColor3s
+ GLshort red
+ GLshort green
+ GLshort blue
+
+
+
+ void glColor3sv
+ const GLshort *v
+
+
+
+ void glColor3ub
+ GLubyte red
+ GLubyte green
+ GLubyte blue
+
+
+
+ void glColor3ubv
+ const GLubyte *v
+
+
+
+ void glColor3ui
+ GLuint red
+ GLuint green
+ GLuint blue
+
+
+
+ void glColor3uiv
+ const GLuint *v
+
+
+
+ void glColor3us
+ GLushort red
+ GLushort green
+ GLushort blue
+
+
+
+ void glColor3usv
+ const GLushort *v
+
+
+
+ void glColor3xOES
+ GLfixed red
+ GLfixed green
+ GLfixed blue
+
+
+ void glColor3xvOES
+ const GLfixed *components
+
+
+ void glColor4b
+ GLbyte red
+ GLbyte green
+ GLbyte blue
+ GLbyte alpha
+
+
+
+ void glColor4bv
+ const GLbyte *v
+
+
+
+ void glColor4d
+ GLdouble red
+ GLdouble green
+ GLdouble blue
+ GLdouble alpha
+
+
+
+ void glColor4dv
+ const GLdouble *v
+
+
+
+ void glColor4f
+ GLfloat red
+ GLfloat green
+ GLfloat blue
+ GLfloat alpha
+
+
+
+ void glColor4fNormal3fVertex3fSUN
+ GLfloat r
+ GLfloat g
+ GLfloat b
+ GLfloat a
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glColor4fNormal3fVertex3fvSUN
+ const GLfloat *c
+ const GLfloat *n
+ const GLfloat *v
+
+
+ void glColor4fv
+ const GLfloat *v
+
+
+
+ void glColor4hNV
+ GLhalfNV red
+ GLhalfNV green
+ GLhalfNV blue
+ GLhalfNV alpha
+
+
+
+ void glColor4hvNV
+ const GLhalfNV *v
+
+
+
+ void glColor4i
+ GLint red
+ GLint green
+ GLint blue
+ GLint alpha
+
+
+
+ void glColor4iv
+ const GLint *v
+
+
+
+ void glColor4s
+ GLshort red
+ GLshort green
+ GLshort blue
+ GLshort alpha
+
+
+
+ void glColor4sv
+ const GLshort *v
+
+
+
+ void glColor4ub
+ GLubyte red
+ GLubyte green
+ GLubyte blue
+ GLubyte alpha
+
+
+
+ void glColor4ubVertex2fSUN
+ GLubyte r
+ GLubyte g
+ GLubyte b
+ GLubyte a
+ GLfloat x
+ GLfloat y
+
+
+ void glColor4ubVertex2fvSUN
+ const GLubyte *c
+ const GLfloat *v
+
+
+ void glColor4ubVertex3fSUN
+ GLubyte r
+ GLubyte g
+ GLubyte b
+ GLubyte a
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glColor4ubVertex3fvSUN
+ const GLubyte *c
+ const GLfloat *v
+
+
+ void glColor4ubv
+ const GLubyte *v
+
+
+
+ void glColor4ui
+ GLuint red
+ GLuint green
+ GLuint blue
+ GLuint alpha
+
+
+
+ void glColor4uiv
+ const GLuint *v
+
+
+
+ void glColor4us
+ GLushort red
+ GLushort green
+ GLushort blue
+ GLushort alpha
+
+
+
+ void glColor4usv
+ const GLushort *v
+
+
+
+ void glColor4x
+ GLfixed red
+ GLfixed green
+ GLfixed blue
+ GLfixed alpha
+
+
+ void glColor4xOES
+ GLfixed red
+ GLfixed green
+ GLfixed blue
+ GLfixed alpha
+
+
+ void glColor4xvOES
+ const GLfixed *components
+
+
+ void glColorFormatNV
+ GLint size
+ GLenum type
+ GLsizei stride
+
+
+ void glColorFragmentOp1ATI
+ GLenum op
+ GLuint dst
+ GLuint dstMask
+ GLuint dstMod
+ GLuint arg1
+ GLuint arg1Rep
+ GLuint arg1Mod
+
+
+ void glColorFragmentOp2ATI
+ GLenum op
+ GLuint dst
+ GLuint dstMask
+ GLuint dstMod
+ GLuint arg1
+ GLuint arg1Rep
+ GLuint arg1Mod
+ GLuint arg2
+ GLuint arg2Rep
+ GLuint arg2Mod
+
+
+ void glColorFragmentOp3ATI
+ GLenum op
+ GLuint dst
+ GLuint dstMask
+ GLuint dstMod
+ GLuint arg1
+ GLuint arg1Rep
+ GLuint arg1Mod
+ GLuint arg2
+ GLuint arg2Rep
+ GLuint arg2Mod
+ GLuint arg3
+ GLuint arg3Rep
+ GLuint arg3Mod
+
+
+ void glColorMask
+ GLboolean red
+ GLboolean green
+ GLboolean blue
+ GLboolean alpha
+
+
+
+ void glColorMaskIndexedEXT
+ GLuint index
+ GLboolean r
+ GLboolean g
+ GLboolean b
+ GLboolean a
+
+
+
+ void glColorMaski
+ GLuint index
+ GLboolean r
+ GLboolean g
+ GLboolean b
+ GLboolean a
+
+
+ void glColorMaskiEXT
+ GLuint index
+ GLboolean r
+ GLboolean g
+ GLboolean b
+ GLboolean a
+
+
+
+ void glColorMaskiOES
+ GLuint index
+ GLboolean r
+ GLboolean g
+ GLboolean b
+ GLboolean a
+
+
+
+ void glColorMaterial
+ GLenum face
+ GLenum mode
+
+
+
+ void glColorP3ui
+ GLenum type
+ GLuint color
+
+
+ void glColorP3uiv
+ GLenum type
+ const GLuint *color
+
+
+ void glColorP4ui
+ GLenum type
+ GLuint color
+
+
+ void glColorP4uiv
+ GLenum type
+ const GLuint *color
+
+
+ void glColorPointer
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glColorPointerEXT
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLsizei count
+ const void *pointer
+
+
+ void glColorPointerListIBM
+ GLint size
+ GLenum type
+ GLint stride
+ const void **pointer
+ GLint ptrstride
+
+
+ void glColorPointervINTEL
+ GLint size
+ GLenum type
+ const void **pointer
+
+
+ void glColorSubTable
+ GLenum target
+ GLsizei start
+ GLsizei count
+ GLenum format
+ GLenum type
+ const void *data
+
+
+
+
+ void glColorSubTableEXT
+ GLenum target
+ GLsizei start
+ GLsizei count
+ GLenum format
+ GLenum type
+ const void *data
+
+
+
+ void glColorTable
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *table
+
+
+
+
+ void glColorTableEXT
+ GLenum target
+ GLenum internalFormat
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *table
+
+
+
+ void glColorTableParameterfv
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glColorTableParameterfvSGI
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+
+
+ void glColorTableParameteriv
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+
+ void glColorTableParameterivSGI
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+
+
+ void glColorTableSGI
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *table
+
+
+
+
+ void glCombinerInputNV
+ GLenum stage
+ GLenum portion
+ GLenum variable
+ GLenum input
+ GLenum mapping
+ GLenum componentUsage
+
+
+
+ void glCombinerOutputNV
+ GLenum stage
+ GLenum portion
+ GLenum abOutput
+ GLenum cdOutput
+ GLenum sumOutput
+ GLenum scale
+ GLenum bias
+ GLboolean abDotProduct
+ GLboolean cdDotProduct
+ GLboolean muxSum
+
+
+
+ void glCombinerParameterfNV
+ GLenum pname
+ GLfloat param
+
+
+
+ void glCombinerParameterfvNV
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glCombinerParameteriNV
+ GLenum pname
+ GLint param
+
+
+
+ void glCombinerParameterivNV
+ GLenum pname
+ const GLint *params
+
+
+
+ void glCombinerStageParameterfvNV
+ GLenum stage
+ GLenum pname
+ const GLfloat *params
+
+
+ void glCommandListSegmentsNV
+ GLuint list
+ GLuint segments
+
+
+ void glCompileCommandListNV
+ GLuint list
+
+
+ void glCompileShader
+ GLuint shader
+
+
+ void glCompileShaderARB
+ GLhandleARB shaderObj
+
+
+
+ void glCompileShaderIncludeARB
+ GLuint shader
+ GLsizei count
+ const GLchar *const*path
+ const GLint *length
+
+
+ void glCompressedMultiTexImage1DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLint border
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedMultiTexImage2DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLint border
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedMultiTexImage3DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedMultiTexSubImage1DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedMultiTexSubImage2DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedMultiTexSubImage3DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedTexImage1D
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLint border
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexImage1DARB
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLint border
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexImage2D
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLint border
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexImage2DARB
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLint border
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexImage3D
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexImage3DARB
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexImage3DOES
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLsizei imageSize
+ const void *data
+
+
+
+ void glCompressedTexSubImage1D
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexSubImage1DARB
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexSubImage2D
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexSubImage2DARB
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexSubImage3D
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexSubImage3DARB
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+
+
+ void glCompressedTexSubImage3DOES
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+
+ void glCompressedTextureImage1DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLint border
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedTextureImage2DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLint border
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedTextureImage3DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedTextureSubImage1D
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+ void glCompressedTextureSubImage1DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedTextureSubImage2D
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+ void glCompressedTextureSubImage2DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLsizei imageSize
+ const void *bits
+
+
+ void glCompressedTextureSubImage3D
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLsizei imageSize
+ const void *data
+
+
+ void glCompressedTextureSubImage3DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLsizei imageSize
+ const void *bits
+
+
+ void glConvolutionFilter1D
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *image
+
+
+
+
+ void glConvolutionFilter1DEXT
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *image
+
+
+
+
+ void glConvolutionFilter2D
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *image
+
+
+
+
+ void glConvolutionFilter2DEXT
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *image
+
+
+
+
+ void glConvolutionParameterf
+ GLenum target
+ GLenum pname
+ GLfloat params
+
+
+
+ void glConvolutionParameterfEXT
+ GLenum target
+ GLenum pname
+ GLfloat params
+
+
+
+
+ void glConvolutionParameterfv
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glConvolutionParameterfvEXT
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+
+
+ void glConvolutionParameteri
+ GLenum target
+ GLenum pname
+ GLint params
+
+
+
+ void glConvolutionParameteriEXT
+ GLenum target
+ GLenum pname
+ GLint params
+
+
+
+
+ void glConvolutionParameteriv
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+
+ void glConvolutionParameterivEXT
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+
+
+ void glConvolutionParameterxOES
+ GLenum target
+ GLenum pname
+ GLfixed param
+
+
+ void glConvolutionParameterxvOES
+ GLenum target
+ GLenum pname
+ const GLfixed *params
+
+
+ void glCopyBufferSubData
+ GLenum readTarget
+ GLenum writeTarget
+ GLintptr readOffset
+ GLintptr writeOffset
+ GLsizeiptr size
+
+
+ void glCopyBufferSubDataNV
+ GLenum readTarget
+ GLenum writeTarget
+ GLintptr readOffset
+ GLintptr writeOffset
+ GLsizeiptr size
+
+
+
+ void glCopyColorSubTable
+ GLenum target
+ GLsizei start
+ GLint x
+ GLint y
+ GLsizei width
+
+
+
+ void glCopyColorSubTableEXT
+ GLenum target
+ GLsizei start
+ GLint x
+ GLint y
+ GLsizei width
+
+
+
+ void glCopyColorTable
+ GLenum target
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+
+
+
+ void glCopyColorTableSGI
+ GLenum target
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+
+
+
+
+ void glCopyConvolutionFilter1D
+ GLenum target
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+
+
+
+ void glCopyConvolutionFilter1DEXT
+ GLenum target
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+
+
+
+
+ void glCopyConvolutionFilter2D
+ GLenum target
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+
+ void glCopyConvolutionFilter2DEXT
+ GLenum target
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+
+
+ void glCopyImageSubData
+ GLuint srcName
+ GLenum srcTarget
+ GLint srcLevel
+ GLint srcX
+ GLint srcY
+ GLint srcZ
+ GLuint dstName
+ GLenum dstTarget
+ GLint dstLevel
+ GLint dstX
+ GLint dstY
+ GLint dstZ
+ GLsizei srcWidth
+ GLsizei srcHeight
+ GLsizei srcDepth
+
+
+ void glCopyImageSubDataEXT
+ GLuint srcName
+ GLenum srcTarget
+ GLint srcLevel
+ GLint srcX
+ GLint srcY
+ GLint srcZ
+ GLuint dstName
+ GLenum dstTarget
+ GLint dstLevel
+ GLint dstX
+ GLint dstY
+ GLint dstZ
+ GLsizei srcWidth
+ GLsizei srcHeight
+ GLsizei srcDepth
+
+
+
+ void glCopyImageSubDataOES
+ GLuint srcName
+ GLenum srcTarget
+ GLint srcLevel
+ GLint srcX
+ GLint srcY
+ GLint srcZ
+ GLuint dstName
+ GLenum dstTarget
+ GLint dstLevel
+ GLint dstX
+ GLint dstY
+ GLint dstZ
+ GLsizei srcWidth
+ GLsizei srcHeight
+ GLsizei srcDepth
+
+
+
+ void glCopyImageSubDataNV
+ GLuint srcName
+ GLenum srcTarget
+ GLint srcLevel
+ GLint srcX
+ GLint srcY
+ GLint srcZ
+ GLuint dstName
+ GLenum dstTarget
+ GLint dstLevel
+ GLint dstX
+ GLint dstY
+ GLint dstZ
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+
+
+
+ void glCopyMultiTexImage1DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLint border
+
+
+ void glCopyMultiTexImage2DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLint border
+
+
+ void glCopyMultiTexSubImage1DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint x
+ GLint y
+ GLsizei width
+
+
+ void glCopyMultiTexSubImage2DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+ void glCopyMultiTexSubImage3DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+ void glCopyNamedBufferSubData
+ GLuint readBuffer
+ GLuint writeBuffer
+ GLintptr readOffset
+ GLintptr writeOffset
+ GLsizeiptr size
+
+
+ void glCopyPathNV
+ GLuint resultPath
+ GLuint srcPath
+
+
+ void glCopyPixels
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLenum type
+
+
+
+ void glCopyTexImage1D
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLint border
+
+
+
+ void glCopyTexImage1DEXT
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLint border
+
+
+
+
+ void glCopyTexImage2D
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLint border
+
+
+
+ void glCopyTexImage2DEXT
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLint border
+
+
+
+
+ void glCopyTexSubImage1D
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint x
+ GLint y
+ GLsizei width
+
+
+
+ void glCopyTexSubImage1DEXT
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint x
+ GLint y
+ GLsizei width
+
+
+
+
+ void glCopyTexSubImage2D
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+
+ void glCopyTexSubImage2DEXT
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+
+
+ void glCopyTexSubImage3D
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+
+ void glCopyTexSubImage3DEXT
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+
+
+ void glCopyTexSubImage3DOES
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+
+ void glCopyTextureImage1DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLint border
+
+
+ void glCopyTextureImage2DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLint border
+
+
+ void glCopyTextureLevelsAPPLE
+ GLuint destinationTexture
+ GLuint sourceTexture
+ GLint sourceBaseLevel
+ GLsizei sourceLevelCount
+
+
+ void glCopyTextureSubImage1D
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint x
+ GLint y
+ GLsizei width
+
+
+ void glCopyTextureSubImage1DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint x
+ GLint y
+ GLsizei width
+
+
+ void glCopyTextureSubImage2D
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+ void glCopyTextureSubImage2DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+ void glCopyTextureSubImage3D
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+ void glCopyTextureSubImage3DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+ void glCoverFillPathInstancedNV
+ GLsizei numPaths
+ GLenum pathNameType
+ const void *paths
+ GLuint pathBase
+ GLenum coverMode
+ GLenum transformType
+ const GLfloat *transformValues
+
+
+ void glCoverFillPathNV
+ GLuint path
+ GLenum coverMode
+
+
+ void glCoverStrokePathInstancedNV
+ GLsizei numPaths
+ GLenum pathNameType
+ const void *paths
+ GLuint pathBase
+ GLenum coverMode
+ GLenum transformType
+ const GLfloat *transformValues
+
+
+ void glCoverStrokePathNV
+ GLuint path
+ GLenum coverMode
+
+
+ void glCoverageMaskNV
+ GLboolean mask
+
+
+ void glCoverageOperationNV
+ GLenum operation
+
+
+ void glCreateBuffers
+ GLsizei n
+ GLuint *buffers
+
+
+ void glCreateCommandListsNV
+ GLsizei n
+ GLuint *lists
+
+
+ void glCreateStatesNV
+ GLsizei n
+ GLuint *states
+
+
+ void glCreateFramebuffers
+ GLsizei n
+ GLuint *framebuffers
+
+
+ void glCreatePerfQueryINTEL
+ GLuint queryId
+ GLuint *queryHandle
+
+
+ GLuint glCreateProgram
+
+
+ GLhandleARB glCreateProgramObjectARB
+
+
+
+ void glCreateProgramPipelines
+ GLsizei n
+ GLuint *pipelines
+
+
+ void glCreateQueries
+ GLenum target
+ GLsizei n
+ GLuint *ids
+
+
+ void glCreateRenderbuffers
+ GLsizei n
+ GLuint *renderbuffers
+
+
+ void glCreateSamplers
+ GLsizei n
+ GLuint *samplers
+
+
+ GLuint glCreateShader
+ GLenum type
+
+
+ GLhandleARB glCreateShaderObjectARB
+ GLenum shaderType
+
+
+
+ GLuint glCreateShaderProgramEXT
+ GLenum type
+ const GLchar *string
+
+
+ GLuint glCreateShaderProgramv
+ GLenum type
+ GLsizei count
+ const GLchar *const*strings
+
+
+ GLuint glCreateShaderProgramvEXT
+ GLenum type
+ GLsizei count
+ const GLchar **strings
+
+
+ GLsync glCreateSyncFromCLeventARB
+ struct _cl_context *context
+ struct _cl_event *event
+ GLbitfield flags
+
+
+ void glCreateTextures
+ GLenum target
+ GLsizei n
+ GLuint *textures
+
+
+ void glCreateTransformFeedbacks
+ GLsizei n
+ GLuint *ids
+
+
+ void glCreateVertexArrays
+ GLsizei n
+ GLuint *arrays
+
+
+ void glCullFace
+ GLenum mode
+
+
+
+ void glCullParameterdvEXT
+ GLenum pname
+ GLdouble *params
+
+
+ void glCullParameterfvEXT
+ GLenum pname
+ GLfloat *params
+
+
+ void glCurrentPaletteMatrixARB
+ GLint index
+
+
+
+ void glCurrentPaletteMatrixOES
+ GLuint matrixpaletteindex
+
+
+ void glDebugMessageCallback
+ GLDEBUGPROC callback
+ const void *userParam
+
+
+ void glDebugMessageCallbackAMD
+ GLDEBUGPROCAMD callback
+ void *userParam
+
+
+ void glDebugMessageCallbackARB
+ GLDEBUGPROCARB callback
+ const void *userParam
+
+
+
+ void glDebugMessageCallbackKHR
+ GLDEBUGPROCKHR callback
+ const void *userParam
+
+
+
+ void glDebugMessageControl
+ GLenum source
+ GLenum type
+ GLenum severity
+ GLsizei count
+ const GLuint *ids
+ GLboolean enabled
+
+
+ void glDebugMessageControlARB
+ GLenum source
+ GLenum type
+ GLenum severity
+ GLsizei count
+ const GLuint *ids
+ GLboolean enabled
+
+
+
+ void glDebugMessageControlKHR
+ GLenum source
+ GLenum type
+ GLenum severity
+ GLsizei count
+ const GLuint *ids
+ GLboolean enabled
+
+
+
+ void glDebugMessageEnableAMD
+ GLenum category
+ GLenum severity
+ GLsizei count
+ const GLuint *ids
+ GLboolean enabled
+
+
+ void glDebugMessageInsert
+ GLenum source
+ GLenum type
+ GLuint id
+ GLenum severity
+ GLsizei length
+ const GLchar *buf
+
+
+ void glDebugMessageInsertAMD
+ GLenum category
+ GLenum severity
+ GLuint id
+ GLsizei length
+ const GLchar *buf
+
+
+ void glDebugMessageInsertARB
+ GLenum source
+ GLenum type
+ GLuint id
+ GLenum severity
+ GLsizei length
+ const GLchar *buf
+
+
+
+ void glDebugMessageInsertKHR
+ GLenum source
+ GLenum type
+ GLuint id
+ GLenum severity
+ GLsizei length
+ const GLchar *buf
+
+
+
+ void glDeformSGIX
+ GLbitfield mask
+
+
+
+ void glDeformationMap3dSGIX
+ GLenum target
+ GLdouble u1
+ GLdouble u2
+ GLint ustride
+ GLint uorder
+ GLdouble v1
+ GLdouble v2
+ GLint vstride
+ GLint vorder
+ GLdouble w1
+ GLdouble w2
+ GLint wstride
+ GLint worder
+ const GLdouble *points
+
+
+
+ void glDeformationMap3fSGIX
+ GLenum target
+ GLfloat u1
+ GLfloat u2
+ GLint ustride
+ GLint uorder
+ GLfloat v1
+ GLfloat v2
+ GLint vstride
+ GLint vorder
+ GLfloat w1
+ GLfloat w2
+ GLint wstride
+ GLint worder
+ const GLfloat *points
+
+
+
+ void glDeleteAsyncMarkersSGIX
+ GLuint marker
+ GLsizei range
+
+
+ void glDeleteBuffers
+ GLsizei n
+ const GLuint *buffers
+
+
+ void glDeleteBuffersARB
+ GLsizei n
+ const GLuint *buffers
+
+
+
+ void glDeleteCommandListsNV
+ GLsizei n
+ const GLuint *lists
+
+
+ void glDeleteStatesNV
+ GLsizei n
+ const GLuint *states
+
+
+ void glDeleteFencesAPPLE
+ GLsizei n
+ const GLuint *fences
+
+
+ void glDeleteFencesNV
+ GLsizei n
+ const GLuint *fences
+
+
+
+ void glDeleteFragmentShaderATI
+ GLuint id
+
+
+ void glDeleteFramebuffers
+ GLsizei n
+ const GLuint *framebuffers
+
+
+
+ void glDeleteFramebuffersEXT
+ GLsizei n
+ const GLuint *framebuffers
+
+
+
+
+ void glDeleteFramebuffersOES
+ GLsizei n
+ const GLuint *framebuffers
+
+
+ void glDeleteLists
+ GLuint list
+ GLsizei range
+
+
+
+ void glDeleteNamedStringARB
+ GLint namelen
+ const GLchar *name
+
+
+ void glDeleteNamesAMD
+ GLenum identifier
+ GLuint num
+ const GLuint *names
+
+
+ void glDeleteObjectARB
+ GLhandleARB obj
+
+
+ void glDeleteOcclusionQueriesNV
+ GLsizei n
+ const GLuint *ids
+
+
+ void glDeletePathsNV
+ GLuint path
+ GLsizei range
+
+
+ void glDeletePerfMonitorsAMD
+ GLsizei n
+ GLuint *monitors
+
+
+ void glDeletePerfQueryINTEL
+ GLuint queryHandle
+
+
+ void glDeleteProgram
+ GLuint program
+
+
+
+ void glDeleteProgramPipelines
+ GLsizei n
+ const GLuint *pipelines
+
+
+ void glDeleteProgramPipelinesEXT
+ GLsizei n
+ const GLuint *pipelines
+
+
+ void glDeleteProgramsARB
+ GLsizei n
+ const GLuint *programs
+
+
+
+ void glDeleteProgramsNV
+ GLsizei n
+ const GLuint *programs
+
+
+
+
+ void glDeleteQueries
+ GLsizei n
+ const GLuint *ids
+
+
+
+ void glDeleteQueriesARB
+ GLsizei n
+ const GLuint *ids
+
+
+
+ void glDeleteQueriesEXT
+ GLsizei n
+ const GLuint *ids
+
+
+ void glDeleteRenderbuffers
+ GLsizei n
+ const GLuint *renderbuffers
+
+
+
+ void glDeleteRenderbuffersEXT
+ GLsizei n
+ const GLuint *renderbuffers
+
+
+
+
+ void glDeleteRenderbuffersOES
+ GLsizei n
+ const GLuint *renderbuffers
+
+
+ void glDeleteSamplers
+ GLsizei count
+ const GLuint *samplers
+
+
+ void glDeleteShader
+ GLuint shader
+
+
+
+ void glDeleteSync
+ GLsync sync
+
+
+ void glDeleteSyncAPPLE
+ GLsync sync
+
+
+
+ void glDeleteTextures
+ GLsizei n
+ const GLuint *textures
+
+
+
+ void glDeleteTexturesEXT
+ GLsizei n
+ const GLuint *textures
+
+
+
+ void glDeleteTransformFeedbacks
+ GLsizei n
+ const GLuint *ids
+
+
+ void glDeleteTransformFeedbacksNV
+ GLsizei n
+ const GLuint *ids
+
+
+
+ void glDeleteVertexArrays
+ GLsizei n
+ const GLuint *arrays
+
+
+
+ void glDeleteVertexArraysAPPLE
+ GLsizei n
+ const GLuint *arrays
+
+
+
+ void glDeleteVertexArraysOES
+ GLsizei n
+ const GLuint *arrays
+
+
+
+ void glDeleteVertexShaderEXT
+ GLuint id
+
+
+ void glDepthBoundsEXT
+ GLclampd zmin
+ GLclampd zmax
+
+
+
+ void glDepthBoundsdNV
+ GLdouble zmin
+ GLdouble zmax
+
+
+
+ void glDepthFunc
+ GLenum func
+
+
+
+ void glDepthMask
+ GLboolean flag
+
+
+
+ void glDepthRange
+ GLdouble near
+ GLdouble far
+
+
+
+ void glDepthRangeArrayv
+ GLuint first
+ GLsizei count
+ const GLdouble *v
+
+
+ void glDepthRangeArrayfvNV
+ GLuint first
+ GLsizei count
+ const GLfloat *v
+
+
+ void glDepthRangeIndexed
+ GLuint index
+ GLdouble n
+ GLdouble f
+
+
+ void glDepthRangeIndexedfNV
+ GLuint index
+ GLfloat n
+ GLfloat f
+
+
+ void glDepthRangedNV
+ GLdouble zNear
+ GLdouble zFar
+
+
+
+ void glDepthRangef
+ GLfloat n
+ GLfloat f
+
+
+ void glDepthRangefOES
+ GLclampf n
+ GLclampf f
+
+
+
+
+ void glDepthRangex
+ GLfixed n
+ GLfixed f
+
+
+ void glDepthRangexOES
+ GLfixed n
+ GLfixed f
+
+
+ void glDetachObjectARB
+ GLhandleARB containerObj
+ GLhandleARB attachedObj
+
+
+
+ void glDetachShader
+ GLuint program
+ GLuint shader
+
+
+ void glDetailTexFuncSGIS
+ GLenum target
+ GLsizei n
+ const GLfloat *points
+
+
+
+ void glDisable
+ GLenum cap
+
+
+
+ void glDisableClientState
+ GLenum array
+
+
+ void glDisableClientStateIndexedEXT
+ GLenum array
+ GLuint index
+
+
+ void glDisableClientStateiEXT
+ GLenum array
+ GLuint index
+
+
+ void glDisableDriverControlQCOM
+ GLuint driverControl
+
+
+ void glDisableIndexedEXT
+ GLenum target
+ GLuint index
+
+
+
+ void glDisableVariantClientStateEXT
+ GLuint id
+
+
+ void glDisableVertexArrayAttrib
+ GLuint vaobj
+ GLuint index
+
+
+ void glDisableVertexArrayAttribEXT
+ GLuint vaobj
+ GLuint index
+
+
+ void glDisableVertexArrayEXT
+ GLuint vaobj
+ GLenum array
+
+
+ void glDisableVertexAttribAPPLE
+ GLuint index
+ GLenum pname
+
+
+ void glDisableVertexAttribArray
+ GLuint index
+
+
+ void glDisableVertexAttribArrayARB
+ GLuint index
+
+
+
+ void glDisablei
+ GLenum target
+ GLuint index
+
+
+ void glDisableiEXT
+ GLenum target
+ GLuint index
+
+
+
+ void glDisableiNV
+ GLenum target
+ GLuint index
+
+
+
+ void glDisableiOES
+ GLenum target
+ GLuint index
+
+
+
+ void glDiscardFramebufferEXT
+ GLenum target
+ GLsizei numAttachments
+ const GLenum *attachments
+
+
+ void glDispatchCompute
+ GLuint num_groups_x
+ GLuint num_groups_y
+ GLuint num_groups_z
+
+
+ void glDispatchComputeGroupSizeARB
+ GLuint num_groups_x
+ GLuint num_groups_y
+ GLuint num_groups_z
+ GLuint group_size_x
+ GLuint group_size_y
+ GLuint group_size_z
+
+
+ void glDispatchComputeIndirect
+ GLintptr indirect
+
+
+ void glDrawArrays
+ GLenum mode
+ GLint first
+ GLsizei count
+
+
+
+ void glDrawArraysEXT
+ GLenum mode
+ GLint first
+ GLsizei count
+
+
+
+
+ void glDrawArraysIndirect
+ GLenum mode
+ const void *indirect
+
+
+ void glDrawArraysInstanced
+ GLenum mode
+ GLint first
+ GLsizei count
+ GLsizei instancecount
+
+
+ void glDrawArraysInstancedANGLE
+ GLenum mode
+ GLint first
+ GLsizei count
+ GLsizei primcount
+
+
+
+ void glDrawArraysInstancedARB
+ GLenum mode
+ GLint first
+ GLsizei count
+ GLsizei primcount
+
+
+
+ void glDrawArraysInstancedBaseInstance
+ GLenum mode
+ GLint first
+ GLsizei count
+ GLsizei instancecount
+ GLuint baseinstance
+
+
+ void glDrawArraysInstancedBaseInstanceEXT
+ GLenum mode
+ GLint first
+ GLsizei count
+ GLsizei instancecount
+ GLuint baseinstance
+
+
+
+ void glDrawArraysInstancedEXT
+ GLenum mode
+ GLint start
+ GLsizei count
+ GLsizei primcount
+
+
+
+ void glDrawArraysInstancedNV
+ GLenum mode
+ GLint first
+ GLsizei count
+ GLsizei primcount
+
+
+
+ void glDrawBuffer
+ GLenum buf
+
+
+
+ void glDrawBuffers
+ GLsizei n
+ const GLenum *bufs
+
+
+
+ void glDrawBuffersARB
+ GLsizei n
+ const GLenum *bufs
+
+
+
+ void glDrawBuffersATI
+ GLsizei n
+ const GLenum *bufs
+
+
+
+
+ void glDrawBuffersEXT
+ GLsizei n
+ const GLenum *bufs
+
+
+
+ void glDrawBuffersIndexedEXT
+ GLint n
+ const GLenum *location
+ const GLint *indices
+
+
+ void glDrawBuffersNV
+ GLsizei n
+ const GLenum *bufs
+
+
+ void glDrawCommandsNV
+ GLenum primitiveMode
+ GLuint buffer
+ const GLintptr *indirects
+ const GLsizei *sizes
+ GLuint count
+
+
+ void glDrawCommandsAddressNV
+ GLenum primitiveMode
+ const GLuint64 *indirects
+ const GLsizei *sizes
+ GLuint count
+
+
+ void glDrawCommandsStatesNV
+ GLuint buffer
+ const GLintptr *indirects
+ const GLsizei *sizes
+ const GLuint *states
+ const GLuint *fbos
+ GLuint count
+
+
+ void glDrawCommandsStatesAddressNV
+ const GLuint64 *indirects
+ const GLsizei *sizes
+ const GLuint *states
+ const GLuint *fbos
+ GLuint count
+
+
+ void glDrawElementArrayAPPLE
+ GLenum mode
+ GLint first
+ GLsizei count
+
+
+ void glDrawElementArrayATI
+ GLenum mode
+ GLsizei count
+
+
+ void glDrawElements
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+
+
+ void glDrawElementsBaseVertex
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLint basevertex
+
+
+ void glDrawElementsBaseVertexEXT
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLint basevertex
+
+
+
+ void glDrawElementsBaseVertexOES
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLint basevertex
+
+
+
+ void glDrawElementsIndirect
+ GLenum mode
+ GLenum type
+ const void *indirect
+
+
+ void glDrawElementsInstanced
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei instancecount
+
+
+ void glDrawElementsInstancedANGLE
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei primcount
+
+
+
+ void glDrawElementsInstancedARB
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei primcount
+
+
+
+ void glDrawElementsInstancedBaseInstance
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei instancecount
+ GLuint baseinstance
+
+
+ void glDrawElementsInstancedBaseInstanceEXT
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei instancecount
+ GLuint baseinstance
+
+
+
+ void glDrawElementsInstancedBaseVertex
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei instancecount
+ GLint basevertex
+
+
+ void glDrawElementsInstancedBaseVertexEXT
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei instancecount
+ GLint basevertex
+
+
+
+ void glDrawElementsInstancedBaseVertexOES
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei instancecount
+ GLint basevertex
+
+
+
+ void glDrawElementsInstancedBaseVertexBaseInstance
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei instancecount
+ GLint basevertex
+ GLuint baseinstance
+
+
+ void glDrawElementsInstancedBaseVertexBaseInstanceEXT
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei instancecount
+ GLint basevertex
+ GLuint baseinstance
+
+
+
+ void glDrawElementsInstancedEXT
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei primcount
+
+
+
+ void glDrawElementsInstancedNV
+ GLenum mode
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLsizei primcount
+
+
+
+ void glDrawMeshArraysSUN
+ GLenum mode
+ GLint first
+ GLsizei count
+ GLsizei width
+
+
+ void glDrawPixels
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glDrawRangeElementArrayAPPLE
+ GLenum mode
+ GLuint start
+ GLuint end
+ GLint first
+ GLsizei count
+
+
+ void glDrawRangeElementArrayATI
+ GLenum mode
+ GLuint start
+ GLuint end
+ GLsizei count
+
+
+ void glDrawRangeElements
+ GLenum mode
+ GLuint start
+ GLuint end
+ GLsizei count
+ GLenum type
+ const void *indices
+
+
+ void glDrawRangeElementsBaseVertex
+ GLenum mode
+ GLuint start
+ GLuint end
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLint basevertex
+
+
+ void glDrawRangeElementsBaseVertexEXT
+ GLenum mode
+ GLuint start
+ GLuint end
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLint basevertex
+
+
+
+ void glDrawRangeElementsBaseVertexOES
+ GLenum mode
+ GLuint start
+ GLuint end
+ GLsizei count
+ GLenum type
+ const void *indices
+ GLint basevertex
+
+
+
+ void glDrawRangeElementsEXT
+ GLenum mode
+ GLuint start
+ GLuint end
+ GLsizei count
+ GLenum type
+ const void *indices
+
+
+
+ void glDrawTexfOES
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat width
+ GLfloat height
+
+
+ void glDrawTexfvOES
+ const GLfloat *coords
+
+
+ void glDrawTexiOES
+ GLint x
+ GLint y
+ GLint z
+ GLint width
+ GLint height
+
+
+ void glDrawTexivOES
+ const GLint *coords
+
+
+ void glDrawTexsOES
+ GLshort x
+ GLshort y
+ GLshort z
+ GLshort width
+ GLshort height
+
+
+ void glDrawTexsvOES
+ const GLshort *coords
+
+
+ void glDrawTextureNV
+ GLuint texture
+ GLuint sampler
+ GLfloat x0
+ GLfloat y0
+ GLfloat x1
+ GLfloat y1
+ GLfloat z
+ GLfloat s0
+ GLfloat t0
+ GLfloat s1
+ GLfloat t1
+
+
+ void glDrawTexxOES
+ GLfixed x
+ GLfixed y
+ GLfixed z
+ GLfixed width
+ GLfixed height
+
+
+ void glDrawTexxvOES
+ const GLfixed *coords
+
+
+ void glDrawTransformFeedback
+ GLenum mode
+ GLuint id
+
+
+ void glDrawTransformFeedbackInstanced
+ GLenum mode
+ GLuint id
+ GLsizei instancecount
+
+
+ void glDrawTransformFeedbackNV
+ GLenum mode
+ GLuint id
+
+
+
+ void glDrawTransformFeedbackStream
+ GLenum mode
+ GLuint id
+ GLuint stream
+
+
+ void glDrawTransformFeedbackStreamInstanced
+ GLenum mode
+ GLuint id
+ GLuint stream
+ GLsizei instancecount
+
+
+ void glEGLImageTargetRenderbufferStorageOES
+ GLenum target
+ GLeglImageOES image
+
+
+ void glEGLImageTargetTexture2DOES
+ GLenum target
+ GLeglImageOES image
+
+
+ void glEdgeFlag
+ GLboolean flag
+
+
+
+ void glEdgeFlagFormatNV
+ GLsizei stride
+
+
+ void glEdgeFlagPointer
+ GLsizei stride
+ const void *pointer
+
+
+ void glEdgeFlagPointerEXT
+ GLsizei stride
+ GLsizei count
+ const GLboolean *pointer
+
+
+ void glEdgeFlagPointerListIBM
+ GLint stride
+ const GLboolean **pointer
+ GLint ptrstride
+
+
+ void glEdgeFlagv
+ const GLboolean *flag
+
+
+
+ void glElementPointerAPPLE
+ GLenum type
+ const void *pointer
+
+
+ void glElementPointerATI
+ GLenum type
+ const void *pointer
+
+
+ void glEnable
+ GLenum cap
+
+
+
+ void glEnableClientState
+ GLenum array
+
+
+ void glEnableClientStateIndexedEXT
+ GLenum array
+ GLuint index
+
+
+ void glEnableClientStateiEXT
+ GLenum array
+ GLuint index
+
+
+ void glEnableDriverControlQCOM
+ GLuint driverControl
+
+
+ void glEnableIndexedEXT
+ GLenum target
+ GLuint index
+
+
+
+ void glEnableVariantClientStateEXT
+ GLuint id
+
+
+ void glEnableVertexArrayAttrib
+ GLuint vaobj
+ GLuint index
+
+
+ void glEnableVertexArrayAttribEXT
+ GLuint vaobj
+ GLuint index
+
+
+ void glEnableVertexArrayEXT
+ GLuint vaobj
+ GLenum array
+
+
+ void glEnableVertexAttribAPPLE
+ GLuint index
+ GLenum pname
+
+
+ void glEnableVertexAttribArray
+ GLuint index
+
+
+ void glEnableVertexAttribArrayARB
+ GLuint index
+
+
+
+ void glEnablei
+ GLenum target
+ GLuint index
+
+
+ void glEnableiEXT
+ GLenum target
+ GLuint index
+
+
+
+ void glEnableiNV
+ GLenum target
+ GLuint index
+
+
+
+ void glEnableiOES
+ GLenum target
+ GLuint index
+
+
+
+ void glEnd
+
+
+
+ void glEndConditionalRender
+
+
+
+ void glEndConditionalRenderNV
+
+
+
+ void glEndConditionalRenderNVX
+
+
+
+ void glEndFragmentShaderATI
+
+
+ void glEndList
+
+
+
+ void glEndOcclusionQueryNV
+
+
+ void glEndPerfMonitorAMD
+ GLuint monitor
+
+
+ void glEndPerfQueryINTEL
+ GLuint queryHandle
+
+
+ void glEndQuery
+ GLenum target
+
+
+
+ void glEndQueryARB
+ GLenum target
+
+
+
+ void glEndQueryEXT
+ GLenum target
+
+
+ void glEndQueryIndexed
+ GLenum target
+ GLuint index
+
+
+ void glEndTilingQCOM
+ GLbitfield preserveMask
+
+
+ void glEndTransformFeedback
+
+
+ void glEndTransformFeedbackEXT
+
+
+
+ void glEndTransformFeedbackNV
+
+
+
+ void glEndVertexShaderEXT
+
+
+ void glEndVideoCaptureNV
+ GLuint video_capture_slot
+
+
+ void glEvalCoord1d
+ GLdouble u
+
+
+
+ void glEvalCoord1dv
+ const GLdouble *u
+
+
+
+ void glEvalCoord1f
+ GLfloat u
+
+
+
+ void glEvalCoord1fv
+ const GLfloat *u
+
+
+
+ void glEvalCoord1xOES
+ GLfixed u
+
+
+ void glEvalCoord1xvOES
+ const GLfixed *coords
+
+
+ void glEvalCoord2d
+ GLdouble u
+ GLdouble v
+
+
+
+ void glEvalCoord2dv
+ const GLdouble *u
+
+
+
+ void glEvalCoord2f
+ GLfloat u
+ GLfloat v
+
+
+
+ void glEvalCoord2fv
+ const GLfloat *u
+
+
+
+ void glEvalCoord2xOES
+ GLfixed u
+ GLfixed v
+
+
+ void glEvalCoord2xvOES
+ const GLfixed *coords
+
+
+ void glEvalMapsNV
+ GLenum target
+ GLenum mode
+
+
+ void glEvalMesh1
+ GLenum mode
+ GLint i1
+ GLint i2
+
+
+
+ void glEvalMesh2
+ GLenum mode
+ GLint i1
+ GLint i2
+ GLint j1
+ GLint j2
+
+
+
+ void glEvalPoint1
+ GLint i
+
+
+
+ void glEvalPoint2
+ GLint i
+ GLint j
+
+
+
+ void glExecuteProgramNV
+ GLenum target
+ GLuint id
+ const GLfloat *params
+
+
+
+ void glExtGetBufferPointervQCOM
+ GLenum target
+ void **params
+
+
+ void glExtGetBuffersQCOM
+ GLuint *buffers
+ GLint maxBuffers
+ GLint *numBuffers
+
+
+ void glExtGetFramebuffersQCOM
+ GLuint *framebuffers
+ GLint maxFramebuffers
+ GLint *numFramebuffers
+
+
+ void glExtGetProgramBinarySourceQCOM
+ GLuint program
+ GLenum shadertype
+ GLchar *source
+ GLint *length
+
+
+ void glExtGetProgramsQCOM
+ GLuint *programs
+ GLint maxPrograms
+ GLint *numPrograms
+
+
+ void glExtGetRenderbuffersQCOM
+ GLuint *renderbuffers
+ GLint maxRenderbuffers
+ GLint *numRenderbuffers
+
+
+ void glExtGetShadersQCOM
+ GLuint *shaders
+ GLint maxShaders
+ GLint *numShaders
+
+
+ void glExtGetTexLevelParameterivQCOM
+ GLuint texture
+ GLenum face
+ GLint level
+ GLenum pname
+ GLint *params
+
+
+ void glExtGetTexSubImageQCOM
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLenum type
+ void *texels
+
+
+ void glExtGetTexturesQCOM
+ GLuint *textures
+ GLint maxTextures
+ GLint *numTextures
+
+
+ GLboolean glExtIsProgramBinaryQCOM
+ GLuint program
+
+
+ void glExtTexObjectStateOverrideiQCOM
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+ void glExtractComponentEXT
+ GLuint res
+ GLuint src
+ GLuint num
+
+
+ void glFeedbackBuffer
+ GLsizei size
+ GLenum type
+ GLfloat *buffer
+
+
+
+ void glFeedbackBufferxOES
+ GLsizei n
+ GLenum type
+ const GLfixed *buffer
+
+
+ GLsync glFenceSync
+ GLenum condition
+ GLbitfield flags
+
+
+ GLsync glFenceSyncAPPLE
+ GLenum condition
+ GLbitfield flags
+
+
+
+ void glFinalCombinerInputNV
+ GLenum variable
+ GLenum input
+ GLenum mapping
+ GLenum componentUsage
+
+
+
+ void glFinish
+
+
+
+ GLint glFinishAsyncSGIX
+ GLuint *markerp
+
+
+ void glFinishFenceAPPLE
+ GLuint fence
+
+
+ void glFinishFenceNV
+ GLuint fence
+
+
+
+ void glFinishObjectAPPLE
+ GLenum object
+ GLint name
+
+
+ void glFinishTextureSUNX
+
+
+ void glFlush
+
+
+
+ void glFlushMappedBufferRange
+ GLenum target
+ GLintptr offset
+ GLsizeiptr length
+
+
+ void glFlushMappedBufferRangeAPPLE
+ GLenum target
+ GLintptr offset
+ GLsizeiptr size
+
+
+
+ void glFlushMappedBufferRangeEXT
+ GLenum target
+ GLintptr offset
+ GLsizeiptr length
+
+
+
+ void glFlushMappedNamedBufferRange
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr length
+
+
+ void glFlushMappedNamedBufferRangeEXT
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr length
+
+
+ void glFlushPixelDataRangeNV
+ GLenum target
+
+
+ void glFlushRasterSGIX
+
+
+
+ void glFlushStaticDataIBM
+ GLenum target
+
+
+ void glFlushVertexArrayRangeAPPLE
+ GLsizei length
+ void *pointer
+
+
+ void glFlushVertexArrayRangeNV
+
+
+ void glFogCoordFormatNV
+ GLenum type
+ GLsizei stride
+
+
+ void glFogCoordPointer
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glFogCoordPointerEXT
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+
+ void glFogCoordPointerListIBM
+ GLenum type
+ GLint stride
+ const void **pointer
+ GLint ptrstride
+
+
+ void glFogCoordd
+ GLdouble coord
+
+
+
+ void glFogCoorddEXT
+ GLdouble coord
+
+
+
+
+ void glFogCoorddv
+ const GLdouble *coord
+
+
+
+ void glFogCoorddvEXT
+ const GLdouble *coord
+
+
+
+
+ void glFogCoordf
+ GLfloat coord
+
+
+
+ void glFogCoordfEXT
+ GLfloat coord
+
+
+
+
+ void glFogCoordfv
+ const GLfloat *coord
+
+
+
+ void glFogCoordfvEXT
+ const GLfloat *coord
+
+
+
+
+ void glFogCoordhNV
+ GLhalfNV fog
+
+
+
+ void glFogCoordhvNV
+ const GLhalfNV *fog
+
+
+
+ void glFogFuncSGIS
+ GLsizei n
+ const GLfloat *points
+
+
+
+ void glFogf
+ GLenum pname
+ GLfloat param
+
+
+
+ void glFogfv
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glFogi
+ GLenum pname
+ GLint param
+
+
+
+ void glFogiv
+ GLenum pname
+ const GLint *params
+
+
+
+ void glFogx
+ GLenum pname
+ GLfixed param
+
+
+ void glFogxOES
+ GLenum pname
+ GLfixed param
+
+
+ void glFogxv
+ GLenum pname
+ const GLfixed *param
+
+
+ void glFogxvOES
+ GLenum pname
+ const GLfixed *param
+
+
+ void glFragmentColorMaterialSGIX
+ GLenum face
+ GLenum mode
+
+
+ void glFragmentLightModelfSGIX
+ GLenum pname
+ GLfloat param
+
+
+ void glFragmentLightModelfvSGIX
+ GLenum pname
+ const GLfloat *params
+
+
+ void glFragmentLightModeliSGIX
+ GLenum pname
+ GLint param
+
+
+ void glFragmentLightModelivSGIX
+ GLenum pname
+ const GLint *params
+
+
+ void glFragmentLightfSGIX
+ GLenum light
+ GLenum pname
+ GLfloat param
+
+
+ void glFragmentLightfvSGIX
+ GLenum light
+ GLenum pname
+ const GLfloat *params
+
+
+ void glFragmentLightiSGIX
+ GLenum light
+ GLenum pname
+ GLint param
+
+
+ void glFragmentLightivSGIX
+ GLenum light
+ GLenum pname
+ const GLint *params
+
+
+ void glFragmentMaterialfSGIX
+ GLenum face
+ GLenum pname
+ GLfloat param
+
+
+ void glFragmentMaterialfvSGIX
+ GLenum face
+ GLenum pname
+ const GLfloat *params
+
+
+ void glFragmentMaterialiSGIX
+ GLenum face
+ GLenum pname
+ GLint param
+
+
+ void glFragmentMaterialivSGIX
+ GLenum face
+ GLenum pname
+ const GLint *params
+
+
+ void glFrameTerminatorGREMEDY
+
+
+ void glFrameZoomSGIX
+ GLint factor
+
+
+
+ void glFramebufferDrawBufferEXT
+ GLuint framebuffer
+ GLenum mode
+
+
+ void glFramebufferDrawBuffersEXT
+ GLuint framebuffer
+ GLsizei n
+ const GLenum *bufs
+
+
+ void glFramebufferParameteri
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+ void glFramebufferReadBufferEXT
+ GLuint framebuffer
+ GLenum mode
+
+
+ void glFramebufferRenderbuffer
+ GLenum target
+ GLenum attachment
+ GLenum renderbuffertarget
+ GLuint renderbuffer
+
+
+
+ void glFramebufferRenderbufferEXT
+ GLenum target
+ GLenum attachment
+ GLenum renderbuffertarget
+ GLuint renderbuffer
+
+
+
+
+ void glFramebufferRenderbufferOES
+ GLenum target
+ GLenum attachment
+ GLenum renderbuffertarget
+ GLuint renderbuffer
+
+
+ void glFramebufferTexture
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+
+
+ void glFramebufferTexture1D
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+
+
+
+ void glFramebufferTexture1DEXT
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+
+
+
+
+ void glFramebufferTexture2D
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+
+
+
+ void glFramebufferTexture2DEXT
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+
+
+
+
+ void glFramebufferTexture2DMultisampleEXT
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+ GLsizei samples
+
+
+ void glFramebufferTexture2DMultisampleIMG
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+ GLsizei samples
+
+
+ void glFramebufferTexture2DOES
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+
+
+ void glFramebufferTexture3D
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+ GLint zoffset
+
+
+
+ void glFramebufferTexture3DEXT
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+ GLint zoffset
+
+
+
+
+ void glFramebufferTexture3DOES
+ GLenum target
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+ GLint zoffset
+
+
+
+ void glFramebufferTextureARB
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+
+
+
+ void glFramebufferTextureEXT
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+
+
+
+ void glFramebufferTextureOES
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+
+
+
+ void glFramebufferTextureFaceARB
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+ GLenum face
+
+
+ void glFramebufferTextureFaceEXT
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+ GLenum face
+
+
+
+ void glFramebufferTextureLayer
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+ GLint layer
+
+
+
+ void glFramebufferTextureLayerARB
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+ GLint layer
+
+
+
+ void glFramebufferTextureLayerEXT
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+ GLint layer
+
+
+
+ void glFramebufferTextureMultiviewOVR
+ GLenum target
+ GLenum attachment
+ GLuint texture
+ GLint level
+ GLint baseViewIndex
+ GLsizei numViews
+
+
+ void glFreeObjectBufferATI
+ GLuint buffer
+
+
+ void glFrontFace
+ GLenum mode
+
+
+
+ void glFrustum
+ GLdouble left
+ GLdouble right
+ GLdouble bottom
+ GLdouble top
+ GLdouble zNear
+ GLdouble zFar
+
+
+
+ void glFrustumf
+ GLfloat l
+ GLfloat r
+ GLfloat b
+ GLfloat t
+ GLfloat n
+ GLfloat f
+
+
+ void glFrustumfOES
+ GLfloat l
+ GLfloat r
+ GLfloat b
+ GLfloat t
+ GLfloat n
+ GLfloat f
+
+
+
+ void glFrustumx
+ GLfixed l
+ GLfixed r
+ GLfixed b
+ GLfixed t
+ GLfixed n
+ GLfixed f
+
+
+ void glFrustumxOES
+ GLfixed l
+ GLfixed r
+ GLfixed b
+ GLfixed t
+ GLfixed n
+ GLfixed f
+
+
+ GLuint glGenAsyncMarkersSGIX
+ GLsizei range
+
+
+ void glGenBuffers
+ GLsizei n
+ GLuint *buffers
+
+
+ void glGenBuffersARB
+ GLsizei n
+ GLuint *buffers
+
+
+
+ void glGenFencesAPPLE
+ GLsizei n
+ GLuint *fences
+
+
+ void glGenFencesNV
+ GLsizei n
+ GLuint *fences
+
+
+
+ GLuint glGenFragmentShadersATI
+ GLuint range
+
+
+ void glGenFramebuffers
+ GLsizei n
+ GLuint *framebuffers
+
+
+
+ void glGenFramebuffersEXT
+ GLsizei n
+ GLuint *framebuffers
+
+
+
+
+ void glGenFramebuffersOES
+ GLsizei n
+ GLuint *framebuffers
+
+
+ GLuint glGenLists
+ GLsizei range
+
+
+
+ void glGenNamesAMD
+ GLenum identifier
+ GLuint num
+ GLuint *names
+
+
+ void glGenOcclusionQueriesNV
+ GLsizei n
+ GLuint *ids
+
+
+ GLuint glGenPathsNV
+ GLsizei range
+
+
+ void glGenPerfMonitorsAMD
+ GLsizei n
+ GLuint *monitors
+
+
+ void glGenProgramPipelines
+ GLsizei n
+ GLuint *pipelines
+
+
+ void glGenProgramPipelinesEXT
+ GLsizei n
+ GLuint *pipelines
+
+
+ void glGenProgramsARB
+ GLsizei n
+ GLuint *programs
+
+
+
+ void glGenProgramsNV
+ GLsizei n
+ GLuint *programs
+
+
+
+
+ void glGenQueries
+ GLsizei n
+ GLuint *ids
+
+
+
+ void glGenQueriesARB
+ GLsizei n
+ GLuint *ids
+
+
+
+ void glGenQueriesEXT
+ GLsizei n
+ GLuint *ids
+
+
+ void glGenRenderbuffers
+ GLsizei n
+ GLuint *renderbuffers
+
+
+
+ void glGenRenderbuffersEXT
+ GLsizei n
+ GLuint *renderbuffers
+
+
+
+
+ void glGenRenderbuffersOES
+ GLsizei n
+ GLuint *renderbuffers
+
+
+ void glGenSamplers
+ GLsizei count
+ GLuint *samplers
+
+
+ GLuint glGenSymbolsEXT
+ GLenum datatype
+ GLenum storagetype
+ GLenum range
+ GLuint components
+
+
+ void glGenTextures
+ GLsizei n
+ GLuint *textures
+
+
+
+ void glGenTexturesEXT
+ GLsizei n
+ GLuint *textures
+
+
+
+ void glGenTransformFeedbacks
+ GLsizei n
+ GLuint *ids
+
+
+ void glGenTransformFeedbacksNV
+ GLsizei n
+ GLuint *ids
+
+
+
+ void glGenVertexArrays
+ GLsizei n
+ GLuint *arrays
+
+
+
+ void glGenVertexArraysAPPLE
+ GLsizei n
+ GLuint *arrays
+
+
+
+ void glGenVertexArraysOES
+ GLsizei n
+ GLuint *arrays
+
+
+
+ GLuint glGenVertexShadersEXT
+ GLuint range
+
+
+ void glGenerateMipmap
+ GLenum target
+
+
+
+ void glGenerateMipmapEXT
+ GLenum target
+
+
+
+
+ void glGenerateMipmapOES
+ GLenum target
+
+
+ void glGenerateMultiTexMipmapEXT
+ GLenum texunit
+ GLenum target
+
+
+ void glGenerateTextureMipmap
+ GLuint texture
+
+
+ void glGenerateTextureMipmapEXT
+ GLuint texture
+ GLenum target
+
+
+ void glGetActiveAtomicCounterBufferiv
+ GLuint program
+ GLuint bufferIndex
+ GLenum pname
+ GLint *params
+
+
+ void glGetActiveAttrib
+ GLuint program
+ GLuint index
+ GLsizei bufSize
+ GLsizei *length
+ GLint *size
+ GLenum *type
+ GLchar *name
+
+
+ void glGetActiveAttribARB
+ GLhandleARB programObj
+ GLuint index
+ GLsizei maxLength
+ GLsizei *length
+ GLint *size
+ GLenum *type
+ GLcharARB *name
+
+
+
+ void glGetActiveSubroutineName
+ GLuint program
+ GLenum shadertype
+ GLuint index
+ GLsizei bufsize
+ GLsizei *length
+ GLchar *name
+
+
+ void glGetActiveSubroutineUniformName
+ GLuint program
+ GLenum shadertype
+ GLuint index
+ GLsizei bufsize
+ GLsizei *length
+ GLchar *name
+
+
+ void glGetActiveSubroutineUniformiv
+ GLuint program
+ GLenum shadertype
+ GLuint index
+ GLenum pname
+ GLint *values
+
+
+ void glGetActiveUniform
+ GLuint program
+ GLuint index
+ GLsizei bufSize
+ GLsizei *length
+ GLint *size
+ GLenum *type
+ GLchar *name
+
+
+ void glGetActiveUniformARB
+ GLhandleARB programObj
+ GLuint index
+ GLsizei maxLength
+ GLsizei *length
+ GLint *size
+ GLenum *type
+ GLcharARB *name
+
+
+
+ void glGetActiveUniformBlockName
+ GLuint program
+ GLuint uniformBlockIndex
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *uniformBlockName
+
+
+ void glGetActiveUniformBlockiv
+ GLuint program
+ GLuint uniformBlockIndex
+ GLenum pname
+ GLint *params
+
+
+ void glGetActiveUniformName
+ GLuint program
+ GLuint uniformIndex
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *uniformName
+
+
+ void glGetActiveUniformsiv
+ GLuint program
+ GLsizei uniformCount
+ const GLuint *uniformIndices
+ GLenum pname
+ GLint *params
+
+
+ void glGetActiveVaryingNV
+ GLuint program
+ GLuint index
+ GLsizei bufSize
+ GLsizei *length
+ GLsizei *size
+ GLenum *type
+ GLchar *name
+
+
+ void glGetArrayObjectfvATI
+ GLenum array
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetArrayObjectivATI
+ GLenum array
+ GLenum pname
+ GLint *params
+
+
+ void glGetAttachedObjectsARB
+ GLhandleARB containerObj
+ GLsizei maxCount
+ GLsizei *count
+ GLhandleARB *obj
+
+
+ void glGetAttachedShaders
+ GLuint program
+ GLsizei maxCount
+ GLsizei *count
+ GLuint *shaders
+
+
+ GLint glGetAttribLocation
+ GLuint program
+ const GLchar *name
+
+
+ GLint glGetAttribLocationARB
+ GLhandleARB programObj
+ const GLcharARB *name
+
+
+
+ void glGetBooleanIndexedvEXT
+ GLenum target
+ GLuint index
+ GLboolean *data
+
+
+
+ void glGetBooleani_v
+ GLenum target
+ GLuint index
+ GLboolean *data
+
+
+ void glGetBooleanv
+ GLenum pname
+ GLboolean *data
+
+
+
+ void glGetBufferParameteri64v
+ GLenum target
+ GLenum pname
+ GLint64 *params
+
+
+ void glGetBufferParameteriv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetBufferParameterivARB
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetBufferParameterui64vNV
+ GLenum target
+ GLenum pname
+ GLuint64EXT *params
+
+
+ void glGetBufferPointerv
+ GLenum target
+ GLenum pname
+ void **params
+
+
+ void glGetBufferPointervARB
+ GLenum target
+ GLenum pname
+ void **params
+
+
+
+ void glGetBufferPointervOES
+ GLenum target
+ GLenum pname
+ void **params
+
+
+
+ void glGetBufferSubData
+ GLenum target
+ GLintptr offset
+ GLsizeiptr size
+ void *data
+
+
+ void glGetBufferSubDataARB
+ GLenum target
+ GLintptrARB offset
+ GLsizeiptrARB size
+ void *data
+
+
+
+ void glGetClipPlane
+ GLenum plane
+ GLdouble *equation
+
+
+
+ void glGetClipPlanef
+ GLenum plane
+ GLfloat *equation
+
+
+ void glGetClipPlanefOES
+ GLenum plane
+ GLfloat *equation
+
+
+
+ void glGetClipPlanex
+ GLenum plane
+ GLfixed *equation
+
+
+ void glGetClipPlanexOES
+ GLenum plane
+ GLfixed *equation
+
+
+ void glGetColorTable
+ GLenum target
+ GLenum format
+ GLenum type
+ void *table
+
+
+
+
+ void glGetColorTableEXT
+ GLenum target
+ GLenum format
+ GLenum type
+ void *data
+
+
+
+ void glGetColorTableParameterfv
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetColorTableParameterfvEXT
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetColorTableParameterfvSGI
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetColorTableParameteriv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetColorTableParameterivEXT
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetColorTableParameterivSGI
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetColorTableSGI
+ GLenum target
+ GLenum format
+ GLenum type
+ void *table
+
+
+
+ void glGetCombinerInputParameterfvNV
+ GLenum stage
+ GLenum portion
+ GLenum variable
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetCombinerInputParameterivNV
+ GLenum stage
+ GLenum portion
+ GLenum variable
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetCombinerOutputParameterfvNV
+ GLenum stage
+ GLenum portion
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetCombinerOutputParameterivNV
+ GLenum stage
+ GLenum portion
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetCombinerStageParameterfvNV
+ GLenum stage
+ GLenum pname
+ GLfloat *params
+
+
+ GLuint glGetCommandHeaderNV
+ GLenum tokenID
+ GLuint size
+
+
+ void glGetCompressedMultiTexImageEXT
+ GLenum texunit
+ GLenum target
+ GLint lod
+ void *img
+
+
+ void glGetCompressedTexImage
+ GLenum target
+ GLint level
+ void *img
+
+
+
+
+ void glGetCompressedTexImageARB
+ GLenum target
+ GLint level
+ void *img
+
+
+
+
+ void glGetCompressedTextureImage
+ GLuint texture
+ GLint level
+ GLsizei bufSize
+ void *pixels
+
+
+ void glGetCompressedTextureImageEXT
+ GLuint texture
+ GLenum target
+ GLint lod
+ void *img
+
+
+ void glGetCompressedTextureSubImage
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLsizei bufSize
+ void *pixels
+
+
+ void glGetConvolutionFilter
+ GLenum target
+ GLenum format
+ GLenum type
+ void *image
+
+
+
+
+ void glGetConvolutionFilterEXT
+ GLenum target
+ GLenum format
+ GLenum type
+ void *image
+
+
+
+ void glGetConvolutionParameterfv
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetConvolutionParameterfvEXT
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetConvolutionParameteriv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetConvolutionParameterivEXT
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetConvolutionParameterxvOES
+ GLenum target
+ GLenum pname
+ GLfixed *params
+
+
+ GLuint glGetDebugMessageLog
+ GLuint count
+ GLsizei bufSize
+ GLenum *sources
+ GLenum *types
+ GLuint *ids
+ GLenum *severities
+ GLsizei *lengths
+ GLchar *messageLog
+
+
+ GLuint glGetDebugMessageLogAMD
+ GLuint count
+ GLsizei bufsize
+ GLenum *categories
+ GLuint *severities
+ GLuint *ids
+ GLsizei *lengths
+ GLchar *message
+
+
+ GLuint glGetDebugMessageLogARB
+ GLuint count
+ GLsizei bufSize
+ GLenum *sources
+ GLenum *types
+ GLuint *ids
+ GLenum *severities
+ GLsizei *lengths
+ GLchar *messageLog
+
+
+
+ GLuint glGetDebugMessageLogKHR
+ GLuint count
+ GLsizei bufSize
+ GLenum *sources
+ GLenum *types
+ GLuint *ids
+ GLenum *severities
+ GLsizei *lengths
+ GLchar *messageLog
+
+
+
+ void glGetDetailTexFuncSGIS
+ GLenum target
+ GLfloat *points
+
+
+
+ void glGetDoubleIndexedvEXT
+ GLenum target
+ GLuint index
+ GLdouble *data
+
+
+
+ void glGetDoublei_v
+ GLenum target
+ GLuint index
+ GLdouble *data
+
+
+ void glGetDoublei_vEXT
+ GLenum pname
+ GLuint index
+ GLdouble *params
+
+
+
+ void glGetDoublev
+ GLenum pname
+ GLdouble *data
+
+
+
+ void glGetDriverControlStringQCOM
+ GLuint driverControl
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *driverControlString
+
+
+ void glGetDriverControlsQCOM
+ GLint *num
+ GLsizei size
+ GLuint *driverControls
+
+
+ GLenum glGetError
+
+
+
+ void glGetFenceivNV
+ GLuint fence
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetFinalCombinerInputParameterfvNV
+ GLenum variable
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetFinalCombinerInputParameterivNV
+ GLenum variable
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetFirstPerfQueryIdINTEL
+ GLuint *queryId
+
+
+ void glGetFixedv
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetFixedvOES
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetFloatIndexedvEXT
+ GLenum target
+ GLuint index
+ GLfloat *data
+
+
+
+ void glGetFloati_v
+ GLenum target
+ GLuint index
+ GLfloat *data
+
+
+ void glGetFloati_vNV
+ GLenum target
+ GLuint index
+ GLfloat *data
+
+
+
+ void glGetFloati_vEXT
+ GLenum pname
+ GLuint index
+ GLfloat *params
+
+
+
+ void glGetFloatv
+ GLenum pname
+ GLfloat *data
+
+
+
+ void glGetFogFuncSGIS
+ GLfloat *points
+
+
+ GLint glGetFragDataIndex
+ GLuint program
+ const GLchar *name
+
+
+ GLint glGetFragDataLocation
+ GLuint program
+ const GLchar *name
+
+
+ GLint glGetFragDataLocationEXT
+ GLuint program
+ const GLchar *name
+
+
+
+ void glGetFragmentLightfvSGIX
+ GLenum light
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetFragmentLightivSGIX
+ GLenum light
+ GLenum pname
+ GLint *params
+
+
+ void glGetFragmentMaterialfvSGIX
+ GLenum face
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetFragmentMaterialivSGIX
+ GLenum face
+ GLenum pname
+ GLint *params
+
+
+ void glGetFramebufferAttachmentParameteriv
+ GLenum target
+ GLenum attachment
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetFramebufferAttachmentParameterivEXT
+ GLenum target
+ GLenum attachment
+ GLenum pname
+ GLint *params
+
+
+
+
+ void glGetFramebufferAttachmentParameterivOES
+ GLenum target
+ GLenum attachment
+ GLenum pname
+ GLint *params
+
+
+ void glGetFramebufferParameteriv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetFramebufferParameterivEXT
+ GLuint framebuffer
+ GLenum pname
+ GLint *params
+
+
+ GLenum glGetGraphicsResetStatus
+
+
+ GLenum glGetGraphicsResetStatusARB
+
+
+ GLenum glGetGraphicsResetStatusEXT
+
+
+ GLenum glGetGraphicsResetStatusKHR
+
+
+
+ GLhandleARB glGetHandleARB
+ GLenum pname
+
+
+ void glGetHistogram
+ GLenum target
+ GLboolean reset
+ GLenum format
+ GLenum type
+ void *values
+
+
+
+
+ void glGetHistogramEXT
+ GLenum target
+ GLboolean reset
+ GLenum format
+ GLenum type
+ void *values
+
+
+
+ void glGetHistogramParameterfv
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetHistogramParameterfvEXT
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetHistogramParameteriv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetHistogramParameterivEXT
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetHistogramParameterxvOES
+ GLenum target
+ GLenum pname
+ GLfixed *params
+
+
+ GLuint64 glGetImageHandleARB
+ GLuint texture
+ GLint level
+ GLboolean layered
+ GLint layer
+ GLenum format
+
+
+ GLuint64 glGetImageHandleNV
+ GLuint texture
+ GLint level
+ GLboolean layered
+ GLint layer
+ GLenum format
+
+
+ void glGetImageTransformParameterfvHP
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetImageTransformParameterivHP
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetInfoLogARB
+ GLhandleARB obj
+ GLsizei maxLength
+ GLsizei *length
+ GLcharARB *infoLog
+
+
+ GLint glGetInstrumentsSGIX
+
+
+
+ void glGetInteger64i_v
+ GLenum target
+ GLuint index
+ GLint64 *data
+
+
+ void glGetInteger64v
+ GLenum pname
+ GLint64 *data
+
+
+ void glGetInteger64vAPPLE
+ GLenum pname
+ GLint64 *params
+
+
+
+ void glGetIntegerIndexedvEXT
+ GLenum target
+ GLuint index
+ GLint *data
+
+
+
+ void glGetIntegeri_v
+ GLenum target
+ GLuint index
+ GLint *data
+
+
+ void glGetIntegeri_vEXT
+ GLenum target
+ GLuint index
+ GLint *data
+
+
+ void glGetIntegerui64i_vNV
+ GLenum value
+ GLuint index
+ GLuint64EXT *result
+
+
+ void glGetIntegerui64vNV
+ GLenum value
+ GLuint64EXT *result
+
+
+ void glGetIntegerv
+ GLenum pname
+ GLint *data
+
+
+
+ void glGetInternalformati64v
+ GLenum target
+ GLenum internalformat
+ GLenum pname
+ GLsizei bufSize
+ GLint64 *params
+
+
+ void glGetInternalformativ
+ GLenum target
+ GLenum internalformat
+ GLenum pname
+ GLsizei bufSize
+ GLint *params
+
+
+ void glGetInternalformatSampleivNV
+ GLenum target
+ GLenum internalformat
+ GLsizei samples
+ GLenum pname
+ GLsizei bufSize
+ GLint *params
+
+
+ void glGetInvariantBooleanvEXT
+ GLuint id
+ GLenum value
+ GLboolean *data
+
+
+ void glGetInvariantFloatvEXT
+ GLuint id
+ GLenum value
+ GLfloat *data
+
+
+ void glGetInvariantIntegervEXT
+ GLuint id
+ GLenum value
+ GLint *data
+
+
+ void glGetLightfv
+ GLenum light
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetLightiv
+ GLenum light
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetLightxOES
+ GLenum light
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetLightxv
+ GLenum light
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetLightxvOES
+ GLenum light
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetListParameterfvSGIX
+ GLuint list
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetListParameterivSGIX
+ GLuint list
+ GLenum pname
+ GLint *params
+
+
+ void glGetLocalConstantBooleanvEXT
+ GLuint id
+ GLenum value
+ GLboolean *data
+
+
+ void glGetLocalConstantFloatvEXT
+ GLuint id
+ GLenum value
+ GLfloat *data
+
+
+ void glGetLocalConstantIntegervEXT
+ GLuint id
+ GLenum value
+ GLint *data
+
+
+ void glGetMapAttribParameterfvNV
+ GLenum target
+ GLuint index
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetMapAttribParameterivNV
+ GLenum target
+ GLuint index
+ GLenum pname
+ GLint *params
+
+
+ void glGetMapControlPointsNV
+ GLenum target
+ GLuint index
+ GLenum type
+ GLsizei ustride
+ GLsizei vstride
+ GLboolean packed
+ void *points
+
+
+ void glGetMapParameterfvNV
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetMapParameterivNV
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetMapdv
+ GLenum target
+ GLenum query
+ GLdouble *v
+
+
+
+ void glGetMapfv
+ GLenum target
+ GLenum query
+ GLfloat *v
+
+
+
+ void glGetMapiv
+ GLenum target
+ GLenum query
+ GLint *v
+
+
+
+ void glGetMapxvOES
+ GLenum target
+ GLenum query
+ GLfixed *v
+
+
+ void glGetMaterialfv
+ GLenum face
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetMaterialiv
+ GLenum face
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetMaterialxOES
+ GLenum face
+ GLenum pname
+ GLfixed param
+
+
+ void glGetMaterialxv
+ GLenum face
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetMaterialxvOES
+ GLenum face
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetMinmax
+ GLenum target
+ GLboolean reset
+ GLenum format
+ GLenum type
+ void *values
+
+
+
+
+ void glGetMinmaxEXT
+ GLenum target
+ GLboolean reset
+ GLenum format
+ GLenum type
+ void *values
+
+
+
+ void glGetMinmaxParameterfv
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetMinmaxParameterfvEXT
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetMinmaxParameteriv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetMinmaxParameterivEXT
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetMultiTexEnvfvEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetMultiTexEnvivEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetMultiTexGendvEXT
+ GLenum texunit
+ GLenum coord
+ GLenum pname
+ GLdouble *params
+
+
+ void glGetMultiTexGenfvEXT
+ GLenum texunit
+ GLenum coord
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetMultiTexGenivEXT
+ GLenum texunit
+ GLenum coord
+ GLenum pname
+ GLint *params
+
+
+ void glGetMultiTexImageEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLenum format
+ GLenum type
+ void *pixels
+
+
+ void glGetMultiTexLevelParameterfvEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetMultiTexLevelParameterivEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLenum pname
+ GLint *params
+
+
+ void glGetMultiTexParameterIivEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetMultiTexParameterIuivEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLuint *params
+
+
+ void glGetMultiTexParameterfvEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetMultiTexParameterivEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetMultisamplefv
+ GLenum pname
+ GLuint index
+ GLfloat *val
+
+
+ void glGetMultisamplefvNV
+ GLenum pname
+ GLuint index
+ GLfloat *val
+
+
+
+ void glGetNamedBufferParameteri64v
+ GLuint buffer
+ GLenum pname
+ GLint64 *params
+
+
+ void glGetNamedBufferParameteriv
+ GLuint buffer
+ GLenum pname
+ GLint *params
+
+
+ void glGetNamedBufferParameterivEXT
+ GLuint buffer
+ GLenum pname
+ GLint *params
+
+
+ void glGetNamedBufferParameterui64vNV
+ GLuint buffer
+ GLenum pname
+ GLuint64EXT *params
+
+
+ void glGetNamedBufferPointerv
+ GLuint buffer
+ GLenum pname
+ void **params
+
+
+ void glGetNamedBufferPointervEXT
+ GLuint buffer
+ GLenum pname
+ void **params
+
+
+ void glGetNamedBufferSubData
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+ void *data
+
+
+ void glGetNamedBufferSubDataEXT
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+ void *data
+
+
+ void glGetNamedFramebufferAttachmentParameteriv
+ GLuint framebuffer
+ GLenum attachment
+ GLenum pname
+ GLint *params
+
+
+ void glGetNamedFramebufferAttachmentParameterivEXT
+ GLuint framebuffer
+ GLenum attachment
+ GLenum pname
+ GLint *params
+
+
+ void glGetNamedFramebufferParameteriv
+ GLuint framebuffer
+ GLenum pname
+ GLint *param
+
+
+ void glGetNamedFramebufferParameterivEXT
+ GLuint framebuffer
+ GLenum pname
+ GLint *params
+
+
+ void glGetNamedProgramLocalParameterIivEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLint *params
+
+
+ void glGetNamedProgramLocalParameterIuivEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLuint *params
+
+
+ void glGetNamedProgramLocalParameterdvEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLdouble *params
+
+
+ void glGetNamedProgramLocalParameterfvEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLfloat *params
+
+
+ void glGetNamedProgramStringEXT
+ GLuint program
+ GLenum target
+ GLenum pname
+ void *string
+
+
+ void glGetNamedProgramivEXT
+ GLuint program
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetNamedRenderbufferParameteriv
+ GLuint renderbuffer
+ GLenum pname
+ GLint *params
+
+
+ void glGetNamedRenderbufferParameterivEXT
+ GLuint renderbuffer
+ GLenum pname
+ GLint *params
+
+
+ void glGetNamedStringARB
+ GLint namelen
+ const GLchar *name
+ GLsizei bufSize
+ GLint *stringlen
+ GLchar *string
+
+
+ void glGetNamedStringivARB
+ GLint namelen
+ const GLchar *name
+ GLenum pname
+ GLint *params
+
+
+ void glGetNextPerfQueryIdINTEL
+ GLuint queryId
+ GLuint *nextQueryId
+
+
+ void glGetObjectBufferfvATI
+ GLuint buffer
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetObjectBufferivATI
+ GLuint buffer
+ GLenum pname
+ GLint *params
+
+
+ void glGetObjectLabel
+ GLenum identifier
+ GLuint name
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *label
+
+
+ void glGetObjectLabelEXT
+ GLenum type
+ GLuint object
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *label
+
+
+ void glGetObjectLabelKHR
+ GLenum identifier
+ GLuint name
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *label
+
+
+
+ void glGetObjectParameterfvARB
+ GLhandleARB obj
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetObjectParameterivAPPLE
+ GLenum objectType
+ GLuint name
+ GLenum pname
+ GLint *params
+
+
+ void glGetObjectParameterivARB
+ GLhandleARB obj
+ GLenum pname
+ GLint *params
+
+
+ void glGetObjectPtrLabel
+ const void *ptr
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *label
+
+
+ void glGetObjectPtrLabelKHR
+ const void *ptr
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *label
+
+
+
+ void glGetOcclusionQueryivNV
+ GLuint id
+ GLenum pname
+ GLint *params
+
+
+ void glGetOcclusionQueryuivNV
+ GLuint id
+ GLenum pname
+ GLuint *params
+
+
+ void glGetPathColorGenfvNV
+ GLenum color
+ GLenum pname
+ GLfloat *value
+
+
+ void glGetPathColorGenivNV
+ GLenum color
+ GLenum pname
+ GLint *value
+
+
+ void glGetPathCommandsNV
+ GLuint path
+ GLubyte *commands
+
+
+ void glGetPathCoordsNV
+ GLuint path
+ GLfloat *coords
+
+
+ void glGetPathDashArrayNV
+ GLuint path
+ GLfloat *dashArray
+
+
+ GLfloat glGetPathLengthNV
+ GLuint path
+ GLsizei startSegment
+ GLsizei numSegments
+
+
+ void glGetPathMetricRangeNV
+ GLbitfield metricQueryMask
+ GLuint firstPathName
+ GLsizei numPaths
+ GLsizei stride
+ GLfloat *metrics
+
+
+ void glGetPathMetricsNV
+ GLbitfield metricQueryMask
+ GLsizei numPaths
+ GLenum pathNameType
+ const void *paths
+ GLuint pathBase
+ GLsizei stride
+ GLfloat *metrics
+
+
+ void glGetPathParameterfvNV
+ GLuint path
+ GLenum pname
+ GLfloat *value
+
+
+ void glGetPathParameterivNV
+ GLuint path
+ GLenum pname
+ GLint *value
+
+
+ void glGetPathSpacingNV
+ GLenum pathListMode
+ GLsizei numPaths
+ GLenum pathNameType
+ const void *paths
+ GLuint pathBase
+ GLfloat advanceScale
+ GLfloat kerningScale
+ GLenum transformType
+ GLfloat *returnedSpacing
+
+
+ void glGetPathTexGenfvNV
+ GLenum texCoordSet
+ GLenum pname
+ GLfloat *value
+
+
+ void glGetPathTexGenivNV
+ GLenum texCoordSet
+ GLenum pname
+ GLint *value
+
+
+ void glGetPerfCounterInfoINTEL
+ GLuint queryId
+ GLuint counterId
+ GLuint counterNameLength
+ GLchar *counterName
+ GLuint counterDescLength
+ GLchar *counterDesc
+ GLuint *counterOffset
+ GLuint *counterDataSize
+ GLuint *counterTypeEnum
+ GLuint *counterDataTypeEnum
+ GLuint64 *rawCounterMaxValue
+
+
+ void glGetPerfMonitorCounterDataAMD
+ GLuint monitor
+ GLenum pname
+ GLsizei dataSize
+ GLuint *data
+ GLint *bytesWritten
+
+
+ void glGetPerfMonitorCounterInfoAMD
+ GLuint group
+ GLuint counter
+ GLenum pname
+ void *data
+
+
+ void glGetPerfMonitorCounterStringAMD
+ GLuint group
+ GLuint counter
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *counterString
+
+
+ void glGetPerfMonitorCountersAMD
+ GLuint group
+ GLint *numCounters
+ GLint *maxActiveCounters
+ GLsizei counterSize
+ GLuint *counters
+
+
+ void glGetPerfMonitorGroupStringAMD
+ GLuint group
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *groupString
+
+
+ void glGetPerfMonitorGroupsAMD
+ GLint *numGroups
+ GLsizei groupsSize
+ GLuint *groups
+
+
+ void glGetPerfQueryDataINTEL
+ GLuint queryHandle
+ GLuint flags
+ GLsizei dataSize
+ GLvoid *data
+ GLuint *bytesWritten
+
+
+ void glGetPerfQueryIdByNameINTEL
+ GLchar *queryName
+ GLuint *queryId
+
+
+ void glGetPerfQueryInfoINTEL
+ GLuint queryId
+ GLuint queryNameLength
+ GLchar *queryName
+ GLuint *dataSize
+ GLuint *noCounters
+ GLuint *noInstances
+ GLuint *capsMask
+
+
+ void glGetPixelMapfv
+ GLenum map
+ GLfloat *values
+
+
+
+
+ void glGetPixelMapuiv
+ GLenum map
+ GLuint *values
+
+
+
+
+ void glGetPixelMapusv
+ GLenum map
+ GLushort *values
+
+
+
+
+ void glGetPixelMapxv
+ GLenum map
+ GLint size
+ GLfixed *values
+
+
+ void glGetPixelTexGenParameterfvSGIS
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetPixelTexGenParameterivSGIS
+ GLenum pname
+ GLint *params
+
+
+ void glGetPixelTransformParameterfvEXT
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetPixelTransformParameterivEXT
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetPointerIndexedvEXT
+ GLenum target
+ GLuint index
+ void **data
+
+
+ void glGetPointeri_vEXT
+ GLenum pname
+ GLuint index
+ void **params
+
+
+ void glGetPointerv
+ GLenum pname
+ void **params
+
+
+
+ void glGetPointervEXT
+ GLenum pname
+ void **params
+
+
+
+ void glGetPointervKHR
+ GLenum pname
+ void **params
+
+
+
+ void glGetPolygonStipple
+ GLubyte *mask
+
+
+
+
+ void glGetProgramBinary
+ GLuint program
+ GLsizei bufSize
+ GLsizei *length
+ GLenum *binaryFormat
+ void *binary
+
+
+ void glGetProgramBinaryOES
+ GLuint program
+ GLsizei bufSize
+ GLsizei *length
+ GLenum *binaryFormat
+ void *binary
+
+
+
+ void glGetProgramEnvParameterIivNV
+ GLenum target
+ GLuint index
+ GLint *params
+
+
+ void glGetProgramEnvParameterIuivNV
+ GLenum target
+ GLuint index
+ GLuint *params
+
+
+ void glGetProgramEnvParameterdvARB
+ GLenum target
+ GLuint index
+ GLdouble *params
+
+
+ void glGetProgramEnvParameterfvARB
+ GLenum target
+ GLuint index
+ GLfloat *params
+
+
+ void glGetProgramInfoLog
+ GLuint program
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *infoLog
+
+
+
+ void glGetProgramInterfaceiv
+ GLuint program
+ GLenum programInterface
+ GLenum pname
+ GLint *params
+
+
+ void glGetProgramLocalParameterIivNV
+ GLenum target
+ GLuint index
+ GLint *params
+
+
+ void glGetProgramLocalParameterIuivNV
+ GLenum target
+ GLuint index
+ GLuint *params
+
+
+ void glGetProgramLocalParameterdvARB
+ GLenum target
+ GLuint index
+ GLdouble *params
+
+
+ void glGetProgramLocalParameterfvARB
+ GLenum target
+ GLuint index
+ GLfloat *params
+
+
+ void glGetProgramNamedParameterdvNV
+ GLuint id
+ GLsizei len
+ const GLubyte *name
+ GLdouble *params
+
+
+
+ void glGetProgramNamedParameterfvNV
+ GLuint id
+ GLsizei len
+ const GLubyte *name
+ GLfloat *params
+
+
+
+ void glGetProgramParameterdvNV
+ GLenum target
+ GLuint index
+ GLenum pname
+ GLdouble *params
+
+
+
+ void glGetProgramParameterfvNV
+ GLenum target
+ GLuint index
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetProgramPipelineInfoLog
+ GLuint pipeline
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *infoLog
+
+
+ void glGetProgramPipelineInfoLogEXT
+ GLuint pipeline
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *infoLog
+
+
+ void glGetProgramPipelineiv
+ GLuint pipeline
+ GLenum pname
+ GLint *params
+
+
+ void glGetProgramPipelineivEXT
+ GLuint pipeline
+ GLenum pname
+ GLint *params
+
+
+ GLuint glGetProgramResourceIndex
+ GLuint program
+ GLenum programInterface
+ const GLchar *name
+
+
+ GLint glGetProgramResourceLocation
+ GLuint program
+ GLenum programInterface
+ const GLchar *name
+
+
+ GLint glGetProgramResourceLocationIndex
+ GLuint program
+ GLenum programInterface
+ const GLchar *name
+
+
+ void glGetProgramResourceName
+ GLuint program
+ GLenum programInterface
+ GLuint index
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *name
+
+
+ void glGetProgramResourcefvNV
+ GLuint program
+ GLenum programInterface
+ GLuint index
+ GLsizei propCount
+ const GLenum *props
+ GLsizei bufSize
+ GLsizei *length
+ GLfloat *params
+
+
+ void glGetProgramResourceiv
+ GLuint program
+ GLenum programInterface
+ GLuint index
+ GLsizei propCount
+ const GLenum *props
+ GLsizei bufSize
+ GLsizei *length
+ GLint *params
+
+
+ void glGetProgramStageiv
+ GLuint program
+ GLenum shadertype
+ GLenum pname
+ GLint *values
+
+
+ void glGetProgramStringARB
+ GLenum target
+ GLenum pname
+ void *string
+
+
+ void glGetProgramStringNV
+ GLuint id
+ GLenum pname
+ GLubyte *program
+
+
+
+ void glGetProgramSubroutineParameteruivNV
+ GLenum target
+ GLuint index
+ GLuint *param
+
+
+ void glGetProgramiv
+ GLuint program
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetProgramivARB
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetProgramivNV
+ GLuint id
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetQueryBufferObjecti64v
+ GLuint id
+ GLuint buffer
+ GLenum pname
+ GLintptr offset
+
+
+ void glGetQueryBufferObjectiv
+ GLuint id
+ GLuint buffer
+ GLenum pname
+ GLintptr offset
+
+
+ void glGetQueryBufferObjectui64v
+ GLuint id
+ GLuint buffer
+ GLenum pname
+ GLintptr offset
+
+
+ void glGetQueryBufferObjectuiv
+ GLuint id
+ GLuint buffer
+ GLenum pname
+ GLintptr offset
+
+
+ void glGetQueryIndexediv
+ GLenum target
+ GLuint index
+ GLenum pname
+ GLint *params
+
+
+ void glGetQueryObjecti64v
+ GLuint id
+ GLenum pname
+ GLint64 *params
+
+
+ void glGetQueryObjecti64vEXT
+ GLuint id
+ GLenum pname
+ GLint64 *params
+
+
+
+
+ void glGetQueryObjectiv
+ GLuint id
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetQueryObjectivARB
+ GLuint id
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetQueryObjectivEXT
+ GLuint id
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetQueryObjectui64v
+ GLuint id
+ GLenum pname
+ GLuint64 *params
+
+
+ void glGetQueryObjectui64vEXT
+ GLuint id
+ GLenum pname
+ GLuint64 *params
+
+
+
+
+ void glGetQueryObjectuiv
+ GLuint id
+ GLenum pname
+ GLuint *params
+
+
+
+ void glGetQueryObjectuivARB
+ GLuint id
+ GLenum pname
+ GLuint *params
+
+
+
+ void glGetQueryObjectuivEXT
+ GLuint id
+ GLenum pname
+ GLuint *params
+
+
+ void glGetQueryiv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetQueryivARB
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetQueryivEXT
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetRenderbufferParameteriv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetRenderbufferParameterivEXT
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+
+ void glGetRenderbufferParameterivOES
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetSamplerParameterIiv
+ GLuint sampler
+ GLenum pname
+ GLint *params
+
+
+ void glGetSamplerParameterIivEXT
+ GLuint sampler
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetSamplerParameterIivOES
+ GLuint sampler
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetSamplerParameterIuiv
+ GLuint sampler
+ GLenum pname
+ GLuint *params
+
+
+ void glGetSamplerParameterIuivEXT
+ GLuint sampler
+ GLenum pname
+ GLuint *params
+
+
+
+ void glGetSamplerParameterIuivOES
+ GLuint sampler
+ GLenum pname
+ GLuint *params
+
+
+
+ void glGetSamplerParameterfv
+ GLuint sampler
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetSamplerParameteriv
+ GLuint sampler
+ GLenum pname
+ GLint *params
+
+
+ void glGetSeparableFilter
+ GLenum target
+ GLenum format
+ GLenum type
+ void *row
+ void *column
+ void *span
+
+
+
+
+ void glGetSeparableFilterEXT
+ GLenum target
+ GLenum format
+ GLenum type
+ void *row
+ void *column
+ void *span
+
+
+
+ void glGetShaderInfoLog
+ GLuint shader
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *infoLog
+
+
+
+ void glGetShaderPrecisionFormat
+ GLenum shadertype
+ GLenum precisiontype
+ GLint *range
+ GLint *precision
+
+
+ void glGetShaderSource
+ GLuint shader
+ GLsizei bufSize
+ GLsizei *length
+ GLchar *source
+
+
+ void glGetShaderSourceARB
+ GLhandleARB obj
+ GLsizei maxLength
+ GLsizei *length
+ GLcharARB *source
+
+
+
+ void glGetShaderiv
+ GLuint shader
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetSharpenTexFuncSGIS
+ GLenum target
+ GLfloat *points
+
+
+
+ GLushort glGetStageIndexNV
+ GLenum shadertype
+
+
+ const GLubyte *glGetString
+ GLenum name
+
+
+
+ const GLubyte *glGetStringi
+ GLenum name
+ GLuint index
+
+
+ GLuint glGetSubroutineIndex
+ GLuint program
+ GLenum shadertype
+ const GLchar *name
+
+
+ GLint glGetSubroutineUniformLocation
+ GLuint program
+ GLenum shadertype
+ const GLchar *name
+
+
+ void glGetSynciv
+ GLsync sync
+ GLenum pname
+ GLsizei bufSize
+ GLsizei *length
+ GLint *values
+
+
+ void glGetSyncivAPPLE
+ GLsync sync
+ GLenum pname
+ GLsizei bufSize
+ GLsizei *length
+ GLint *values
+
+
+
+ void glGetTexBumpParameterfvATI
+ GLenum pname
+ GLfloat *param
+
+
+ void glGetTexBumpParameterivATI
+ GLenum pname
+ GLint *param
+
+
+ void glGetTexEnvfv
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetTexEnviv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetTexEnvxv
+ GLenum target
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetTexEnvxvOES
+ GLenum target
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetTexFilterFuncSGIS
+ GLenum target
+ GLenum filter
+ GLfloat *weights
+
+
+
+ void glGetTexGendv
+ GLenum coord
+ GLenum pname
+ GLdouble *params
+
+
+
+ void glGetTexGenfv
+ GLenum coord
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetTexGenfvOES
+ GLenum coord
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetTexGeniv
+ GLenum coord
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetTexGenivOES
+ GLenum coord
+ GLenum pname
+ GLint *params
+
+
+ void glGetTexGenxvOES
+ GLenum coord
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetTexImage
+ GLenum target
+ GLint level
+ GLenum format
+ GLenum type
+ void *pixels
+
+
+
+
+ void glGetTexLevelParameterfv
+ GLenum target
+ GLint level
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetTexLevelParameteriv
+ GLenum target
+ GLint level
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetTexLevelParameterxvOES
+ GLenum target
+ GLint level
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetTexParameterIiv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetTexParameterIivEXT
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetTexParameterIivOES
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetTexParameterIuiv
+ GLenum target
+ GLenum pname
+ GLuint *params
+
+
+
+ void glGetTexParameterIuivEXT
+ GLenum target
+ GLenum pname
+ GLuint *params
+
+
+
+ void glGetTexParameterIuivOES
+ GLenum target
+ GLenum pname
+ GLuint *params
+
+
+
+ void glGetTexParameterPointervAPPLE
+ GLenum target
+ GLenum pname
+ void **params
+
+
+ void glGetTexParameterfv
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetTexParameteriv
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetTexParameterxv
+ GLenum target
+ GLenum pname
+ GLfixed *params
+
+
+ void glGetTexParameterxvOES
+ GLenum target
+ GLenum pname
+ GLfixed *params
+
+
+ GLuint64 glGetTextureHandleARB
+ GLuint texture
+
+
+ GLuint64 glGetTextureHandleNV
+ GLuint texture
+
+
+ void glGetTextureImage
+ GLuint texture
+ GLint level
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *pixels
+
+
+ void glGetTextureImageEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLenum format
+ GLenum type
+ void *pixels
+
+
+ void glGetTextureLevelParameterfv
+ GLuint texture
+ GLint level
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetTextureLevelParameterfvEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetTextureLevelParameteriv
+ GLuint texture
+ GLint level
+ GLenum pname
+ GLint *params
+
+
+ void glGetTextureLevelParameterivEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLenum pname
+ GLint *params
+
+
+ void glGetTextureParameterIiv
+ GLuint texture
+ GLenum pname
+ GLint *params
+
+
+ void glGetTextureParameterIivEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ void glGetTextureParameterIuiv
+ GLuint texture
+ GLenum pname
+ GLuint *params
+
+
+ void glGetTextureParameterIuivEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ GLuint *params
+
+
+ void glGetTextureParameterfv
+ GLuint texture
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetTextureParameterfvEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetTextureParameteriv
+ GLuint texture
+ GLenum pname
+ GLint *params
+
+
+ void glGetTextureParameterivEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ GLint *params
+
+
+ GLuint64 glGetTextureSamplerHandleARB
+ GLuint texture
+ GLuint sampler
+
+
+ GLuint64 glGetTextureSamplerHandleNV
+ GLuint texture
+ GLuint sampler
+
+
+ void glGetTextureSubImage
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *pixels
+
+
+ void glGetTrackMatrixivNV
+ GLenum target
+ GLuint address
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetTransformFeedbackVarying
+ GLuint program
+ GLuint index
+ GLsizei bufSize
+ GLsizei *length
+ GLsizei *size
+ GLenum *type
+ GLchar *name
+
+
+ void glGetTransformFeedbackVaryingEXT
+ GLuint program
+ GLuint index
+ GLsizei bufSize
+ GLsizei *length
+ GLsizei *size
+ GLenum *type
+ GLchar *name
+
+
+
+ void glGetTransformFeedbackVaryingNV
+ GLuint program
+ GLuint index
+ GLint *location
+
+
+ void glGetTransformFeedbacki64_v
+ GLuint xfb
+ GLenum pname
+ GLuint index
+ GLint64 *param
+
+
+ void glGetTransformFeedbacki_v
+ GLuint xfb
+ GLenum pname
+ GLuint index
+ GLint *param
+
+
+ void glGetTransformFeedbackiv
+ GLuint xfb
+ GLenum pname
+ GLint *param
+
+
+ void glGetTranslatedShaderSourceANGLE
+ GLuint shader
+ GLsizei bufsize
+ GLsizei *length
+ GLchar *source
+
+
+ GLuint glGetUniformBlockIndex
+ GLuint program
+ const GLchar *uniformBlockName
+
+
+ GLint glGetUniformBufferSizeEXT
+ GLuint program
+ GLint location
+
+
+ void glGetUniformIndices
+ GLuint program
+ GLsizei uniformCount
+ const GLchar *const*uniformNames
+ GLuint *uniformIndices
+
+
+ GLint glGetUniformLocation
+ GLuint program
+ const GLchar *name
+
+
+ GLint glGetUniformLocationARB
+ GLhandleARB programObj
+ const GLcharARB *name
+
+
+
+ GLintptr glGetUniformOffsetEXT
+ GLuint program
+ GLint location
+
+
+ void glGetUniformSubroutineuiv
+ GLenum shadertype
+ GLint location
+ GLuint *params
+
+
+ void glGetUniformdv
+ GLuint program
+ GLint location
+ GLdouble *params
+
+
+ void glGetUniformfv
+ GLuint program
+ GLint location
+ GLfloat *params
+
+
+ void glGetUniformfvARB
+ GLhandleARB programObj
+ GLint location
+ GLfloat *params
+
+
+
+ void glGetUniformi64vNV
+ GLuint program
+ GLint location
+ GLint64EXT *params
+
+
+ void glGetUniformiv
+ GLuint program
+ GLint location
+ GLint *params
+
+
+ void glGetUniformivARB
+ GLhandleARB programObj
+ GLint location
+ GLint *params
+
+
+
+ void glGetUniformui64vNV
+ GLuint program
+ GLint location
+ GLuint64EXT *params
+
+
+ void glGetUniformuiv
+ GLuint program
+ GLint location
+ GLuint *params
+
+
+ void glGetUniformuivEXT
+ GLuint program
+ GLint location
+ GLuint *params
+
+
+
+ void glGetVariantArrayObjectfvATI
+ GLuint id
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetVariantArrayObjectivATI
+ GLuint id
+ GLenum pname
+ GLint *params
+
+
+ void glGetVariantBooleanvEXT
+ GLuint id
+ GLenum value
+ GLboolean *data
+
+
+ void glGetVariantFloatvEXT
+ GLuint id
+ GLenum value
+ GLfloat *data
+
+
+ void glGetVariantIntegervEXT
+ GLuint id
+ GLenum value
+ GLint *data
+
+
+ void glGetVariantPointervEXT
+ GLuint id
+ GLenum value
+ void **data
+
+
+ GLint glGetVaryingLocationNV
+ GLuint program
+ const GLchar *name
+
+
+ void glGetVertexArrayIndexed64iv
+ GLuint vaobj
+ GLuint index
+ GLenum pname
+ GLint64 *param
+
+
+ void glGetVertexArrayIndexediv
+ GLuint vaobj
+ GLuint index
+ GLenum pname
+ GLint *param
+
+
+ void glGetVertexArrayIntegeri_vEXT
+ GLuint vaobj
+ GLuint index
+ GLenum pname
+ GLint *param
+
+
+ void glGetVertexArrayIntegervEXT
+ GLuint vaobj
+ GLenum pname
+ GLint *param
+
+
+ void glGetVertexArrayPointeri_vEXT
+ GLuint vaobj
+ GLuint index
+ GLenum pname
+ void **param
+
+
+ void glGetVertexArrayPointervEXT
+ GLuint vaobj
+ GLenum pname
+ void **param
+
+
+ void glGetVertexArrayiv
+ GLuint vaobj
+ GLenum pname
+ GLint *param
+
+
+ void glGetVertexAttribArrayObjectfvATI
+ GLuint index
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetVertexAttribArrayObjectivATI
+ GLuint index
+ GLenum pname
+ GLint *params
+
+
+ void glGetVertexAttribIiv
+ GLuint index
+ GLenum pname
+ GLint *params
+
+
+ void glGetVertexAttribIivEXT
+ GLuint index
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetVertexAttribIuiv
+ GLuint index
+ GLenum pname
+ GLuint *params
+
+
+ void glGetVertexAttribIuivEXT
+ GLuint index
+ GLenum pname
+ GLuint *params
+
+
+
+ void glGetVertexAttribLdv
+ GLuint index
+ GLenum pname
+ GLdouble *params
+
+
+ void glGetVertexAttribLdvEXT
+ GLuint index
+ GLenum pname
+ GLdouble *params
+
+
+
+ void glGetVertexAttribLi64vNV
+ GLuint index
+ GLenum pname
+ GLint64EXT *params
+
+
+ void glGetVertexAttribLui64vARB
+ GLuint index
+ GLenum pname
+ GLuint64EXT *params
+
+
+ void glGetVertexAttribLui64vNV
+ GLuint index
+ GLenum pname
+ GLuint64EXT *params
+
+
+ void glGetVertexAttribPointerv
+ GLuint index
+ GLenum pname
+ void **pointer
+
+
+
+ void glGetVertexAttribPointervARB
+ GLuint index
+ GLenum pname
+ void **pointer
+
+
+
+ void glGetVertexAttribPointervNV
+ GLuint index
+ GLenum pname
+ void **pointer
+
+
+
+ void glGetVertexAttribdv
+ GLuint index
+ GLenum pname
+ GLdouble *params
+
+
+
+ void glGetVertexAttribdvARB
+ GLuint index
+ GLenum pname
+ GLdouble *params
+
+
+
+
+ void glGetVertexAttribdvNV
+ GLuint index
+ GLenum pname
+ GLdouble *params
+
+
+
+
+ void glGetVertexAttribfv
+ GLuint index
+ GLenum pname
+ GLfloat *params
+
+
+
+ void glGetVertexAttribfvARB
+ GLuint index
+ GLenum pname
+ GLfloat *params
+
+
+
+
+ void glGetVertexAttribfvNV
+ GLuint index
+ GLenum pname
+ GLfloat *params
+
+
+
+
+ void glGetVertexAttribiv
+ GLuint index
+ GLenum pname
+ GLint *params
+
+
+
+ void glGetVertexAttribivARB
+ GLuint index
+ GLenum pname
+ GLint *params
+
+
+
+
+ void glGetVertexAttribivNV
+ GLuint index
+ GLenum pname
+ GLint *params
+
+
+
+
+ void glGetVideoCaptureStreamdvNV
+ GLuint video_capture_slot
+ GLuint stream
+ GLenum pname
+ GLdouble *params
+
+
+ void glGetVideoCaptureStreamfvNV
+ GLuint video_capture_slot
+ GLuint stream
+ GLenum pname
+ GLfloat *params
+
+
+ void glGetVideoCaptureStreamivNV
+ GLuint video_capture_slot
+ GLuint stream
+ GLenum pname
+ GLint *params
+
+
+ void glGetVideoCaptureivNV
+ GLuint video_capture_slot
+ GLenum pname
+ GLint *params
+
+
+ void glGetVideoi64vNV
+ GLuint video_slot
+ GLenum pname
+ GLint64EXT *params
+
+
+ void glGetVideoivNV
+ GLuint video_slot
+ GLenum pname
+ GLint *params
+
+
+ void glGetVideoui64vNV
+ GLuint video_slot
+ GLenum pname
+ GLuint64EXT *params
+
+
+ void glGetVideouivNV
+ GLuint video_slot
+ GLenum pname
+ GLuint *params
+
+
+ void glGetnColorTable
+ GLenum target
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *table
+
+
+ void glGetnColorTableARB
+ GLenum target
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *table
+
+
+ void glGetnCompressedTexImage
+ GLenum target
+ GLint lod
+ GLsizei bufSize
+ void *pixels
+
+
+ void glGetnCompressedTexImageARB
+ GLenum target
+ GLint lod
+ GLsizei bufSize
+ void *img
+
+
+ void glGetnConvolutionFilter
+ GLenum target
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *image
+
+
+ void glGetnConvolutionFilterARB
+ GLenum target
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *image
+
+
+ void glGetnHistogram
+ GLenum target
+ GLboolean reset
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *values
+
+
+ void glGetnHistogramARB
+ GLenum target
+ GLboolean reset
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *values
+
+
+ void glGetnMapdv
+ GLenum target
+ GLenum query
+ GLsizei bufSize
+ GLdouble *v
+
+
+ void glGetnMapdvARB
+ GLenum target
+ GLenum query
+ GLsizei bufSize
+ GLdouble *v
+
+
+ void glGetnMapfv
+ GLenum target
+ GLenum query
+ GLsizei bufSize
+ GLfloat *v
+
+
+ void glGetnMapfvARB
+ GLenum target
+ GLenum query
+ GLsizei bufSize
+ GLfloat *v
+
+
+ void glGetnMapiv
+ GLenum target
+ GLenum query
+ GLsizei bufSize
+ GLint *v
+
+
+ void glGetnMapivARB
+ GLenum target
+ GLenum query
+ GLsizei bufSize
+ GLint *v
+
+
+ void glGetnMinmax
+ GLenum target
+ GLboolean reset
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *values
+
+
+ void glGetnMinmaxARB
+ GLenum target
+ GLboolean reset
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *values
+
+
+ void glGetnPixelMapfv
+ GLenum map
+ GLsizei bufSize
+ GLfloat *values
+
+
+ void glGetnPixelMapfvARB
+ GLenum map
+ GLsizei bufSize
+ GLfloat *values
+
+
+ void glGetnPixelMapuiv
+ GLenum map
+ GLsizei bufSize
+ GLuint *values
+
+
+ void glGetnPixelMapuivARB
+ GLenum map
+ GLsizei bufSize
+ GLuint *values
+
+
+ void glGetnPixelMapusv
+ GLenum map
+ GLsizei bufSize
+ GLushort *values
+
+
+ void glGetnPixelMapusvARB
+ GLenum map
+ GLsizei bufSize
+ GLushort *values
+
+
+ void glGetnPolygonStipple
+ GLsizei bufSize
+ GLubyte *pattern
+
+
+ void glGetnPolygonStippleARB
+ GLsizei bufSize
+ GLubyte *pattern
+
+
+ void glGetnSeparableFilter
+ GLenum target
+ GLenum format
+ GLenum type
+ GLsizei rowBufSize
+ void *row
+ GLsizei columnBufSize
+ void *column
+ void *span
+
+
+ void glGetnSeparableFilterARB
+ GLenum target
+ GLenum format
+ GLenum type
+ GLsizei rowBufSize
+ void *row
+ GLsizei columnBufSize
+ void *column
+ void *span
+
+
+ void glGetnTexImage
+ GLenum target
+ GLint level
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *pixels
+
+
+ void glGetnTexImageARB
+ GLenum target
+ GLint level
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *img
+
+
+ void glGetnUniformdv
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLdouble *params
+
+
+ void glGetnUniformdvARB
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLdouble *params
+
+
+ void glGetnUniformfv
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLfloat *params
+
+
+ void glGetnUniformfvARB
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLfloat *params
+
+
+ void glGetnUniformfvEXT
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLfloat *params
+
+
+ void glGetnUniformfvKHR
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLfloat *params
+
+
+
+ void glGetnUniformiv
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLint *params
+
+
+ void glGetnUniformivARB
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLint *params
+
+
+ void glGetnUniformivEXT
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLint *params
+
+
+ void glGetnUniformivKHR
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLint *params
+
+
+
+ void glGetnUniformuiv
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLuint *params
+
+
+ void glGetnUniformuivARB
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLuint *params
+
+
+ void glGetnUniformuivKHR
+ GLuint program
+ GLint location
+ GLsizei bufSize
+ GLuint *params
+
+
+
+ void glGlobalAlphaFactorbSUN
+ GLbyte factor
+
+
+ void glGlobalAlphaFactordSUN
+ GLdouble factor
+
+
+ void glGlobalAlphaFactorfSUN
+ GLfloat factor
+
+
+ void glGlobalAlphaFactoriSUN
+ GLint factor
+
+
+ void glGlobalAlphaFactorsSUN
+ GLshort factor
+
+
+ void glGlobalAlphaFactorubSUN
+ GLubyte factor
+
+
+ void glGlobalAlphaFactoruiSUN
+ GLuint factor
+
+
+ void glGlobalAlphaFactorusSUN
+ GLushort factor
+
+
+ void glHint
+ GLenum target
+ GLenum mode
+
+
+
+ void glHintPGI
+ GLenum target
+ GLint mode
+
+
+ void glHistogram
+ GLenum target
+ GLsizei width
+ GLenum internalformat
+ GLboolean sink
+
+
+
+ void glHistogramEXT
+ GLenum target
+ GLsizei width
+ GLenum internalformat
+ GLboolean sink
+
+
+
+
+ void glIglooInterfaceSGIX
+ GLenum pname
+ const void *params
+
+
+
+ void glImageTransformParameterfHP
+ GLenum target
+ GLenum pname
+ GLfloat param
+
+
+ void glImageTransformParameterfvHP
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+ void glImageTransformParameteriHP
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+ void glImageTransformParameterivHP
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+ GLsync glImportSyncEXT
+ GLenum external_sync_type
+ GLintptr external_sync
+ GLbitfield flags
+
+
+ void glIndexFormatNV
+ GLenum type
+ GLsizei stride
+
+
+ void glIndexFuncEXT
+ GLenum func
+ GLclampf ref
+
+
+ void glIndexMask
+ GLuint mask
+
+
+
+ void glIndexMaterialEXT
+ GLenum face
+ GLenum mode
+
+
+ void glIndexPointer
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glIndexPointerEXT
+ GLenum type
+ GLsizei stride
+ GLsizei count
+ const void *pointer
+
+
+ void glIndexPointerListIBM
+ GLenum type
+ GLint stride
+ const void **pointer
+ GLint ptrstride
+
+
+ void glIndexd
+ GLdouble c
+
+
+
+ void glIndexdv
+ const GLdouble *c
+
+
+
+ void glIndexf
+ GLfloat c
+
+
+
+ void glIndexfv
+ const GLfloat *c
+
+
+
+ void glIndexi
+ GLint c
+
+
+
+ void glIndexiv
+ const GLint *c
+
+
+
+ void glIndexs
+ GLshort c
+
+
+
+ void glIndexsv
+ const GLshort *c
+
+
+
+ void glIndexub
+ GLubyte c
+
+
+
+ void glIndexubv
+ const GLubyte *c
+
+
+
+ void glIndexxOES
+ GLfixed component
+
+
+ void glIndexxvOES
+ const GLfixed *component
+
+
+ void glInitNames
+
+
+
+ void glInsertComponentEXT
+ GLuint res
+ GLuint src
+ GLuint num
+
+
+ void glInsertEventMarkerEXT
+ GLsizei length
+ const GLchar *marker
+
+
+ void glInstrumentsBufferSGIX
+ GLsizei size
+ GLint *buffer
+
+
+
+ void glInterleavedArrays
+ GLenum format
+ GLsizei stride
+ const void *pointer
+
+
+ void glInterpolatePathsNV
+ GLuint resultPath
+ GLuint pathA
+ GLuint pathB
+ GLfloat weight
+
+
+ void glInvalidateBufferData
+ GLuint buffer
+
+
+ void glInvalidateBufferSubData
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr length
+
+
+ void glInvalidateFramebuffer
+ GLenum target
+ GLsizei numAttachments
+ const GLenum *attachments
+
+
+ void glInvalidateNamedFramebufferData
+ GLuint framebuffer
+ GLsizei numAttachments
+ const GLenum *attachments
+
+
+ void glInvalidateNamedFramebufferSubData
+ GLuint framebuffer
+ GLsizei numAttachments
+ const GLenum *attachments
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+ void glInvalidateSubFramebuffer
+ GLenum target
+ GLsizei numAttachments
+ const GLenum *attachments
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+ void glInvalidateTexImage
+ GLuint texture
+ GLint level
+
+
+ void glInvalidateTexSubImage
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+
+
+ GLboolean glIsAsyncMarkerSGIX
+ GLuint marker
+
+
+ GLboolean glIsBuffer
+ GLuint buffer
+
+
+ GLboolean glIsBufferARB
+ GLuint buffer
+
+
+
+ GLboolean glIsBufferResidentNV
+ GLenum target
+
+
+ GLboolean glIsCommandListNV
+ GLuint list
+
+
+ GLboolean glIsEnabled
+ GLenum cap
+
+
+
+ GLboolean glIsEnabledIndexedEXT
+ GLenum target
+ GLuint index
+
+
+
+ GLboolean glIsEnabledi
+ GLenum target
+ GLuint index
+
+
+ GLboolean glIsEnablediEXT
+ GLenum target
+ GLuint index
+
+
+
+ GLboolean glIsEnablediOES
+ GLenum target
+ GLuint index
+
+
+
+ GLboolean glIsEnablediNV
+ GLenum target
+ GLuint index
+
+
+
+ GLboolean glIsFenceAPPLE
+ GLuint fence
+
+
+ GLboolean glIsFenceNV
+ GLuint fence
+
+
+
+ GLboolean glIsFramebuffer
+ GLuint framebuffer
+
+
+
+ GLboolean glIsFramebufferEXT
+ GLuint framebuffer
+
+
+
+
+ GLboolean glIsFramebufferOES
+ GLuint framebuffer
+
+
+ GLboolean glIsImageHandleResidentARB
+ GLuint64 handle
+
+
+ GLboolean glIsImageHandleResidentNV
+ GLuint64 handle
+
+
+ GLboolean glIsList
+ GLuint list
+
+
+
+ GLboolean glIsNameAMD
+ GLenum identifier
+ GLuint name
+
+
+ GLboolean glIsNamedBufferResidentNV
+ GLuint buffer
+
+
+ GLboolean glIsNamedStringARB
+ GLint namelen
+ const GLchar *name
+
+
+ GLboolean glIsObjectBufferATI
+ GLuint buffer
+
+
+ GLboolean glIsOcclusionQueryNV
+ GLuint id
+
+
+ GLboolean glIsPathNV
+ GLuint path
+
+
+ GLboolean glIsPointInFillPathNV
+ GLuint path
+ GLuint mask
+ GLfloat x
+ GLfloat y
+
+
+ GLboolean glIsPointInStrokePathNV
+ GLuint path
+ GLfloat x
+ GLfloat y
+
+
+ GLboolean glIsProgram
+ GLuint program
+
+
+
+ GLboolean glIsProgramARB
+ GLuint program
+
+
+
+ GLboolean glIsProgramNV
+ GLuint id
+
+
+
+
+ GLboolean glIsProgramPipeline
+ GLuint pipeline
+
+
+ GLboolean glIsProgramPipelineEXT
+ GLuint pipeline
+
+
+ GLboolean glIsQuery
+ GLuint id
+
+
+
+ GLboolean glIsQueryARB
+ GLuint id
+
+
+
+ GLboolean glIsQueryEXT
+ GLuint id
+
+
+ GLboolean glIsRenderbuffer
+ GLuint renderbuffer
+
+
+
+ GLboolean glIsRenderbufferEXT
+ GLuint renderbuffer
+
+
+
+
+ GLboolean glIsRenderbufferOES
+ GLuint renderbuffer
+
+
+ GLboolean glIsSampler
+ GLuint sampler
+
+
+ GLboolean glIsShader
+ GLuint shader
+
+
+
+ GLboolean glIsStateNV
+ GLuint state
+
+
+ GLboolean glIsSync
+ GLsync sync
+
+
+ GLboolean glIsSyncAPPLE
+ GLsync sync
+
+
+
+ GLboolean glIsTexture
+ GLuint texture
+
+
+
+ GLboolean glIsTextureEXT
+ GLuint texture
+
+
+
+ GLboolean glIsTextureHandleResidentARB
+ GLuint64 handle
+
+
+ GLboolean glIsTextureHandleResidentNV
+ GLuint64 handle
+
+
+ GLboolean glIsTransformFeedback
+ GLuint id
+
+
+ GLboolean glIsTransformFeedbackNV
+ GLuint id
+
+
+
+ GLboolean glIsVariantEnabledEXT
+ GLuint id
+ GLenum cap
+
+
+ GLboolean glIsVertexArray
+ GLuint array
+
+
+
+ GLboolean glIsVertexArrayAPPLE
+ GLuint array
+
+
+
+ GLboolean glIsVertexArrayOES
+ GLuint array
+
+
+
+ GLboolean glIsVertexAttribEnabledAPPLE
+ GLuint index
+ GLenum pname
+
+
+ void glLabelObjectEXT
+ GLenum type
+ GLuint object
+ GLsizei length
+ const GLchar *label
+
+
+ void glLightEnviSGIX
+ GLenum pname
+ GLint param
+
+
+ void glLightModelf
+ GLenum pname
+ GLfloat param
+
+
+
+ void glLightModelfv
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glLightModeli
+ GLenum pname
+ GLint param
+
+
+
+ void glLightModeliv
+ GLenum pname
+ const GLint *params
+
+
+
+ void glLightModelx
+ GLenum pname
+ GLfixed param
+
+
+ void glLightModelxOES
+ GLenum pname
+ GLfixed param
+
+
+ void glLightModelxv
+ GLenum pname
+ const GLfixed *param
+
+
+ void glLightModelxvOES
+ GLenum pname
+ const GLfixed *param
+
+
+ void glLightf
+ GLenum light
+ GLenum pname
+ GLfloat param
+
+
+
+ void glLightfv
+ GLenum light
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glLighti
+ GLenum light
+ GLenum pname
+ GLint param
+
+
+
+ void glLightiv
+ GLenum light
+ GLenum pname
+ const GLint *params
+
+
+
+ void glLightx
+ GLenum light
+ GLenum pname
+ GLfixed param
+
+
+ void glLightxOES
+ GLenum light
+ GLenum pname
+ GLfixed param
+
+
+ void glLightxv
+ GLenum light
+ GLenum pname
+ const GLfixed *params
+
+
+ void glLightxvOES
+ GLenum light
+ GLenum pname
+ const GLfixed *params
+
+
+ void glLineStipple
+ GLint factor
+ GLushort pattern
+
+
+
+ void glLineWidth
+ GLfloat width
+
+
+
+ void glLineWidthx
+ GLfixed width
+
+
+ void glLineWidthxOES
+ GLfixed width
+
+
+ void glLinkProgram
+ GLuint program
+
+
+ void glLinkProgramARB
+ GLhandleARB programObj
+
+
+
+ void glListBase
+ GLuint base
+
+
+
+ void glListDrawCommandsStatesClientNV
+ GLuint list
+ GLuint segment
+ const void **indirects
+ const GLsizei *sizes
+ const GLuint *states
+ const GLuint *fbos
+ GLuint count
+
+
+ void glListParameterfSGIX
+ GLuint list
+ GLenum pname
+ GLfloat param
+
+
+
+ void glListParameterfvSGIX
+ GLuint list
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glListParameteriSGIX
+ GLuint list
+ GLenum pname
+ GLint param
+
+
+
+ void glListParameterivSGIX
+ GLuint list
+ GLenum pname
+ const GLint *params
+
+
+
+ void glLoadIdentity
+
+
+
+ void glLoadIdentityDeformationMapSGIX
+ GLbitfield mask
+
+
+
+ void glLoadMatrixd
+ const GLdouble *m
+
+
+
+ void glLoadMatrixf
+ const GLfloat *m
+
+
+
+ void glLoadMatrixx
+ const GLfixed *m
+
+
+ void glLoadMatrixxOES
+ const GLfixed *m
+
+
+ void glLoadName
+ GLuint name
+
+
+
+ void glLoadPaletteFromModelViewMatrixOES
+
+
+ void glLoadProgramNV
+ GLenum target
+ GLuint id
+ GLsizei len
+ const GLubyte *program
+
+
+
+ void glLoadTransposeMatrixd
+ const GLdouble *m
+
+
+ void glLoadTransposeMatrixdARB
+ const GLdouble *m
+
+
+
+ void glLoadTransposeMatrixf
+ const GLfloat *m
+
+
+ void glLoadTransposeMatrixfARB
+ const GLfloat *m
+
+
+
+ void glLoadTransposeMatrixxOES
+ const GLfixed *m
+
+
+ void glLockArraysEXT
+ GLint first
+ GLsizei count
+
+
+ void glLogicOp
+ GLenum opcode
+
+
+
+ void glMakeBufferNonResidentNV
+ GLenum target
+
+
+ void glMakeBufferResidentNV
+ GLenum target
+ GLenum access
+
+
+ void glMakeImageHandleNonResidentARB
+ GLuint64 handle
+
+
+ void glMakeImageHandleNonResidentNV
+ GLuint64 handle
+
+
+ void glMakeImageHandleResidentARB
+ GLuint64 handle
+ GLenum access
+
+
+ void glMakeImageHandleResidentNV
+ GLuint64 handle
+ GLenum access
+
+
+ void glMakeNamedBufferNonResidentNV
+ GLuint buffer
+
+
+ void glMakeNamedBufferResidentNV
+ GLuint buffer
+ GLenum access
+
+
+ void glMakeTextureHandleNonResidentARB
+ GLuint64 handle
+
+
+ void glMakeTextureHandleNonResidentNV
+ GLuint64 handle
+
+
+ void glMakeTextureHandleResidentARB
+ GLuint64 handle
+
+
+ void glMakeTextureHandleResidentNV
+ GLuint64 handle
+
+
+ void glMap1d
+ GLenum target
+ GLdouble u1
+ GLdouble u2
+ GLint stride
+ GLint order
+ const GLdouble *points
+
+
+
+ void glMap1f
+ GLenum target
+ GLfloat u1
+ GLfloat u2
+ GLint stride
+ GLint order
+ const GLfloat *points
+
+
+
+ void glMap1xOES
+ GLenum target
+ GLfixed u1
+ GLfixed u2
+ GLint stride
+ GLint order
+ GLfixed points
+
+
+ void glMap2d
+ GLenum target
+ GLdouble u1
+ GLdouble u2
+ GLint ustride
+ GLint uorder
+ GLdouble v1
+ GLdouble v2
+ GLint vstride
+ GLint vorder
+ const GLdouble *points
+
+
+
+ void glMap2f
+ GLenum target
+ GLfloat u1
+ GLfloat u2
+ GLint ustride
+ GLint uorder
+ GLfloat v1
+ GLfloat v2
+ GLint vstride
+ GLint vorder
+ const GLfloat *points
+
+
+
+ void glMap2xOES
+ GLenum target
+ GLfixed u1
+ GLfixed u2
+ GLint ustride
+ GLint uorder
+ GLfixed v1
+ GLfixed v2
+ GLint vstride
+ GLint vorder
+ GLfixed points
+
+
+ void *glMapBuffer
+ GLenum target
+ GLenum access
+
+
+ void *glMapBufferARB
+ GLenum target
+ GLenum access
+
+
+
+ void *glMapBufferOES
+ GLenum target
+ GLenum access
+
+
+
+ void *glMapBufferRange
+ GLenum target
+ GLintptr offset
+ GLsizeiptr length
+ GLbitfield access
+
+
+
+ void *glMapBufferRangeEXT
+ GLenum target
+ GLintptr offset
+ GLsizeiptr length
+ GLbitfield access
+
+
+
+ void glMapControlPointsNV
+ GLenum target
+ GLuint index
+ GLenum type
+ GLsizei ustride
+ GLsizei vstride
+ GLint uorder
+ GLint vorder
+ GLboolean packed
+ const void *points
+
+
+ void glMapGrid1d
+ GLint un
+ GLdouble u1
+ GLdouble u2
+
+
+
+ void glMapGrid1f
+ GLint un
+ GLfloat u1
+ GLfloat u2
+
+
+
+ void glMapGrid1xOES
+ GLint n
+ GLfixed u1
+ GLfixed u2
+
+
+ void glMapGrid2d
+ GLint un
+ GLdouble u1
+ GLdouble u2
+ GLint vn
+ GLdouble v1
+ GLdouble v2
+
+
+
+ void glMapGrid2f
+ GLint un
+ GLfloat u1
+ GLfloat u2
+ GLint vn
+ GLfloat v1
+ GLfloat v2
+
+
+
+ void glMapGrid2xOES
+ GLint n
+ GLfixed u1
+ GLfixed u2
+ GLfixed v1
+ GLfixed v2
+
+
+ void *glMapNamedBuffer
+ GLuint buffer
+ GLenum access
+
+
+ void *glMapNamedBufferEXT
+ GLuint buffer
+ GLenum access
+
+
+ void *glMapNamedBufferRange
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr length
+ GLbitfield access
+
+
+ void *glMapNamedBufferRangeEXT
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr length
+ GLbitfield access
+
+
+ void *glMapObjectBufferATI
+ GLuint buffer
+
+
+ void glMapParameterfvNV
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+ void glMapParameterivNV
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+ void *glMapTexture2DINTEL
+ GLuint texture
+ GLint level
+ GLbitfield access
+ GLint *stride
+ GLenum *layout
+
+
+ void glMapVertexAttrib1dAPPLE
+ GLuint index
+ GLuint size
+ GLdouble u1
+ GLdouble u2
+ GLint stride
+ GLint order
+ const GLdouble *points
+
+
+ void glMapVertexAttrib1fAPPLE
+ GLuint index
+ GLuint size
+ GLfloat u1
+ GLfloat u2
+ GLint stride
+ GLint order
+ const GLfloat *points
+
+
+ void glMapVertexAttrib2dAPPLE
+ GLuint index
+ GLuint size
+ GLdouble u1
+ GLdouble u2
+ GLint ustride
+ GLint uorder
+ GLdouble v1
+ GLdouble v2
+ GLint vstride
+ GLint vorder
+ const GLdouble *points
+
+
+ void glMapVertexAttrib2fAPPLE
+ GLuint index
+ GLuint size
+ GLfloat u1
+ GLfloat u2
+ GLint ustride
+ GLint uorder
+ GLfloat v1
+ GLfloat v2
+ GLint vstride
+ GLint vorder
+ const GLfloat *points
+
+
+ void glMaterialf
+ GLenum face
+ GLenum pname
+ GLfloat param
+
+
+
+ void glMaterialfv
+ GLenum face
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glMateriali
+ GLenum face
+ GLenum pname
+ GLint param
+
+
+
+ void glMaterialiv
+ GLenum face
+ GLenum pname
+ const GLint *params
+
+
+
+ void glMaterialx
+ GLenum face
+ GLenum pname
+ GLfixed param
+
+
+ void glMaterialxOES
+ GLenum face
+ GLenum pname
+ GLfixed param
+
+
+ void glMaterialxv
+ GLenum face
+ GLenum pname
+ const GLfixed *param
+
+
+ void glMaterialxvOES
+ GLenum face
+ GLenum pname
+ const GLfixed *param
+
+
+ void glMatrixFrustumEXT
+ GLenum mode
+ GLdouble left
+ GLdouble right
+ GLdouble bottom
+ GLdouble top
+ GLdouble zNear
+ GLdouble zFar
+
+
+ void glMatrixIndexPointerARB
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glMatrixIndexPointerOES
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glMatrixIndexubvARB
+ GLint size
+ const GLubyte *indices
+
+
+
+ void glMatrixIndexuivARB
+ GLint size
+ const GLuint *indices
+
+
+
+ void glMatrixIndexusvARB
+ GLint size
+ const GLushort *indices
+
+
+
+ void glMatrixLoad3x2fNV
+ GLenum matrixMode
+ const GLfloat *m
+
+
+ void glMatrixLoad3x3fNV
+ GLenum matrixMode
+ const GLfloat *m
+
+
+ void glMatrixLoadIdentityEXT
+ GLenum mode
+
+
+ void glMatrixLoadTranspose3x3fNV
+ GLenum matrixMode
+ const GLfloat *m
+
+
+ void glMatrixLoadTransposedEXT
+ GLenum mode
+ const GLdouble *m
+
+
+ void glMatrixLoadTransposefEXT
+ GLenum mode
+ const GLfloat *m
+
+
+ void glMatrixLoaddEXT
+ GLenum mode
+ const GLdouble *m
+
+
+ void glMatrixLoadfEXT
+ GLenum mode
+ const GLfloat *m
+
+
+ void glMatrixMode
+ GLenum mode
+
+
+
+ void glMatrixMult3x2fNV
+ GLenum matrixMode
+ const GLfloat *m
+
+
+ void glMatrixMult3x3fNV
+ GLenum matrixMode
+ const GLfloat *m
+
+
+ void glMatrixMultTranspose3x3fNV
+ GLenum matrixMode
+ const GLfloat *m
+
+
+ void glMatrixMultTransposedEXT
+ GLenum mode
+ const GLdouble *m
+
+
+ void glMatrixMultTransposefEXT
+ GLenum mode
+ const GLfloat *m
+
+
+ void glMatrixMultdEXT
+ GLenum mode
+ const GLdouble *m
+
+
+ void glMatrixMultfEXT
+ GLenum mode
+ const GLfloat *m
+
+
+ void glMatrixOrthoEXT
+ GLenum mode
+ GLdouble left
+ GLdouble right
+ GLdouble bottom
+ GLdouble top
+ GLdouble zNear
+ GLdouble zFar
+
+
+ void glMatrixPopEXT
+ GLenum mode
+
+
+ void glMatrixPushEXT
+ GLenum mode
+
+
+ void glMatrixRotatedEXT
+ GLenum mode
+ GLdouble angle
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+ void glMatrixRotatefEXT
+ GLenum mode
+ GLfloat angle
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glMatrixScaledEXT
+ GLenum mode
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+ void glMatrixScalefEXT
+ GLenum mode
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glMatrixTranslatedEXT
+ GLenum mode
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+ void glMatrixTranslatefEXT
+ GLenum mode
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glMemoryBarrier
+ GLbitfield barriers
+
+
+ void glMemoryBarrierByRegion
+ GLbitfield barriers
+
+
+ void glMemoryBarrierEXT
+ GLbitfield barriers
+
+
+
+ void glMinSampleShading
+ GLfloat value
+
+
+ void glMinSampleShadingARB
+ GLfloat value
+
+
+
+ void glMinSampleShadingOES
+ GLfloat value
+
+
+
+ void glMinmax
+ GLenum target
+ GLenum internalformat
+ GLboolean sink
+
+
+
+ void glMinmaxEXT
+ GLenum target
+ GLenum internalformat
+ GLboolean sink
+
+
+
+
+ void glMultMatrixd
+ const GLdouble *m
+
+
+
+ void glMultMatrixf
+ const GLfloat *m
+
+
+
+ void glMultMatrixx
+ const GLfixed *m
+
+
+ void glMultMatrixxOES
+ const GLfixed *m
+
+
+ void glMultTransposeMatrixd
+ const GLdouble *m
+
+
+ void glMultTransposeMatrixdARB
+ const GLdouble *m
+
+
+
+ void glMultTransposeMatrixf
+ const GLfloat *m
+
+
+ void glMultTransposeMatrixfARB
+ const GLfloat *m
+
+
+
+ void glMultTransposeMatrixxOES
+ const GLfixed *m
+
+
+ void glMultiDrawArrays
+ GLenum mode
+ const GLint *first
+ const GLsizei *count
+ GLsizei drawcount
+
+
+ void glMultiDrawArraysEXT
+ GLenum mode
+ const GLint *first
+ const GLsizei *count
+ GLsizei primcount
+
+
+
+ void glMultiDrawArraysIndirect
+ GLenum mode
+ const void *indirect
+ GLsizei drawcount
+ GLsizei stride
+
+
+ void glMultiDrawArraysIndirectAMD
+ GLenum mode
+ const void *indirect
+ GLsizei primcount
+ GLsizei stride
+
+
+
+ void glMultiDrawArraysIndirectEXT
+ GLenum mode
+ const void *indirect
+ GLsizei drawcount
+ GLsizei stride
+
+
+
+ void glMultiDrawArraysIndirectBindlessCountNV
+ GLenum mode
+ const void *indirect
+ GLsizei drawCount
+ GLsizei maxDrawCount
+ GLsizei stride
+ GLint vertexBufferCount
+
+
+ void glMultiDrawArraysIndirectBindlessNV
+ GLenum mode
+ const void *indirect
+ GLsizei drawCount
+ GLsizei stride
+ GLint vertexBufferCount
+
+
+ void glMultiDrawArraysIndirectCountARB
+ GLenum mode
+ GLintptr indirect
+ GLintptr drawcount
+ GLsizei maxdrawcount
+ GLsizei stride
+
+
+ void glMultiDrawElementArrayAPPLE
+ GLenum mode
+ const GLint *first
+ const GLsizei *count
+ GLsizei primcount
+
+
+ void glMultiDrawElements
+ GLenum mode
+ const GLsizei *count
+ GLenum type
+ const void *const*indices
+ GLsizei drawcount
+
+
+ void glMultiDrawElementsBaseVertex
+ GLenum mode
+ const GLsizei *count
+ GLenum type
+ const void *const*indices
+ GLsizei drawcount
+ const GLint *basevertex
+
+
+ void glMultiDrawElementsBaseVertexEXT
+ GLenum mode
+ const GLsizei *count
+ GLenum type
+ const void *const*indices
+ GLsizei primcount
+ const GLint *basevertex
+
+
+
+ void glMultiDrawElementsBaseVertexOES
+ GLenum mode
+ const GLsizei *count
+ GLenum type
+ const void *const*indices
+ GLsizei primcount
+ const GLint *basevertex
+
+
+
+ void glMultiDrawElementsEXT
+ GLenum mode
+ const GLsizei *count
+ GLenum type
+ const void *const*indices
+ GLsizei primcount
+
+
+
+ void glMultiDrawElementsIndirect
+ GLenum mode
+ GLenum type
+ const void *indirect
+ GLsizei drawcount
+ GLsizei stride
+
+
+ void glMultiDrawElementsIndirectEXT
+ GLenum mode
+ GLenum type
+ const void *indirect
+ GLsizei drawcount
+ GLsizei stride
+
+
+
+ void glMultiDrawElementsIndirectAMD
+ GLenum mode
+ GLenum type
+ const void *indirect
+ GLsizei primcount
+ GLsizei stride
+
+
+
+ void glMultiDrawElementsIndirectBindlessCountNV
+ GLenum mode
+ GLenum type
+ const void *indirect
+ GLsizei drawCount
+ GLsizei maxDrawCount
+ GLsizei stride
+ GLint vertexBufferCount
+
+
+ void glMultiDrawElementsIndirectBindlessNV
+ GLenum mode
+ GLenum type
+ const void *indirect
+ GLsizei drawCount
+ GLsizei stride
+ GLint vertexBufferCount
+
+
+ void glMultiDrawElementsIndirectCountARB
+ GLenum mode
+ GLenum type
+ GLintptr indirect
+ GLintptr drawcount
+ GLsizei maxdrawcount
+ GLsizei stride
+
+
+ void glMultiDrawRangeElementArrayAPPLE
+ GLenum mode
+ GLuint start
+ GLuint end
+ const GLint *first
+ const GLsizei *count
+ GLsizei primcount
+
+
+ void glMultiModeDrawArraysIBM
+ const GLenum *mode
+ const GLint *first
+ const GLsizei *count
+ GLsizei primcount
+ GLint modestride
+
+
+ void glMultiModeDrawElementsIBM
+ const GLenum *mode
+ const GLsizei *count
+ GLenum type
+ const void *const*indices
+ GLsizei primcount
+ GLint modestride
+
+
+ void glMultiTexBufferEXT
+ GLenum texunit
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+
+
+ void glMultiTexCoord1bOES
+ GLenum texture
+ GLbyte s
+
+
+ void glMultiTexCoord1bvOES
+ GLenum texture
+ const GLbyte *coords
+
+
+ void glMultiTexCoord1d
+ GLenum target
+ GLdouble s
+
+
+
+ void glMultiTexCoord1dARB
+ GLenum target
+ GLdouble s
+
+
+
+
+ void glMultiTexCoord1dv
+ GLenum target
+ const GLdouble *v
+
+
+
+ void glMultiTexCoord1dvARB
+ GLenum target
+ const GLdouble *v
+
+
+
+
+ void glMultiTexCoord1f
+ GLenum target
+ GLfloat s
+
+
+
+ void glMultiTexCoord1fARB
+ GLenum target
+ GLfloat s
+
+
+
+
+ void glMultiTexCoord1fv
+ GLenum target
+ const GLfloat *v
+
+
+
+ void glMultiTexCoord1fvARB
+ GLenum target
+ const GLfloat *v
+
+
+
+
+ void glMultiTexCoord1hNV
+ GLenum target
+ GLhalfNV s
+
+
+
+ void glMultiTexCoord1hvNV
+ GLenum target
+ const GLhalfNV *v
+
+
+
+ void glMultiTexCoord1i
+ GLenum target
+ GLint s
+
+
+
+ void glMultiTexCoord1iARB
+ GLenum target
+ GLint s
+
+
+
+
+ void glMultiTexCoord1iv
+ GLenum target
+ const GLint *v
+
+
+
+ void glMultiTexCoord1ivARB
+ GLenum target
+ const GLint *v
+
+
+
+
+ void glMultiTexCoord1s
+ GLenum target
+ GLshort s
+
+
+
+ void glMultiTexCoord1sARB
+ GLenum target
+ GLshort s
+
+
+
+
+ void glMultiTexCoord1sv
+ GLenum target
+ const GLshort *v
+
+
+
+ void glMultiTexCoord1svARB
+ GLenum target
+ const GLshort *v
+
+
+
+
+ void glMultiTexCoord1xOES
+ GLenum texture
+ GLfixed s
+
+
+ void glMultiTexCoord1xvOES
+ GLenum texture
+ const GLfixed *coords
+
+
+ void glMultiTexCoord2bOES
+ GLenum texture
+ GLbyte s
+ GLbyte t
+
+
+ void glMultiTexCoord2bvOES
+ GLenum texture
+ const GLbyte *coords
+
+
+ void glMultiTexCoord2d
+ GLenum target
+ GLdouble s
+ GLdouble t
+
+
+
+ void glMultiTexCoord2dARB
+ GLenum target
+ GLdouble s
+ GLdouble t
+
+
+
+
+ void glMultiTexCoord2dv
+ GLenum target
+ const GLdouble *v
+
+
+
+ void glMultiTexCoord2dvARB
+ GLenum target
+ const GLdouble *v
+
+
+
+
+ void glMultiTexCoord2f
+ GLenum target
+ GLfloat s
+ GLfloat t
+
+
+
+ void glMultiTexCoord2fARB
+ GLenum target
+ GLfloat s
+ GLfloat t
+
+
+
+
+ void glMultiTexCoord2fv
+ GLenum target
+ const GLfloat *v
+
+
+
+ void glMultiTexCoord2fvARB
+ GLenum target
+ const GLfloat *v
+
+
+
+
+ void glMultiTexCoord2hNV
+ GLenum target
+ GLhalfNV s
+ GLhalfNV t
+
+
+
+ void glMultiTexCoord2hvNV
+ GLenum target
+ const GLhalfNV *v
+
+
+
+ void glMultiTexCoord2i
+ GLenum target
+ GLint s
+ GLint t
+
+
+
+ void glMultiTexCoord2iARB
+ GLenum target
+ GLint s
+ GLint t
+
+
+
+
+ void glMultiTexCoord2iv
+ GLenum target
+ const GLint *v
+
+
+
+ void glMultiTexCoord2ivARB
+ GLenum target
+ const GLint *v
+
+
+
+
+ void glMultiTexCoord2s
+ GLenum target
+ GLshort s
+ GLshort t
+
+
+
+ void glMultiTexCoord2sARB
+ GLenum target
+ GLshort s
+ GLshort t
+
+
+
+
+ void glMultiTexCoord2sv
+ GLenum target
+ const GLshort *v
+
+
+
+ void glMultiTexCoord2svARB
+ GLenum target
+ const GLshort *v
+
+
+
+
+ void glMultiTexCoord2xOES
+ GLenum texture
+ GLfixed s
+ GLfixed t
+
+
+ void glMultiTexCoord2xvOES
+ GLenum texture
+ const GLfixed *coords
+
+
+ void glMultiTexCoord3bOES
+ GLenum texture
+ GLbyte s
+ GLbyte t
+ GLbyte r
+
+
+ void glMultiTexCoord3bvOES
+ GLenum texture
+ const GLbyte *coords
+
+
+ void glMultiTexCoord3d
+ GLenum target
+ GLdouble s
+ GLdouble t
+ GLdouble r
+
+
+
+ void glMultiTexCoord3dARB
+ GLenum target
+ GLdouble s
+ GLdouble t
+ GLdouble r
+
+
+
+
+ void glMultiTexCoord3dv
+ GLenum target
+ const GLdouble *v
+
+
+
+ void glMultiTexCoord3dvARB
+ GLenum target
+ const GLdouble *v
+
+
+
+
+ void glMultiTexCoord3f
+ GLenum target
+ GLfloat s
+ GLfloat t
+ GLfloat r
+
+
+
+ void glMultiTexCoord3fARB
+ GLenum target
+ GLfloat s
+ GLfloat t
+ GLfloat r
+
+
+
+
+ void glMultiTexCoord3fv
+ GLenum target
+ const GLfloat *v
+
+
+
+ void glMultiTexCoord3fvARB
+ GLenum target
+ const GLfloat *v
+
+
+
+
+ void glMultiTexCoord3hNV
+ GLenum target
+ GLhalfNV s
+ GLhalfNV t
+ GLhalfNV r
+
+
+
+ void glMultiTexCoord3hvNV
+ GLenum target
+ const GLhalfNV *v
+
+
+
+ void glMultiTexCoord3i
+ GLenum target
+ GLint s
+ GLint t
+ GLint r
+
+
+
+ void glMultiTexCoord3iARB
+ GLenum target
+ GLint s
+ GLint t
+ GLint r
+
+
+
+
+ void glMultiTexCoord3iv
+ GLenum target
+ const GLint *v
+
+
+
+ void glMultiTexCoord3ivARB
+ GLenum target
+ const GLint *v
+
+
+
+
+ void glMultiTexCoord3s
+ GLenum target
+ GLshort s
+ GLshort t
+ GLshort r
+
+
+
+ void glMultiTexCoord3sARB
+ GLenum target
+ GLshort s
+ GLshort t
+ GLshort r
+
+
+
+
+ void glMultiTexCoord3sv
+ GLenum target
+ const GLshort *v
+
+
+
+ void glMultiTexCoord3svARB
+ GLenum target
+ const GLshort *v
+
+
+
+
+ void glMultiTexCoord3xOES
+ GLenum texture
+ GLfixed s
+ GLfixed t
+ GLfixed r
+
+
+ void glMultiTexCoord3xvOES
+ GLenum texture
+ const GLfixed *coords
+
+
+ void glMultiTexCoord4bOES
+ GLenum texture
+ GLbyte s
+ GLbyte t
+ GLbyte r
+ GLbyte q
+
+
+ void glMultiTexCoord4bvOES
+ GLenum texture
+ const GLbyte *coords
+
+
+ void glMultiTexCoord4d
+ GLenum target
+ GLdouble s
+ GLdouble t
+ GLdouble r
+ GLdouble q
+
+
+
+ void glMultiTexCoord4dARB
+ GLenum target
+ GLdouble s
+ GLdouble t
+ GLdouble r
+ GLdouble q
+
+
+
+
+ void glMultiTexCoord4dv
+ GLenum target
+ const GLdouble *v
+
+
+
+ void glMultiTexCoord4dvARB
+ GLenum target
+ const GLdouble *v
+
+
+
+
+ void glMultiTexCoord4f
+ GLenum target
+ GLfloat s
+ GLfloat t
+ GLfloat r
+ GLfloat q
+
+
+
+ void glMultiTexCoord4fARB
+ GLenum target
+ GLfloat s
+ GLfloat t
+ GLfloat r
+ GLfloat q
+
+
+
+
+ void glMultiTexCoord4fv
+ GLenum target
+ const GLfloat *v
+
+
+
+ void glMultiTexCoord4fvARB
+ GLenum target
+ const GLfloat *v
+
+
+
+
+ void glMultiTexCoord4hNV
+ GLenum target
+ GLhalfNV s
+ GLhalfNV t
+ GLhalfNV r
+ GLhalfNV q
+
+
+
+ void glMultiTexCoord4hvNV
+ GLenum target
+ const GLhalfNV *v
+
+
+
+ void glMultiTexCoord4i
+ GLenum target
+ GLint s
+ GLint t
+ GLint r
+ GLint q
+
+
+
+ void glMultiTexCoord4iARB
+ GLenum target
+ GLint s
+ GLint t
+ GLint r
+ GLint q
+
+
+
+
+ void glMultiTexCoord4iv
+ GLenum target
+ const GLint *v
+
+
+
+ void glMultiTexCoord4ivARB
+ GLenum target
+ const GLint *v
+
+
+
+
+ void glMultiTexCoord4s
+ GLenum target
+ GLshort s
+ GLshort t
+ GLshort r
+ GLshort q
+
+
+
+ void glMultiTexCoord4sARB
+ GLenum target
+ GLshort s
+ GLshort t
+ GLshort r
+ GLshort q
+
+
+
+
+ void glMultiTexCoord4sv
+ GLenum target
+ const GLshort *v
+
+
+
+ void glMultiTexCoord4svARB
+ GLenum target
+ const GLshort *v
+
+
+
+
+ void glMultiTexCoord4x
+ GLenum texture
+ GLfixed s
+ GLfixed t
+ GLfixed r
+ GLfixed q
+
+
+ void glMultiTexCoord4xOES
+ GLenum texture
+ GLfixed s
+ GLfixed t
+ GLfixed r
+ GLfixed q
+
+
+ void glMultiTexCoord4xvOES
+ GLenum texture
+ const GLfixed *coords
+
+
+ void glMultiTexCoordP1ui
+ GLenum texture
+ GLenum type
+ GLuint coords
+
+
+ void glMultiTexCoordP1uiv
+ GLenum texture
+ GLenum type
+ const GLuint *coords
+
+
+ void glMultiTexCoordP2ui
+ GLenum texture
+ GLenum type
+ GLuint coords
+
+
+ void glMultiTexCoordP2uiv
+ GLenum texture
+ GLenum type
+ const GLuint *coords
+
+
+ void glMultiTexCoordP3ui
+ GLenum texture
+ GLenum type
+ GLuint coords
+
+
+ void glMultiTexCoordP3uiv
+ GLenum texture
+ GLenum type
+ const GLuint *coords
+
+
+ void glMultiTexCoordP4ui
+ GLenum texture
+ GLenum type
+ GLuint coords
+
+
+ void glMultiTexCoordP4uiv
+ GLenum texture
+ GLenum type
+ const GLuint *coords
+
+
+ void glMultiTexCoordPointerEXT
+ GLenum texunit
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glMultiTexEnvfEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLfloat param
+
+
+
+ void glMultiTexEnvfvEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+ void glMultiTexEnviEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+
+ void glMultiTexEnvivEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+ void glMultiTexGendEXT
+ GLenum texunit
+ GLenum coord
+ GLenum pname
+ GLdouble param
+
+
+
+ void glMultiTexGendvEXT
+ GLenum texunit
+ GLenum coord
+ GLenum pname
+ const GLdouble *params
+
+
+ void glMultiTexGenfEXT
+ GLenum texunit
+ GLenum coord
+ GLenum pname
+ GLfloat param
+
+
+
+ void glMultiTexGenfvEXT
+ GLenum texunit
+ GLenum coord
+ GLenum pname
+ const GLfloat *params
+
+
+ void glMultiTexGeniEXT
+ GLenum texunit
+ GLenum coord
+ GLenum pname
+ GLint param
+
+
+
+ void glMultiTexGenivEXT
+ GLenum texunit
+ GLenum coord
+ GLenum pname
+ const GLint *params
+
+
+ void glMultiTexImage1DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint internalformat
+ GLsizei width
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glMultiTexImage2DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint internalformat
+ GLsizei width
+ GLsizei height
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glMultiTexImage3DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glMultiTexParameterIivEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+ void glMultiTexParameterIuivEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ const GLuint *params
+
+
+ void glMultiTexParameterfEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLfloat param
+
+
+
+ void glMultiTexParameterfvEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+ void glMultiTexParameteriEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+
+ void glMultiTexParameterivEXT
+ GLenum texunit
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+ void glMultiTexRenderbufferEXT
+ GLenum texunit
+ GLenum target
+ GLuint renderbuffer
+
+
+ void glMultiTexSubImage1DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glMultiTexSubImage2DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glMultiTexSubImage3DEXT
+ GLenum texunit
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glNamedBufferData
+ GLuint buffer
+ GLsizeiptr size
+ const void *data
+ GLenum usage
+
+
+ void glNamedBufferDataEXT
+ GLuint buffer
+ GLsizeiptr size
+ const void *data
+ GLenum usage
+
+
+ void glNamedBufferPageCommitmentARB
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+ GLboolean commit
+
+
+ void glNamedBufferPageCommitmentEXT
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+ GLboolean commit
+
+
+ void glNamedBufferStorage
+ GLuint buffer
+ GLsizeiptr size
+ const void *data
+ GLbitfield flags
+
+
+ void glNamedBufferStorageEXT
+ GLuint buffer
+ GLsizeiptr size
+ const void *data
+ GLbitfield flags
+
+
+
+ void glNamedBufferSubData
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+ const void *data
+
+
+ void glNamedBufferSubDataEXT
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+ const void *data
+
+
+
+ void glNamedCopyBufferSubDataEXT
+ GLuint readBuffer
+ GLuint writeBuffer
+ GLintptr readOffset
+ GLintptr writeOffset
+ GLsizeiptr size
+
+
+ void glNamedFramebufferDrawBuffer
+ GLuint framebuffer
+ GLenum buf
+
+
+ void glNamedFramebufferDrawBuffers
+ GLuint framebuffer
+ GLsizei n
+ const GLenum *bufs
+
+
+ void glNamedFramebufferParameteri
+ GLuint framebuffer
+ GLenum pname
+ GLint param
+
+
+ void glNamedFramebufferParameteriEXT
+ GLuint framebuffer
+ GLenum pname
+ GLint param
+
+
+ void glNamedFramebufferReadBuffer
+ GLuint framebuffer
+ GLenum src
+
+
+ void glNamedFramebufferRenderbuffer
+ GLuint framebuffer
+ GLenum attachment
+ GLenum renderbuffertarget
+ GLuint renderbuffer
+
+
+ void glNamedFramebufferRenderbufferEXT
+ GLuint framebuffer
+ GLenum attachment
+ GLenum renderbuffertarget
+ GLuint renderbuffer
+
+
+ void glNamedFramebufferTexture
+ GLuint framebuffer
+ GLenum attachment
+ GLuint texture
+ GLint level
+
+
+ void glNamedFramebufferTexture1DEXT
+ GLuint framebuffer
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+
+
+ void glNamedFramebufferTexture2DEXT
+ GLuint framebuffer
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+
+
+ void glNamedFramebufferTexture3DEXT
+ GLuint framebuffer
+ GLenum attachment
+ GLenum textarget
+ GLuint texture
+ GLint level
+ GLint zoffset
+
+
+ void glNamedFramebufferTextureEXT
+ GLuint framebuffer
+ GLenum attachment
+ GLuint texture
+ GLint level
+
+
+ void glNamedFramebufferTextureFaceEXT
+ GLuint framebuffer
+ GLenum attachment
+ GLuint texture
+ GLint level
+ GLenum face
+
+
+ void glNamedFramebufferTextureLayer
+ GLuint framebuffer
+ GLenum attachment
+ GLuint texture
+ GLint level
+ GLint layer
+
+
+ void glNamedFramebufferTextureLayerEXT
+ GLuint framebuffer
+ GLenum attachment
+ GLuint texture
+ GLint level
+ GLint layer
+
+
+ void glNamedProgramLocalParameter4dEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glNamedProgramLocalParameter4dvEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ const GLdouble *params
+
+
+ void glNamedProgramLocalParameter4fEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+ void glNamedProgramLocalParameter4fvEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ const GLfloat *params
+
+
+ void glNamedProgramLocalParameterI4iEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLint x
+ GLint y
+ GLint z
+ GLint w
+
+
+
+ void glNamedProgramLocalParameterI4ivEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ const GLint *params
+
+
+ void glNamedProgramLocalParameterI4uiEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLuint x
+ GLuint y
+ GLuint z
+ GLuint w
+
+
+
+ void glNamedProgramLocalParameterI4uivEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ const GLuint *params
+
+
+ void glNamedProgramLocalParameters4fvEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLfloat *params
+
+
+ void glNamedProgramLocalParametersI4ivEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLint *params
+
+
+ void glNamedProgramLocalParametersI4uivEXT
+ GLuint program
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLuint *params
+
+
+ void glNamedProgramStringEXT
+ GLuint program
+ GLenum target
+ GLenum format
+ GLsizei len
+ const void *string
+
+
+ void glNamedRenderbufferStorage
+ GLuint renderbuffer
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glNamedRenderbufferStorageEXT
+ GLuint renderbuffer
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glNamedRenderbufferStorageMultisample
+ GLuint renderbuffer
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glNamedRenderbufferStorageMultisampleCoverageEXT
+ GLuint renderbuffer
+ GLsizei coverageSamples
+ GLsizei colorSamples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glNamedRenderbufferStorageMultisampleEXT
+ GLuint renderbuffer
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glNamedStringARB
+ GLenum type
+ GLint namelen
+ const GLchar *name
+ GLint stringlen
+ const GLchar *string
+
+
+ void glNewList
+ GLuint list
+ GLenum mode
+
+
+
+ GLuint glNewObjectBufferATI
+ GLsizei size
+ const void *pointer
+ GLenum usage
+
+
+ void glNormal3b
+ GLbyte nx
+ GLbyte ny
+ GLbyte nz
+
+
+
+ void glNormal3bv
+ const GLbyte *v
+
+
+
+ void glNormal3d
+ GLdouble nx
+ GLdouble ny
+ GLdouble nz
+
+
+
+ void glNormal3dv
+ const GLdouble *v
+
+
+
+ void glNormal3f
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+
+
+
+ void glNormal3fVertex3fSUN
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glNormal3fVertex3fvSUN
+ const GLfloat *n
+ const GLfloat *v
+
+
+ void glNormal3fv
+ const GLfloat *v
+
+
+
+ void glNormal3hNV
+ GLhalfNV nx
+ GLhalfNV ny
+ GLhalfNV nz
+
+
+
+ void glNormal3hvNV
+ const GLhalfNV *v
+
+
+
+ void glNormal3i
+ GLint nx
+ GLint ny
+ GLint nz
+
+
+
+ void glNormal3iv
+ const GLint *v
+
+
+
+ void glNormal3s
+ GLshort nx
+ GLshort ny
+ GLshort nz
+
+
+
+ void glNormal3sv
+ const GLshort *v
+
+
+
+ void glNormal3x
+ GLfixed nx
+ GLfixed ny
+ GLfixed nz
+
+
+ void glNormal3xOES
+ GLfixed nx
+ GLfixed ny
+ GLfixed nz
+
+
+ void glNormal3xvOES
+ const GLfixed *coords
+
+
+ void glNormalFormatNV
+ GLenum type
+ GLsizei stride
+
+
+ void glNormalP3ui
+ GLenum type
+ GLuint coords
+
+
+ void glNormalP3uiv
+ GLenum type
+ const GLuint *coords
+
+
+ void glNormalPointer
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glNormalPointerEXT
+ GLenum type
+ GLsizei stride
+ GLsizei count
+ const void *pointer
+
+
+ void glNormalPointerListIBM
+ GLenum type
+ GLint stride
+ const void **pointer
+ GLint ptrstride
+
+
+ void glNormalPointervINTEL
+ GLenum type
+ const void **pointer
+
+
+ void glNormalStream3bATI
+ GLenum stream
+ GLbyte nx
+ GLbyte ny
+ GLbyte nz
+
+
+ void glNormalStream3bvATI
+ GLenum stream
+ const GLbyte *coords
+
+
+ void glNormalStream3dATI
+ GLenum stream
+ GLdouble nx
+ GLdouble ny
+ GLdouble nz
+
+
+ void glNormalStream3dvATI
+ GLenum stream
+ const GLdouble *coords
+
+
+ void glNormalStream3fATI
+ GLenum stream
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+
+
+ void glNormalStream3fvATI
+ GLenum stream
+ const GLfloat *coords
+
+
+ void glNormalStream3iATI
+ GLenum stream
+ GLint nx
+ GLint ny
+ GLint nz
+
+
+ void glNormalStream3ivATI
+ GLenum stream
+ const GLint *coords
+
+
+ void glNormalStream3sATI
+ GLenum stream
+ GLshort nx
+ GLshort ny
+ GLshort nz
+
+
+ void glNormalStream3svATI
+ GLenum stream
+ const GLshort *coords
+
+
+ void glObjectLabel
+ GLenum identifier
+ GLuint name
+ GLsizei length
+ const GLchar *label
+
+
+ void glObjectLabelKHR
+ GLenum identifier
+ GLuint name
+ GLsizei length
+ const GLchar *label
+
+
+
+ void glObjectPtrLabel
+ const void *ptr
+ GLsizei length
+ const GLchar *label
+
+
+ void glObjectPtrLabelKHR
+ const void *ptr
+ GLsizei length
+ const GLchar *label
+
+
+
+ GLenum glObjectPurgeableAPPLE
+ GLenum objectType
+ GLuint name
+ GLenum option
+
+
+ GLenum glObjectUnpurgeableAPPLE
+ GLenum objectType
+ GLuint name
+ GLenum option
+
+
+ void glOrtho
+ GLdouble left
+ GLdouble right
+ GLdouble bottom
+ GLdouble top
+ GLdouble zNear
+ GLdouble zFar
+
+
+
+ void glOrthof
+ GLfloat l
+ GLfloat r
+ GLfloat b
+ GLfloat t
+ GLfloat n
+ GLfloat f
+
+
+ void glOrthofOES
+ GLfloat l
+ GLfloat r
+ GLfloat b
+ GLfloat t
+ GLfloat n
+ GLfloat f
+
+
+
+ void glOrthox
+ GLfixed l
+ GLfixed r
+ GLfixed b
+ GLfixed t
+ GLfixed n
+ GLfixed f
+
+
+ void glOrthoxOES
+ GLfixed l
+ GLfixed r
+ GLfixed b
+ GLfixed t
+ GLfixed n
+ GLfixed f
+
+
+ void glPNTrianglesfATI
+ GLenum pname
+ GLfloat param
+
+
+ void glPNTrianglesiATI
+ GLenum pname
+ GLint param
+
+
+ void glPassTexCoordATI
+ GLuint dst
+ GLuint coord
+ GLenum swizzle
+
+
+ void glPassThrough
+ GLfloat token
+
+
+
+ void glPassThroughxOES
+ GLfixed token
+
+
+ void glPatchParameterfv
+ GLenum pname
+ const GLfloat *values
+
+
+ void glPatchParameteri
+ GLenum pname
+ GLint value
+
+
+ void glPatchParameteriEXT
+ GLenum pname
+ GLint value
+
+
+
+ void glPatchParameteriOES
+ GLenum pname
+ GLint value
+
+
+
+ void glPathColorGenNV
+ GLenum color
+ GLenum genMode
+ GLenum colorFormat
+ const GLfloat *coeffs
+
+
+ void glPathCommandsNV
+ GLuint path
+ GLsizei numCommands
+ const GLubyte *commands
+ GLsizei numCoords
+ GLenum coordType
+ const void *coords
+
+
+ void glPathCoordsNV
+ GLuint path
+ GLsizei numCoords
+ GLenum coordType
+ const void *coords
+
+
+ void glPathCoverDepthFuncNV
+ GLenum func
+
+
+ void glPathDashArrayNV
+ GLuint path
+ GLsizei dashCount
+ const GLfloat *dashArray
+
+
+ void glPathFogGenNV
+ GLenum genMode
+
+
+ GLenum glPathGlyphIndexArrayNV
+ GLuint firstPathName
+ GLenum fontTarget
+ const void *fontName
+ GLbitfield fontStyle
+ GLuint firstGlyphIndex
+ GLsizei numGlyphs
+ GLuint pathParameterTemplate
+ GLfloat emScale
+
+
+ GLenum glPathGlyphIndexRangeNV
+ GLenum fontTarget
+ const void *fontName
+ GLbitfield fontStyle
+ GLuint pathParameterTemplate
+ GLfloat emScale
+ GLuint baseAndCount [2]
+
+
+ void glPathGlyphRangeNV
+ GLuint firstPathName
+ GLenum fontTarget
+ const void *fontName
+ GLbitfield fontStyle
+ GLuint firstGlyph
+ GLsizei numGlyphs
+ GLenum handleMissingGlyphs
+ GLuint pathParameterTemplate
+ GLfloat emScale
+
+
+ void glPathGlyphsNV
+ GLuint firstPathName
+ GLenum fontTarget
+ const void *fontName
+ GLbitfield fontStyle
+ GLsizei numGlyphs
+ GLenum type
+ const void *charcodes
+ GLenum handleMissingGlyphs
+ GLuint pathParameterTemplate
+ GLfloat emScale
+
+
+ GLenum glPathMemoryGlyphIndexArrayNV
+ GLuint firstPathName
+ GLenum fontTarget
+ GLsizeiptr fontSize
+ const void *fontData
+ GLsizei faceIndex
+ GLuint firstGlyphIndex
+ GLsizei numGlyphs
+ GLuint pathParameterTemplate
+ GLfloat emScale
+
+
+ void glPathParameterfNV
+ GLuint path
+ GLenum pname
+ GLfloat value
+
+
+ void glPathParameterfvNV
+ GLuint path
+ GLenum pname
+ const GLfloat *value
+
+
+ void glPathParameteriNV
+ GLuint path
+ GLenum pname
+ GLint value
+
+
+ void glPathParameterivNV
+ GLuint path
+ GLenum pname
+ const GLint *value
+
+
+ void glPathStencilDepthOffsetNV
+ GLfloat factor
+ GLfloat units
+
+
+ void glPathStencilFuncNV
+ GLenum func
+ GLint ref
+ GLuint mask
+
+
+ void glPathStringNV
+ GLuint path
+ GLenum format
+ GLsizei length
+ const void *pathString
+
+
+ void glPathSubCommandsNV
+ GLuint path
+ GLsizei commandStart
+ GLsizei commandsToDelete
+ GLsizei numCommands
+ const GLubyte *commands
+ GLsizei numCoords
+ GLenum coordType
+ const void *coords
+
+
+ void glPathSubCoordsNV
+ GLuint path
+ GLsizei coordStart
+ GLsizei numCoords
+ GLenum coordType
+ const void *coords
+
+
+ void glPathTexGenNV
+ GLenum texCoordSet
+ GLenum genMode
+ GLint components
+ const GLfloat *coeffs
+
+
+ void glPauseTransformFeedback
+
+
+ void glPauseTransformFeedbackNV
+
+
+
+ void glPixelDataRangeNV
+ GLenum target
+ GLsizei length
+ const void *pointer
+
+
+ void glPixelMapfv
+ GLenum map
+ GLsizei mapsize
+ const GLfloat *values
+
+
+
+
+ void glPixelMapuiv
+ GLenum map
+ GLsizei mapsize
+ const GLuint *values
+
+
+
+
+ void glPixelMapusv
+ GLenum map
+ GLsizei mapsize
+ const GLushort *values
+
+
+
+
+ void glPixelMapx
+ GLenum map
+ GLint size
+ const GLfixed *values
+
+
+ void glPixelStoref
+ GLenum pname
+ GLfloat param
+
+
+
+ void glPixelStorei
+ GLenum pname
+ GLint param
+
+
+
+ void glPixelStorex
+ GLenum pname
+ GLfixed param
+
+
+ void glPixelTexGenParameterfSGIS
+ GLenum pname
+ GLfloat param
+
+
+ void glPixelTexGenParameterfvSGIS
+ GLenum pname
+ const GLfloat *params
+
+
+ void glPixelTexGenParameteriSGIS
+ GLenum pname
+ GLint param
+
+
+ void glPixelTexGenParameterivSGIS
+ GLenum pname
+ const GLint *params
+
+
+ void glPixelTexGenSGIX
+ GLenum mode
+
+
+
+ void glPixelTransferf
+ GLenum pname
+ GLfloat param
+
+
+
+ void glPixelTransferi
+ GLenum pname
+ GLint param
+
+
+
+ void glPixelTransferxOES
+ GLenum pname
+ GLfixed param
+
+
+ void glPixelTransformParameterfEXT
+ GLenum target
+ GLenum pname
+ GLfloat param
+
+
+
+ void glPixelTransformParameterfvEXT
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+ void glPixelTransformParameteriEXT
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+
+ void glPixelTransformParameterivEXT
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+ void glPixelZoom
+ GLfloat xfactor
+ GLfloat yfactor
+
+
+
+ void glPixelZoomxOES
+ GLfixed xfactor
+ GLfixed yfactor
+
+
+ GLboolean glPointAlongPathNV
+ GLuint path
+ GLsizei startSegment
+ GLsizei numSegments
+ GLfloat distance
+ GLfloat *x
+ GLfloat *y
+ GLfloat *tangentX
+ GLfloat *tangentY
+
+
+ void glPointParameterf
+ GLenum pname
+ GLfloat param
+
+
+
+ void glPointParameterfARB
+ GLenum pname
+ GLfloat param
+
+
+
+
+ void glPointParameterfEXT
+ GLenum pname
+ GLfloat param
+
+
+
+ void glPointParameterfSGIS
+ GLenum pname
+ GLfloat param
+
+
+
+ void glPointParameterfv
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glPointParameterfvARB
+ GLenum pname
+ const GLfloat *params
+
+
+
+
+ void glPointParameterfvEXT
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glPointParameterfvSGIS
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glPointParameteri
+ GLenum pname
+ GLint param
+
+
+
+ void glPointParameteriNV
+ GLenum pname
+ GLint param
+
+
+
+
+ void glPointParameteriv
+ GLenum pname
+ const GLint *params
+
+
+
+ void glPointParameterivNV
+ GLenum pname
+ const GLint *params
+
+
+
+
+ void glPointParameterx
+ GLenum pname
+ GLfixed param
+
+
+ void glPointParameterxOES
+ GLenum pname
+ GLfixed param
+
+
+ void glPointParameterxv
+ GLenum pname
+ const GLfixed *params
+
+
+ void glPointParameterxvOES
+ GLenum pname
+ const GLfixed *params
+
+
+ void glPointSize
+ GLfloat size
+
+
+
+ void glPointSizePointerOES
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glPointSizex
+ GLfixed size
+
+
+ void glPointSizexOES
+ GLfixed size
+
+
+ GLint glPollAsyncSGIX
+ GLuint *markerp
+
+
+ GLint glPollInstrumentsSGIX
+ GLint *marker_p
+
+
+
+ void glPolygonMode
+ GLenum face
+ GLenum mode
+
+
+
+ void glPolygonModeNV
+ GLenum face
+ GLenum mode
+
+
+
+ void glPolygonOffset
+ GLfloat factor
+ GLfloat units
+
+
+
+ void glPolygonOffsetEXT
+ GLfloat factor
+ GLfloat bias
+
+
+
+ void glPolygonOffsetx
+ GLfixed factor
+ GLfixed units
+
+
+ void glPolygonOffsetxOES
+ GLfixed factor
+ GLfixed units
+
+
+ void glPolygonOffsetClampEXT
+ GLfloat factor
+ GLfloat units
+ GLfloat clamp
+
+
+
+ void glPolygonStipple
+ const GLubyte *mask
+
+
+
+
+ void glPopAttrib
+
+
+
+ void glPopClientAttrib
+
+
+ void glPopDebugGroup
+
+
+ void glPopDebugGroupKHR
+
+
+
+ void glPopGroupMarkerEXT
+
+
+ void glPopMatrix
+
+
+
+ void glPopName
+
+
+
+ void glPresentFrameDualFillNV
+ GLuint video_slot
+ GLuint64EXT minPresentTime
+ GLuint beginPresentTimeId
+ GLuint presentDurationId
+ GLenum type
+ GLenum target0
+ GLuint fill0
+ GLenum target1
+ GLuint fill1
+ GLenum target2
+ GLuint fill2
+ GLenum target3
+ GLuint fill3
+
+
+ void glPresentFrameKeyedNV
+ GLuint video_slot
+ GLuint64EXT minPresentTime
+ GLuint beginPresentTimeId
+ GLuint presentDurationId
+ GLenum type
+ GLenum target0
+ GLuint fill0
+ GLuint key0
+ GLenum target1
+ GLuint fill1
+ GLuint key1
+
+
+ void glPrimitiveBoundingBoxEXT
+ GLfloat minX
+ GLfloat minY
+ GLfloat minZ
+ GLfloat minW
+ GLfloat maxX
+ GLfloat maxY
+ GLfloat maxZ
+ GLfloat maxW
+
+
+ void glPrimitiveBoundingBoxOES
+ GLfloat minX
+ GLfloat minY
+ GLfloat minZ
+ GLfloat minW
+ GLfloat maxX
+ GLfloat maxY
+ GLfloat maxZ
+ GLfloat maxW
+
+
+ void glPrimitiveRestartIndex
+ GLuint index
+
+
+ void glPrimitiveRestartIndexNV
+ GLuint index
+
+
+ void glPrimitiveRestartNV
+
+
+ void glPrioritizeTextures
+ GLsizei n
+ const GLuint *textures
+ const GLfloat *priorities
+
+
+
+ void glPrioritizeTexturesEXT
+ GLsizei n
+ const GLuint *textures
+ const GLclampf *priorities
+
+
+
+
+ void glPrioritizeTexturesxOES
+ GLsizei n
+ const GLuint *textures
+ const GLfixed *priorities
+
+
+ void glProgramBinary
+ GLuint program
+ GLenum binaryFormat
+ const void *binary
+ GLsizei length
+
+
+ void glProgramBinaryOES
+ GLuint program
+ GLenum binaryFormat
+ const void *binary
+ GLint length
+
+
+
+ void glProgramBufferParametersIivNV
+ GLenum target
+ GLuint bindingIndex
+ GLuint wordIndex
+ GLsizei count
+ const GLint *params
+
+
+ void glProgramBufferParametersIuivNV
+ GLenum target
+ GLuint bindingIndex
+ GLuint wordIndex
+ GLsizei count
+ const GLuint *params
+
+
+ void glProgramBufferParametersfvNV
+ GLenum target
+ GLuint bindingIndex
+ GLuint wordIndex
+ GLsizei count
+ const GLfloat *params
+
+
+ void glProgramEnvParameter4dARB
+ GLenum target
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glProgramEnvParameter4dvARB
+ GLenum target
+ GLuint index
+ const GLdouble *params
+
+
+ void glProgramEnvParameter4fARB
+ GLenum target
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+ void glProgramEnvParameter4fvARB
+ GLenum target
+ GLuint index
+ const GLfloat *params
+
+
+ void glProgramEnvParameterI4iNV
+ GLenum target
+ GLuint index
+ GLint x
+ GLint y
+ GLint z
+ GLint w
+
+
+
+ void glProgramEnvParameterI4ivNV
+ GLenum target
+ GLuint index
+ const GLint *params
+
+
+ void glProgramEnvParameterI4uiNV
+ GLenum target
+ GLuint index
+ GLuint x
+ GLuint y
+ GLuint z
+ GLuint w
+
+
+
+ void glProgramEnvParameterI4uivNV
+ GLenum target
+ GLuint index
+ const GLuint *params
+
+
+ void glProgramEnvParameters4fvEXT
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLfloat *params
+
+
+
+ void glProgramEnvParametersI4ivNV
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLint *params
+
+
+ void glProgramEnvParametersI4uivNV
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLuint *params
+
+
+ void glProgramLocalParameter4dARB
+ GLenum target
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glProgramLocalParameter4dvARB
+ GLenum target
+ GLuint index
+ const GLdouble *params
+
+
+ void glProgramLocalParameter4fARB
+ GLenum target
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+ void glProgramLocalParameter4fvARB
+ GLenum target
+ GLuint index
+ const GLfloat *params
+
+
+ void glProgramLocalParameterI4iNV
+ GLenum target
+ GLuint index
+ GLint x
+ GLint y
+ GLint z
+ GLint w
+
+
+
+ void glProgramLocalParameterI4ivNV
+ GLenum target
+ GLuint index
+ const GLint *params
+
+
+ void glProgramLocalParameterI4uiNV
+ GLenum target
+ GLuint index
+ GLuint x
+ GLuint y
+ GLuint z
+ GLuint w
+
+
+
+ void glProgramLocalParameterI4uivNV
+ GLenum target
+ GLuint index
+ const GLuint *params
+
+
+ void glProgramLocalParameters4fvEXT
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLfloat *params
+
+
+
+ void glProgramLocalParametersI4ivNV
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLint *params
+
+
+ void glProgramLocalParametersI4uivNV
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLuint *params
+
+
+ void glProgramNamedParameter4dNV
+ GLuint id
+ GLsizei len
+ const GLubyte *name
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glProgramNamedParameter4dvNV
+ GLuint id
+ GLsizei len
+ const GLubyte *name
+ const GLdouble *v
+
+
+
+ void glProgramNamedParameter4fNV
+ GLuint id
+ GLsizei len
+ const GLubyte *name
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+ void glProgramNamedParameter4fvNV
+ GLuint id
+ GLsizei len
+ const GLubyte *name
+ const GLfloat *v
+
+
+
+ void glProgramParameter4dNV
+ GLenum target
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glProgramParameter4dvNV
+ GLenum target
+ GLuint index
+ const GLdouble *v
+
+
+
+ void glProgramParameter4fNV
+ GLenum target
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+ void glProgramParameter4fvNV
+ GLenum target
+ GLuint index
+ const GLfloat *v
+
+
+
+ void glProgramParameteri
+ GLuint program
+ GLenum pname
+ GLint value
+
+
+ void glProgramParameteriARB
+ GLuint program
+ GLenum pname
+ GLint value
+
+
+
+ void glProgramParameteriEXT
+ GLuint program
+ GLenum pname
+ GLint value
+
+
+
+ void glProgramParameters4dvNV
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLdouble *v
+
+
+
+ void glProgramParameters4fvNV
+ GLenum target
+ GLuint index
+ GLsizei count
+ const GLfloat *v
+
+
+
+ void glProgramPathFragmentInputGenNV
+ GLuint program
+ GLint location
+ GLenum genMode
+ GLint components
+ const GLfloat *coeffs
+
+
+ void glProgramStringARB
+ GLenum target
+ GLenum format
+ GLsizei len
+ const void *string
+
+
+ void glProgramSubroutineParametersuivNV
+ GLenum target
+ GLsizei count
+ const GLuint *params
+
+
+ void glProgramUniform1d
+ GLuint program
+ GLint location
+ GLdouble v0
+
+
+ void glProgramUniform1dEXT
+ GLuint program
+ GLint location
+ GLdouble x
+
+
+ void glProgramUniform1dv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glProgramUniform1dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glProgramUniform1f
+ GLuint program
+ GLint location
+ GLfloat v0
+
+
+ void glProgramUniform1fEXT
+ GLuint program
+ GLint location
+ GLfloat v0
+
+
+
+ void glProgramUniform1fv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+ void glProgramUniform1fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+
+ void glProgramUniform1i
+ GLuint program
+ GLint location
+ GLint v0
+
+
+ void glProgramUniform1i64NV
+ GLuint program
+ GLint location
+ GLint64EXT x
+
+
+ void glProgramUniform1i64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint64EXT *value
+
+
+ void glProgramUniform1iEXT
+ GLuint program
+ GLint location
+ GLint v0
+
+
+
+ void glProgramUniform1iv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+ void glProgramUniform1ivEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+
+ void glProgramUniform1ui
+ GLuint program
+ GLint location
+ GLuint v0
+
+
+ void glProgramUniform1ui64NV
+ GLuint program
+ GLint location
+ GLuint64EXT x
+
+
+ void glProgramUniform1ui64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glProgramUniform1uiEXT
+ GLuint program
+ GLint location
+ GLuint v0
+
+
+
+ void glProgramUniform1uiv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+ void glProgramUniform1uivEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+
+ void glProgramUniform2d
+ GLuint program
+ GLint location
+ GLdouble v0
+ GLdouble v1
+
+
+ void glProgramUniform2dEXT
+ GLuint program
+ GLint location
+ GLdouble x
+ GLdouble y
+
+
+ void glProgramUniform2dv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glProgramUniform2dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glProgramUniform2f
+ GLuint program
+ GLint location
+ GLfloat v0
+ GLfloat v1
+
+
+ void glProgramUniform2fEXT
+ GLuint program
+ GLint location
+ GLfloat v0
+ GLfloat v1
+
+
+
+ void glProgramUniform2fv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+ void glProgramUniform2fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+
+ void glProgramUniform2i
+ GLuint program
+ GLint location
+ GLint v0
+ GLint v1
+
+
+ void glProgramUniform2i64NV
+ GLuint program
+ GLint location
+ GLint64EXT x
+ GLint64EXT y
+
+
+ void glProgramUniform2i64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint64EXT *value
+
+
+ void glProgramUniform2iEXT
+ GLuint program
+ GLint location
+ GLint v0
+ GLint v1
+
+
+
+ void glProgramUniform2iv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+ void glProgramUniform2ivEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+
+ void glProgramUniform2ui
+ GLuint program
+ GLint location
+ GLuint v0
+ GLuint v1
+
+
+ void glProgramUniform2ui64NV
+ GLuint program
+ GLint location
+ GLuint64EXT x
+ GLuint64EXT y
+
+
+ void glProgramUniform2ui64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glProgramUniform2uiEXT
+ GLuint program
+ GLint location
+ GLuint v0
+ GLuint v1
+
+
+
+ void glProgramUniform2uiv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+ void glProgramUniform2uivEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+
+ void glProgramUniform3d
+ GLuint program
+ GLint location
+ GLdouble v0
+ GLdouble v1
+ GLdouble v2
+
+
+ void glProgramUniform3dEXT
+ GLuint program
+ GLint location
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+ void glProgramUniform3dv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glProgramUniform3dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glProgramUniform3f
+ GLuint program
+ GLint location
+ GLfloat v0
+ GLfloat v1
+ GLfloat v2
+
+
+ void glProgramUniform3fEXT
+ GLuint program
+ GLint location
+ GLfloat v0
+ GLfloat v1
+ GLfloat v2
+
+
+
+ void glProgramUniform3fv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+ void glProgramUniform3fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+
+ void glProgramUniform3i
+ GLuint program
+ GLint location
+ GLint v0
+ GLint v1
+ GLint v2
+
+
+ void glProgramUniform3i64NV
+ GLuint program
+ GLint location
+ GLint64EXT x
+ GLint64EXT y
+ GLint64EXT z
+
+
+ void glProgramUniform3i64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint64EXT *value
+
+
+ void glProgramUniform3iEXT
+ GLuint program
+ GLint location
+ GLint v0
+ GLint v1
+ GLint v2
+
+
+
+ void glProgramUniform3iv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+ void glProgramUniform3ivEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+
+ void glProgramUniform3ui
+ GLuint program
+ GLint location
+ GLuint v0
+ GLuint v1
+ GLuint v2
+
+
+ void glProgramUniform3ui64NV
+ GLuint program
+ GLint location
+ GLuint64EXT x
+ GLuint64EXT y
+ GLuint64EXT z
+
+
+ void glProgramUniform3ui64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glProgramUniform3uiEXT
+ GLuint program
+ GLint location
+ GLuint v0
+ GLuint v1
+ GLuint v2
+
+
+
+ void glProgramUniform3uiv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+ void glProgramUniform3uivEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+
+ void glProgramUniform4d
+ GLuint program
+ GLint location
+ GLdouble v0
+ GLdouble v1
+ GLdouble v2
+ GLdouble v3
+
+
+ void glProgramUniform4dEXT
+ GLuint program
+ GLint location
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+ void glProgramUniform4dv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glProgramUniform4dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glProgramUniform4f
+ GLuint program
+ GLint location
+ GLfloat v0
+ GLfloat v1
+ GLfloat v2
+ GLfloat v3
+
+
+ void glProgramUniform4fEXT
+ GLuint program
+ GLint location
+ GLfloat v0
+ GLfloat v1
+ GLfloat v2
+ GLfloat v3
+
+
+
+ void glProgramUniform4fv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+ void glProgramUniform4fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+
+ void glProgramUniform4i
+ GLuint program
+ GLint location
+ GLint v0
+ GLint v1
+ GLint v2
+ GLint v3
+
+
+ void glProgramUniform4i64NV
+ GLuint program
+ GLint location
+ GLint64EXT x
+ GLint64EXT y
+ GLint64EXT z
+ GLint64EXT w
+
+
+ void glProgramUniform4i64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint64EXT *value
+
+
+ void glProgramUniform4iEXT
+ GLuint program
+ GLint location
+ GLint v0
+ GLint v1
+ GLint v2
+ GLint v3
+
+
+
+ void glProgramUniform4iv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+ void glProgramUniform4ivEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+
+ void glProgramUniform4ui
+ GLuint program
+ GLint location
+ GLuint v0
+ GLuint v1
+ GLuint v2
+ GLuint v3
+
+
+ void glProgramUniform4ui64NV
+ GLuint program
+ GLint location
+ GLuint64EXT x
+ GLuint64EXT y
+ GLuint64EXT z
+ GLuint64EXT w
+
+
+ void glProgramUniform4ui64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glProgramUniform4uiEXT
+ GLuint program
+ GLint location
+ GLuint v0
+ GLuint v1
+ GLuint v2
+ GLuint v3
+
+
+
+ void glProgramUniform4uiv
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+ void glProgramUniform4uivEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+
+ void glProgramUniformHandleui64ARB
+ GLuint program
+ GLint location
+ GLuint64 value
+
+
+ void glProgramUniformHandleui64NV
+ GLuint program
+ GLint location
+ GLuint64 value
+
+
+ void glProgramUniformHandleui64vARB
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint64 *values
+
+
+ void glProgramUniformHandleui64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint64 *values
+
+
+ void glProgramUniformMatrix2dv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix2dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix2fv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glProgramUniformMatrix2fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glProgramUniformMatrix2x3dv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix2x3dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix2x3fv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glProgramUniformMatrix2x3fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glProgramUniformMatrix2x4dv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix2x4dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix2x4fv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glProgramUniformMatrix2x4fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glProgramUniformMatrix3dv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix3dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix3fv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glProgramUniformMatrix3fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glProgramUniformMatrix3x2dv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix3x2dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix3x2fv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glProgramUniformMatrix3x2fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glProgramUniformMatrix3x4dv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix3x4dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix3x4fv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glProgramUniformMatrix3x4fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glProgramUniformMatrix4dv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix4dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix4fv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glProgramUniformMatrix4fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glProgramUniformMatrix4x2dv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix4x2dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix4x2fv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glProgramUniformMatrix4x2fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glProgramUniformMatrix4x3dv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix4x3dvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glProgramUniformMatrix4x3fv
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glProgramUniformMatrix4x3fvEXT
+ GLuint program
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glProgramUniformui64NV
+ GLuint program
+ GLint location
+ GLuint64EXT value
+
+
+ void glProgramUniformui64vNV
+ GLuint program
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glProgramVertexLimitNV
+ GLenum target
+ GLint limit
+
+
+ void glProvokingVertex
+ GLenum mode
+
+
+ void glProvokingVertexEXT
+ GLenum mode
+
+
+
+ void glPushAttrib
+ GLbitfield mask
+
+
+
+ void glPushClientAttrib
+ GLbitfield mask
+
+
+ void glPushClientAttribDefaultEXT
+ GLbitfield mask
+
+
+ void glPushDebugGroup
+ GLenum source
+ GLuint id
+ GLsizei length
+ const GLchar *message
+
+
+ void glPushDebugGroupKHR
+ GLenum source
+ GLuint id
+ GLsizei length
+ const GLchar *message
+
+
+
+ void glPushGroupMarkerEXT
+ GLsizei length
+ const GLchar *marker
+
+
+ void glPushMatrix
+
+
+
+ void glPushName
+ GLuint name
+
+
+
+ void glQueryCounter
+ GLuint id
+ GLenum target
+
+
+ void glQueryCounterEXT
+ GLuint id
+ GLenum target
+
+
+
+ GLbitfield glQueryMatrixxOES
+ GLfixed *mantissa
+ GLint *exponent
+
+
+ void glQueryObjectParameteruiAMD
+ GLenum target
+ GLuint id
+ GLenum pname
+ GLuint param
+
+
+ void glRasterPos2d
+ GLdouble x
+ GLdouble y
+
+
+
+ void glRasterPos2dv
+ const GLdouble *v
+
+
+
+ void glRasterPos2f
+ GLfloat x
+ GLfloat y
+
+
+
+ void glRasterPos2fv
+ const GLfloat *v
+
+
+
+ void glRasterPos2i
+ GLint x
+ GLint y
+
+
+
+ void glRasterPos2iv
+ const GLint *v
+
+
+
+ void glRasterPos2s
+ GLshort x
+ GLshort y
+
+
+
+ void glRasterPos2sv
+ const GLshort *v
+
+
+
+ void glRasterPos2xOES
+ GLfixed x
+ GLfixed y
+
+
+ void glRasterPos2xvOES
+ const GLfixed *coords
+
+
+ void glRasterPos3d
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+ void glRasterPos3dv
+ const GLdouble *v
+
+
+
+ void glRasterPos3f
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+ void glRasterPos3fv
+ const GLfloat *v
+
+
+
+ void glRasterPos3i
+ GLint x
+ GLint y
+ GLint z
+
+
+
+ void glRasterPos3iv
+ const GLint *v
+
+
+
+ void glRasterPos3s
+ GLshort x
+ GLshort y
+ GLshort z
+
+
+
+ void glRasterPos3sv
+ const GLshort *v
+
+
+
+ void glRasterPos3xOES
+ GLfixed x
+ GLfixed y
+ GLfixed z
+
+
+ void glRasterPos3xvOES
+ const GLfixed *coords
+
+
+ void glRasterPos4d
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glRasterPos4dv
+ const GLdouble *v
+
+
+
+ void glRasterPos4f
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+ void glRasterPos4fv
+ const GLfloat *v
+
+
+
+ void glRasterPos4i
+ GLint x
+ GLint y
+ GLint z
+ GLint w
+
+
+
+ void glRasterPos4iv
+ const GLint *v
+
+
+
+ void glRasterPos4s
+ GLshort x
+ GLshort y
+ GLshort z
+ GLshort w
+
+
+
+ void glRasterPos4sv
+ const GLshort *v
+
+
+
+ void glRasterPos4xOES
+ GLfixed x
+ GLfixed y
+ GLfixed z
+ GLfixed w
+
+
+ void glRasterPos4xvOES
+ const GLfixed *coords
+
+
+ void glReadBuffer
+ GLenum src
+
+
+
+ void glReadBufferIndexedEXT
+ GLenum src
+ GLint index
+
+
+ void glReadBufferNV
+ GLenum mode
+
+
+ void glReadInstrumentsSGIX
+ GLint marker
+
+
+
+ void glReadPixels
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ void *pixels
+
+
+
+
+ void glReadnPixels
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *data
+
+
+ void glReadnPixelsARB
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *data
+
+
+
+ void glReadnPixelsEXT
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *data
+
+
+
+ void glReadnPixelsKHR
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ GLsizei bufSize
+ void *data
+
+
+
+ void glRectd
+ GLdouble x1
+ GLdouble y1
+ GLdouble x2
+ GLdouble y2
+
+
+
+ void glRectdv
+ const GLdouble *v1
+ const GLdouble *v2
+
+
+
+ void glRectf
+ GLfloat x1
+ GLfloat y1
+ GLfloat x2
+ GLfloat y2
+
+
+
+ void glRectfv
+ const GLfloat *v1
+ const GLfloat *v2
+
+
+
+ void glRecti
+ GLint x1
+ GLint y1
+ GLint x2
+ GLint y2
+
+
+
+ void glRectiv
+ const GLint *v1
+ const GLint *v2
+
+
+
+ void glRects
+ GLshort x1
+ GLshort y1
+ GLshort x2
+ GLshort y2
+
+
+
+ void glRectsv
+ const GLshort *v1
+ const GLshort *v2
+
+
+
+ void glRectxOES
+ GLfixed x1
+ GLfixed y1
+ GLfixed x2
+ GLfixed y2
+
+
+ void glRectxvOES
+ const GLfixed *v1
+ const GLfixed *v2
+
+
+ void glReferencePlaneSGIX
+ const GLdouble *equation
+
+
+
+ void glReleaseShaderCompiler
+
+
+ GLint glRenderMode
+ GLenum mode
+
+
+
+ void glRenderbufferStorage
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+
+ void glRenderbufferStorageEXT
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+
+
+ void glRenderbufferStorageMultisample
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+
+ void glRenderbufferStorageMultisampleANGLE
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glRenderbufferStorageMultisampleAPPLE
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glRenderbufferStorageMultisampleCoverageNV
+ GLenum target
+ GLsizei coverageSamples
+ GLsizei colorSamples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glRenderbufferStorageMultisampleEXT
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+
+
+ void glRenderbufferStorageMultisampleIMG
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glRenderbufferStorageMultisampleNV
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+
+ void glRenderbufferStorageOES
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glReplacementCodePointerSUN
+ GLenum type
+ GLsizei stride
+ const void **pointer
+
+
+ void glReplacementCodeubSUN
+ GLubyte code
+
+
+ void glReplacementCodeubvSUN
+ const GLubyte *code
+
+
+ void glReplacementCodeuiColor3fVertex3fSUN
+ GLuint rc
+ GLfloat r
+ GLfloat g
+ GLfloat b
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glReplacementCodeuiColor3fVertex3fvSUN
+ const GLuint *rc
+ const GLfloat *c
+ const GLfloat *v
+
+
+ void glReplacementCodeuiColor4fNormal3fVertex3fSUN
+ GLuint rc
+ GLfloat r
+ GLfloat g
+ GLfloat b
+ GLfloat a
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glReplacementCodeuiColor4fNormal3fVertex3fvSUN
+ const GLuint *rc
+ const GLfloat *c
+ const GLfloat *n
+ const GLfloat *v
+
+
+ void glReplacementCodeuiColor4ubVertex3fSUN
+ GLuint rc
+ GLubyte r
+ GLubyte g
+ GLubyte b
+ GLubyte a
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glReplacementCodeuiColor4ubVertex3fvSUN
+ const GLuint *rc
+ const GLubyte *c
+ const GLfloat *v
+
+
+ void glReplacementCodeuiNormal3fVertex3fSUN
+ GLuint rc
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glReplacementCodeuiNormal3fVertex3fvSUN
+ const GLuint *rc
+ const GLfloat *n
+ const GLfloat *v
+
+
+ void glReplacementCodeuiSUN
+ GLuint code
+
+
+ void glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN
+ GLuint rc
+ GLfloat s
+ GLfloat t
+ GLfloat r
+ GLfloat g
+ GLfloat b
+ GLfloat a
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN
+ const GLuint *rc
+ const GLfloat *tc
+ const GLfloat *c
+ const GLfloat *n
+ const GLfloat *v
+
+
+ void glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN
+ GLuint rc
+ GLfloat s
+ GLfloat t
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN
+ const GLuint *rc
+ const GLfloat *tc
+ const GLfloat *n
+ const GLfloat *v
+
+
+ void glReplacementCodeuiTexCoord2fVertex3fSUN
+ GLuint rc
+ GLfloat s
+ GLfloat t
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glReplacementCodeuiTexCoord2fVertex3fvSUN
+ const GLuint *rc
+ const GLfloat *tc
+ const GLfloat *v
+
+
+ void glReplacementCodeuiVertex3fSUN
+ GLuint rc
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glReplacementCodeuiVertex3fvSUN
+ const GLuint *rc
+ const GLfloat *v
+
+
+ void glReplacementCodeuivSUN
+ const GLuint *code
+
+
+ void glReplacementCodeusSUN
+ GLushort code
+
+
+ void glReplacementCodeusvSUN
+ const GLushort *code
+
+
+ void glRequestResidentProgramsNV
+ GLsizei n
+ const GLuint *programs
+
+
+
+ void glResetHistogram
+ GLenum target
+
+
+
+ void glResetHistogramEXT
+ GLenum target
+
+
+
+
+ void glResetMinmax
+ GLenum target
+
+
+
+ void glResetMinmaxEXT
+ GLenum target
+
+
+
+
+ void glResizeBuffersMESA
+
+
+ void glResolveMultisampleFramebufferAPPLE
+
+
+ void glResumeTransformFeedback
+
+
+ void glResumeTransformFeedbackNV
+
+
+
+ void glRotated
+ GLdouble angle
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+ void glRotatef
+ GLfloat angle
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+ void glRotatex
+ GLfixed angle
+ GLfixed x
+ GLfixed y
+ GLfixed z
+
+
+ void glRotatexOES
+ GLfixed angle
+ GLfixed x
+ GLfixed y
+ GLfixed z
+
+
+ void glSampleCoverage
+ GLfloat value
+ GLboolean invert
+
+
+
+ void glSampleCoverageARB
+ GLfloat value
+ GLboolean invert
+
+
+
+ void glSampleCoveragex
+ GLclampx value
+ GLboolean invert
+
+
+ void glSampleCoveragexOES
+ GLclampx value
+ GLboolean invert
+
+
+ void glSampleMapATI
+ GLuint dst
+ GLuint interp
+ GLenum swizzle
+
+
+ void glSampleMaskEXT
+ GLclampf value
+ GLboolean invert
+
+
+ void glSampleMaskIndexedNV
+ GLuint index
+ GLbitfield mask
+
+
+ void glSampleMaskSGIS
+ GLclampf value
+ GLboolean invert
+
+
+
+
+ void glSampleMaski
+ GLuint maskNumber
+ GLbitfield mask
+
+
+ void glSamplePatternEXT
+ GLenum pattern
+
+
+ void glSamplePatternSGIS
+ GLenum pattern
+
+
+
+
+ void glSamplerParameterIiv
+ GLuint sampler
+ GLenum pname
+ const GLint *param
+
+
+ void glSamplerParameterIivEXT
+ GLuint sampler
+ GLenum pname
+ const GLint *param
+
+
+
+ void glSamplerParameterIivOES
+ GLuint sampler
+ GLenum pname
+ const GLint *param
+
+
+
+ void glSamplerParameterIuiv
+ GLuint sampler
+ GLenum pname
+ const GLuint *param
+
+
+ void glSamplerParameterIuivEXT
+ GLuint sampler
+ GLenum pname
+ const GLuint *param
+
+
+
+ void glSamplerParameterIuivOES
+ GLuint sampler
+ GLenum pname
+ const GLuint *param
+
+
+
+ void glSamplerParameterf
+ GLuint sampler
+ GLenum pname
+ GLfloat param
+
+
+ void glSamplerParameterfv
+ GLuint sampler
+ GLenum pname
+ const GLfloat *param
+
+
+ void glSamplerParameteri
+ GLuint sampler
+ GLenum pname
+ GLint param
+
+
+ void glSamplerParameteriv
+ GLuint sampler
+ GLenum pname
+ const GLint *param
+
+
+ void glScaled
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+ void glScalef
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+ void glScalex
+ GLfixed x
+ GLfixed y
+ GLfixed z
+
+
+ void glScalexOES
+ GLfixed x
+ GLfixed y
+ GLfixed z
+
+
+ void glScissor
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+
+ void glScissorArrayv
+ GLuint first
+ GLsizei count
+ const GLint *v
+
+
+ void glScissorArrayvNV
+ GLuint first
+ GLsizei count
+ const GLint *v
+
+
+
+ void glScissorIndexed
+ GLuint index
+ GLint left
+ GLint bottom
+ GLsizei width
+ GLsizei height
+
+
+ void glScissorIndexedNV
+ GLuint index
+ GLint left
+ GLint bottom
+ GLsizei width
+ GLsizei height
+
+
+
+ void glScissorIndexedv
+ GLuint index
+ const GLint *v
+
+
+ void glScissorIndexedvNV
+ GLuint index
+ const GLint *v
+
+
+
+ void glSecondaryColor3b
+ GLbyte red
+ GLbyte green
+ GLbyte blue
+
+
+
+ void glSecondaryColor3bEXT
+ GLbyte red
+ GLbyte green
+ GLbyte blue
+
+
+
+
+ void glSecondaryColor3bv
+ const GLbyte *v
+
+
+
+ void glSecondaryColor3bvEXT
+ const GLbyte *v
+
+
+
+
+ void glSecondaryColor3d
+ GLdouble red
+ GLdouble green
+ GLdouble blue
+
+
+
+ void glSecondaryColor3dEXT
+ GLdouble red
+ GLdouble green
+ GLdouble blue
+
+
+
+
+ void glSecondaryColor3dv
+ const GLdouble *v
+
+
+
+ void glSecondaryColor3dvEXT
+ const GLdouble *v
+
+
+
+
+ void glSecondaryColor3f
+ GLfloat red
+ GLfloat green
+ GLfloat blue
+
+
+
+ void glSecondaryColor3fEXT
+ GLfloat red
+ GLfloat green
+ GLfloat blue
+
+
+
+
+ void glSecondaryColor3fv
+ const GLfloat *v
+
+
+
+ void glSecondaryColor3fvEXT
+ const GLfloat *v
+
+
+
+
+ void glSecondaryColor3hNV
+ GLhalfNV red
+ GLhalfNV green
+ GLhalfNV blue
+
+
+
+ void glSecondaryColor3hvNV
+ const GLhalfNV *v
+
+
+
+ void glSecondaryColor3i
+ GLint red
+ GLint green
+ GLint blue
+
+
+
+ void glSecondaryColor3iEXT
+ GLint red
+ GLint green
+ GLint blue
+
+
+
+
+ void glSecondaryColor3iv
+ const GLint *v
+
+
+
+ void glSecondaryColor3ivEXT
+ const GLint *v
+
+
+
+
+ void glSecondaryColor3s
+ GLshort red
+ GLshort green
+ GLshort blue
+
+
+
+ void glSecondaryColor3sEXT
+ GLshort red
+ GLshort green
+ GLshort blue
+
+
+
+
+ void glSecondaryColor3sv
+ const GLshort *v
+
+
+
+ void glSecondaryColor3svEXT
+ const GLshort *v
+
+
+
+
+ void glSecondaryColor3ub
+ GLubyte red
+ GLubyte green
+ GLubyte blue
+
+
+
+ void glSecondaryColor3ubEXT
+ GLubyte red
+ GLubyte green
+ GLubyte blue
+
+
+
+
+ void glSecondaryColor3ubv
+ const GLubyte *v
+
+
+
+ void glSecondaryColor3ubvEXT
+ const GLubyte *v
+
+
+
+
+ void glSecondaryColor3ui
+ GLuint red
+ GLuint green
+ GLuint blue
+
+
+
+ void glSecondaryColor3uiEXT
+ GLuint red
+ GLuint green
+ GLuint blue
+
+
+
+
+ void glSecondaryColor3uiv
+ const GLuint *v
+
+
+
+ void glSecondaryColor3uivEXT
+ const GLuint *v
+
+
+
+
+ void glSecondaryColor3us
+ GLushort red
+ GLushort green
+ GLushort blue
+
+
+
+ void glSecondaryColor3usEXT
+ GLushort red
+ GLushort green
+ GLushort blue
+
+
+
+
+ void glSecondaryColor3usv
+ const GLushort *v
+
+
+
+ void glSecondaryColor3usvEXT
+ const GLushort *v
+
+
+
+
+ void glSecondaryColorFormatNV
+ GLint size
+ GLenum type
+ GLsizei stride
+
+
+ void glSecondaryColorP3ui
+ GLenum type
+ GLuint color
+
+
+ void glSecondaryColorP3uiv
+ GLenum type
+ const GLuint *color
+
+
+ void glSecondaryColorPointer
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glSecondaryColorPointerEXT
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+
+ void glSecondaryColorPointerListIBM
+ GLint size
+ GLenum type
+ GLint stride
+ const void **pointer
+ GLint ptrstride
+
+
+ void glSelectBuffer
+ GLsizei size
+ GLuint *buffer
+
+
+
+ void glSelectPerfMonitorCountersAMD
+ GLuint monitor
+ GLboolean enable
+ GLuint group
+ GLint numCounters
+ GLuint *counterList
+
+
+ void glSeparableFilter2D
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *row
+ const void *column
+
+
+
+
+ void glSeparableFilter2DEXT
+ GLenum target
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *row
+ const void *column
+
+
+
+
+ void glSetFenceAPPLE
+ GLuint fence
+
+
+ void glSetFenceNV
+ GLuint fence
+ GLenum condition
+
+
+ void glSetFragmentShaderConstantATI
+ GLuint dst
+ const GLfloat *value
+
+
+ void glSetInvariantEXT
+ GLuint id
+ GLenum type
+ const void *addr
+
+
+ void glSetLocalConstantEXT
+ GLuint id
+ GLenum type
+ const void *addr
+
+
+ void glSetMultisamplefvAMD
+ GLenum pname
+ GLuint index
+ const GLfloat *val
+
+
+ void glShadeModel
+ GLenum mode
+
+
+
+ void glShaderBinary
+ GLsizei count
+ const GLuint *shaders
+ GLenum binaryformat
+ const void *binary
+ GLsizei length
+
+
+ void glShaderOp1EXT
+ GLenum op
+ GLuint res
+ GLuint arg1
+
+
+ void glShaderOp2EXT
+ GLenum op
+ GLuint res
+ GLuint arg1
+ GLuint arg2
+
+
+ void glShaderOp3EXT
+ GLenum op
+ GLuint res
+ GLuint arg1
+ GLuint arg2
+ GLuint arg3
+
+
+ void glShaderSource
+ GLuint shader
+ GLsizei count
+ const GLchar *const*string
+ const GLint *length
+
+
+ void glShaderSourceARB
+ GLhandleARB shaderObj
+ GLsizei count
+ const GLcharARB **string
+ const GLint *length
+
+
+
+ void glShaderStorageBlockBinding
+ GLuint program
+ GLuint storageBlockIndex
+ GLuint storageBlockBinding
+
+
+ void glSharpenTexFuncSGIS
+ GLenum target
+ GLsizei n
+ const GLfloat *points
+
+
+
+ void glSpriteParameterfSGIX
+ GLenum pname
+ GLfloat param
+
+
+
+ void glSpriteParameterfvSGIX
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glSpriteParameteriSGIX
+ GLenum pname
+ GLint param
+
+
+
+ void glSpriteParameterivSGIX
+ GLenum pname
+ const GLint *params
+
+
+
+ void glStartInstrumentsSGIX
+
+
+
+ void glStartTilingQCOM
+ GLuint x
+ GLuint y
+ GLuint width
+ GLuint height
+ GLbitfield preserveMask
+
+
+ void glStateCaptureNV
+ GLuint state
+ GLenum mode
+
+
+ void glStencilClearTagEXT
+ GLsizei stencilTagBits
+ GLuint stencilClearTag
+
+
+
+ void glStencilFillPathInstancedNV
+ GLsizei numPaths
+ GLenum pathNameType
+ const void *paths
+ GLuint pathBase
+ GLenum fillMode
+ GLuint mask
+ GLenum transformType
+ const GLfloat *transformValues
+
+
+ void glStencilFillPathNV
+ GLuint path
+ GLenum fillMode
+ GLuint mask
+
+
+ void glStencilFunc
+ GLenum func
+ GLint ref
+ GLuint mask
+
+
+
+ void glStencilFuncSeparate
+ GLenum face
+ GLenum func
+ GLint ref
+ GLuint mask
+
+
+ void glStencilFuncSeparateATI
+ GLenum frontfunc
+ GLenum backfunc
+ GLint ref
+ GLuint mask
+
+
+ void glStencilMask
+ GLuint mask
+
+
+
+ void glStencilMaskSeparate
+ GLenum face
+ GLuint mask
+
+
+ void glStencilOp
+ GLenum fail
+ GLenum zfail
+ GLenum zpass
+
+
+
+ void glStencilOpSeparate
+ GLenum face
+ GLenum sfail
+ GLenum dpfail
+ GLenum dppass
+
+
+ void glStencilOpSeparateATI
+ GLenum face
+ GLenum sfail
+ GLenum dpfail
+ GLenum dppass
+
+
+
+ void glStencilOpValueAMD
+ GLenum face
+ GLuint value
+
+
+ void glStencilStrokePathInstancedNV
+ GLsizei numPaths
+ GLenum pathNameType
+ const void *paths
+ GLuint pathBase
+ GLint reference
+ GLuint mask
+ GLenum transformType
+ const GLfloat *transformValues
+
+
+ void glStencilStrokePathNV
+ GLuint path
+ GLint reference
+ GLuint mask
+
+
+ void glStencilThenCoverFillPathInstancedNV
+ GLsizei numPaths
+ GLenum pathNameType
+ const void *paths
+ GLuint pathBase
+ GLenum fillMode
+ GLuint mask
+ GLenum coverMode
+ GLenum transformType
+ const GLfloat *transformValues
+
+
+ void glStencilThenCoverFillPathNV
+ GLuint path
+ GLenum fillMode
+ GLuint mask
+ GLenum coverMode
+
+
+ void glStencilThenCoverStrokePathInstancedNV
+ GLsizei numPaths
+ GLenum pathNameType
+ const void *paths
+ GLuint pathBase
+ GLint reference
+ GLuint mask
+ GLenum coverMode
+ GLenum transformType
+ const GLfloat *transformValues
+
+
+ void glStencilThenCoverStrokePathNV
+ GLuint path
+ GLint reference
+ GLuint mask
+ GLenum coverMode
+
+
+ void glStopInstrumentsSGIX
+ GLint marker
+
+
+
+ void glStringMarkerGREMEDY
+ GLsizei len
+ const void *string
+
+
+ void glSwizzleEXT
+ GLuint res
+ GLuint in
+ GLenum outX
+ GLenum outY
+ GLenum outZ
+ GLenum outW
+
+
+ void glSyncTextureINTEL
+ GLuint texture
+
+
+ void glTagSampleBufferSGIX
+
+
+
+ void glTangent3bEXT
+ GLbyte tx
+ GLbyte ty
+ GLbyte tz
+
+
+
+ void glTangent3bvEXT
+ const GLbyte *v
+
+
+ void glTangent3dEXT
+ GLdouble tx
+ GLdouble ty
+ GLdouble tz
+
+
+
+ void glTangent3dvEXT
+ const GLdouble *v
+
+
+ void glTangent3fEXT
+ GLfloat tx
+ GLfloat ty
+ GLfloat tz
+
+
+
+ void glTangent3fvEXT
+ const GLfloat *v
+
+
+ void glTangent3iEXT
+ GLint tx
+ GLint ty
+ GLint tz
+
+
+
+ void glTangent3ivEXT
+ const GLint *v
+
+
+ void glTangent3sEXT
+ GLshort tx
+ GLshort ty
+ GLshort tz
+
+
+
+ void glTangent3svEXT
+ const GLshort *v
+
+
+ void glTangentPointerEXT
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glTbufferMask3DFX
+ GLuint mask
+
+
+ void glTessellationFactorAMD
+ GLfloat factor
+
+
+ void glTessellationModeAMD
+ GLenum mode
+
+
+ GLboolean glTestFenceAPPLE
+ GLuint fence
+
+
+ GLboolean glTestFenceNV
+ GLuint fence
+
+
+
+ GLboolean glTestObjectAPPLE
+ GLenum object
+ GLuint name
+
+
+ void glTexBuffer
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+
+
+ void glTexBufferARB
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+
+
+
+ void glTexBufferEXT
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+
+
+
+ void glTexBufferOES
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+
+
+
+ void glTexBufferRange
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+
+
+ void glTexBufferRangeEXT
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+
+
+
+ void glTexBufferRangeOES
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+
+
+
+ void glTexBumpParameterfvATI
+ GLenum pname
+ const GLfloat *param
+
+
+ void glTexBumpParameterivATI
+ GLenum pname
+ const GLint *param
+
+
+ void glTexCoord1bOES
+ GLbyte s
+
+
+ void glTexCoord1bvOES
+ const GLbyte *coords
+
+
+ void glTexCoord1d
+ GLdouble s
+
+
+
+ void glTexCoord1dv
+ const GLdouble *v
+
+
+
+ void glTexCoord1f
+ GLfloat s
+
+
+
+ void glTexCoord1fv
+ const GLfloat *v
+
+
+
+ void glTexCoord1hNV
+ GLhalfNV s
+
+
+
+ void glTexCoord1hvNV
+ const GLhalfNV *v
+
+
+
+ void glTexCoord1i
+ GLint s
+
+
+
+ void glTexCoord1iv
+ const GLint *v
+
+
+
+ void glTexCoord1s
+ GLshort s
+
+
+
+ void glTexCoord1sv
+ const GLshort *v
+
+
+
+ void glTexCoord1xOES
+ GLfixed s
+
+
+ void glTexCoord1xvOES
+ const GLfixed *coords
+
+
+ void glTexCoord2bOES
+ GLbyte s
+ GLbyte t
+
+
+ void glTexCoord2bvOES
+ const GLbyte *coords
+
+
+ void glTexCoord2d
+ GLdouble s
+ GLdouble t
+
+
+
+ void glTexCoord2dv
+ const GLdouble *v
+
+
+
+ void glTexCoord2f
+ GLfloat s
+ GLfloat t
+
+
+
+ void glTexCoord2fColor3fVertex3fSUN
+ GLfloat s
+ GLfloat t
+ GLfloat r
+ GLfloat g
+ GLfloat b
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glTexCoord2fColor3fVertex3fvSUN
+ const GLfloat *tc
+ const GLfloat *c
+ const GLfloat *v
+
+
+ void glTexCoord2fColor4fNormal3fVertex3fSUN
+ GLfloat s
+ GLfloat t
+ GLfloat r
+ GLfloat g
+ GLfloat b
+ GLfloat a
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glTexCoord2fColor4fNormal3fVertex3fvSUN
+ const GLfloat *tc
+ const GLfloat *c
+ const GLfloat *n
+ const GLfloat *v
+
+
+ void glTexCoord2fColor4ubVertex3fSUN
+ GLfloat s
+ GLfloat t
+ GLubyte r
+ GLubyte g
+ GLubyte b
+ GLubyte a
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glTexCoord2fColor4ubVertex3fvSUN
+ const GLfloat *tc
+ const GLubyte *c
+ const GLfloat *v
+
+
+ void glTexCoord2fNormal3fVertex3fSUN
+ GLfloat s
+ GLfloat t
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glTexCoord2fNormal3fVertex3fvSUN
+ const GLfloat *tc
+ const GLfloat *n
+ const GLfloat *v
+
+
+ void glTexCoord2fVertex3fSUN
+ GLfloat s
+ GLfloat t
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glTexCoord2fVertex3fvSUN
+ const GLfloat *tc
+ const GLfloat *v
+
+
+ void glTexCoord2fv
+ const GLfloat *v
+
+
+
+ void glTexCoord2hNV
+ GLhalfNV s
+ GLhalfNV t
+
+
+
+ void glTexCoord2hvNV
+ const GLhalfNV *v
+
+
+
+ void glTexCoord2i
+ GLint s
+ GLint t
+
+
+
+ void glTexCoord2iv
+ const GLint *v
+
+
+
+ void glTexCoord2s
+ GLshort s
+ GLshort t
+
+
+
+ void glTexCoord2sv
+ const GLshort *v
+
+
+
+ void glTexCoord2xOES
+ GLfixed s
+ GLfixed t
+
+
+ void glTexCoord2xvOES
+ const GLfixed *coords
+
+
+ void glTexCoord3bOES
+ GLbyte s
+ GLbyte t
+ GLbyte r
+
+
+ void glTexCoord3bvOES
+ const GLbyte *coords
+
+
+ void glTexCoord3d
+ GLdouble s
+ GLdouble t
+ GLdouble r
+
+
+
+ void glTexCoord3dv
+ const GLdouble *v
+
+
+
+ void glTexCoord3f
+ GLfloat s
+ GLfloat t
+ GLfloat r
+
+
+
+ void glTexCoord3fv
+ const GLfloat *v
+
+
+
+ void glTexCoord3hNV
+ GLhalfNV s
+ GLhalfNV t
+ GLhalfNV r
+
+
+
+ void glTexCoord3hvNV
+ const GLhalfNV *v
+
+
+
+ void glTexCoord3i
+ GLint s
+ GLint t
+ GLint r
+
+
+
+ void glTexCoord3iv
+ const GLint *v
+
+
+
+ void glTexCoord3s
+ GLshort s
+ GLshort t
+ GLshort r
+
+
+
+ void glTexCoord3sv
+ const GLshort *v
+
+
+
+ void glTexCoord3xOES
+ GLfixed s
+ GLfixed t
+ GLfixed r
+
+
+ void glTexCoord3xvOES
+ const GLfixed *coords
+
+
+ void glTexCoord4bOES
+ GLbyte s
+ GLbyte t
+ GLbyte r
+ GLbyte q
+
+
+ void glTexCoord4bvOES
+ const GLbyte *coords
+
+
+ void glTexCoord4d
+ GLdouble s
+ GLdouble t
+ GLdouble r
+ GLdouble q
+
+
+
+ void glTexCoord4dv
+ const GLdouble *v
+
+
+
+ void glTexCoord4f
+ GLfloat s
+ GLfloat t
+ GLfloat r
+ GLfloat q
+
+
+
+ void glTexCoord4fColor4fNormal3fVertex4fSUN
+ GLfloat s
+ GLfloat t
+ GLfloat p
+ GLfloat q
+ GLfloat r
+ GLfloat g
+ GLfloat b
+ GLfloat a
+ GLfloat nx
+ GLfloat ny
+ GLfloat nz
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+ void glTexCoord4fColor4fNormal3fVertex4fvSUN
+ const GLfloat *tc
+ const GLfloat *c
+ const GLfloat *n
+ const GLfloat *v
+
+
+ void glTexCoord4fVertex4fSUN
+ GLfloat s
+ GLfloat t
+ GLfloat p
+ GLfloat q
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+ void glTexCoord4fVertex4fvSUN
+ const GLfloat *tc
+ const GLfloat *v
+
+
+ void glTexCoord4fv
+ const GLfloat *v
+
+
+
+ void glTexCoord4hNV
+ GLhalfNV s
+ GLhalfNV t
+ GLhalfNV r
+ GLhalfNV q
+
+
+
+ void glTexCoord4hvNV
+ const GLhalfNV *v
+
+
+
+ void glTexCoord4i
+ GLint s
+ GLint t
+ GLint r
+ GLint q
+
+
+
+ void glTexCoord4iv
+ const GLint *v
+
+
+
+ void glTexCoord4s
+ GLshort s
+ GLshort t
+ GLshort r
+ GLshort q
+
+
+
+ void glTexCoord4sv
+ const GLshort *v
+
+
+
+ void glTexCoord4xOES
+ GLfixed s
+ GLfixed t
+ GLfixed r
+ GLfixed q
+
+
+ void glTexCoord4xvOES
+ const GLfixed *coords
+
+
+ void glTexCoordFormatNV
+ GLint size
+ GLenum type
+ GLsizei stride
+
+
+ void glTexCoordP1ui
+ GLenum type
+ GLuint coords
+
+
+ void glTexCoordP1uiv
+ GLenum type
+ const GLuint *coords
+
+
+ void glTexCoordP2ui
+ GLenum type
+ GLuint coords
+
+
+ void glTexCoordP2uiv
+ GLenum type
+ const GLuint *coords
+
+
+ void glTexCoordP3ui
+ GLenum type
+ GLuint coords
+
+
+ void glTexCoordP3uiv
+ GLenum type
+ const GLuint *coords
+
+
+ void glTexCoordP4ui
+ GLenum type
+ GLuint coords
+
+
+ void glTexCoordP4uiv
+ GLenum type
+ const GLuint *coords
+
+
+ void glTexCoordPointer
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glTexCoordPointerEXT
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLsizei count
+ const void *pointer
+
+
+ void glTexCoordPointerListIBM
+ GLint size
+ GLenum type
+ GLint stride
+ const void **pointer
+ GLint ptrstride
+
+
+ void glTexCoordPointervINTEL
+ GLint size
+ GLenum type
+ const void **pointer
+
+
+ void glTexEnvf
+ GLenum target
+ GLenum pname
+ GLfloat param
+
+
+
+ void glTexEnvfv
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glTexEnvi
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+
+ void glTexEnviv
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+
+ void glTexEnvx
+ GLenum target
+ GLenum pname
+ GLfixed param
+
+
+ void glTexEnvxOES
+ GLenum target
+ GLenum pname
+ GLfixed param
+
+
+ void glTexEnvxv
+ GLenum target
+ GLenum pname
+ const GLfixed *params
+
+
+ void glTexEnvxvOES
+ GLenum target
+ GLenum pname
+ const GLfixed *params
+
+
+ void glTexFilterFuncSGIS
+ GLenum target
+ GLenum filter
+ GLsizei n
+ const GLfloat *weights
+
+
+
+ void glTexGend
+ GLenum coord
+ GLenum pname
+ GLdouble param
+
+
+
+ void glTexGendv
+ GLenum coord
+ GLenum pname
+ const GLdouble *params
+
+
+
+ void glTexGenf
+ GLenum coord
+ GLenum pname
+ GLfloat param
+
+
+
+ void glTexGenfOES
+ GLenum coord
+ GLenum pname
+ GLfloat param
+
+
+ void glTexGenfv
+ GLenum coord
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glTexGenfvOES
+ GLenum coord
+ GLenum pname
+ const GLfloat *params
+
+
+ void glTexGeni
+ GLenum coord
+ GLenum pname
+ GLint param
+
+
+
+ void glTexGeniOES
+ GLenum coord
+ GLenum pname
+ GLint param
+
+
+ void glTexGeniv
+ GLenum coord
+ GLenum pname
+ const GLint *params
+
+
+
+ void glTexGenivOES
+ GLenum coord
+ GLenum pname
+ const GLint *params
+
+
+ void glTexGenxOES
+ GLenum coord
+ GLenum pname
+ GLfixed param
+
+
+ void glTexGenxvOES
+ GLenum coord
+ GLenum pname
+ const GLfixed *params
+
+
+ void glTexImage1D
+ GLenum target
+ GLint level
+ GLint internalformat
+ GLsizei width
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexImage2D
+ GLenum target
+ GLint level
+ GLint internalformat
+ GLsizei width
+ GLsizei height
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexImage2DMultisample
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLboolean fixedsamplelocations
+
+
+ void glTexImage2DMultisampleCoverageNV
+ GLenum target
+ GLsizei coverageSamples
+ GLsizei colorSamples
+ GLint internalFormat
+ GLsizei width
+ GLsizei height
+ GLboolean fixedSampleLocations
+
+
+ void glTexImage3D
+ GLenum target
+ GLint level
+ GLint internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexImage3DEXT
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexImage3DMultisample
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean fixedsamplelocations
+
+
+ void glTexImage3DMultisampleCoverageNV
+ GLenum target
+ GLsizei coverageSamples
+ GLsizei colorSamples
+ GLint internalFormat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean fixedSampleLocations
+
+
+ void glTexImage3DOES
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+ void glTexImage4DSGIS
+ GLenum target
+ GLint level
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLsizei size4d
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+ void glTexPageCommitmentARB
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean commit
+
+
+ void glTexPageCommitmentEXT
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean commit
+
+
+
+ void glTexParameterIiv
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+
+ void glTexParameterIivEXT
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+
+ void glTexParameterIivOES
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+
+ void glTexParameterIuiv
+ GLenum target
+ GLenum pname
+ const GLuint *params
+
+
+
+ void glTexParameterIuivEXT
+ GLenum target
+ GLenum pname
+ const GLuint *params
+
+
+
+ void glTexParameterIuivOES
+ GLenum target
+ GLenum pname
+ const GLuint *params
+
+
+
+ void glTexParameterf
+ GLenum target
+ GLenum pname
+ GLfloat param
+
+
+
+ void glTexParameterfv
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+
+ void glTexParameteri
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+
+ void glTexParameteriv
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+
+ void glTexParameterx
+ GLenum target
+ GLenum pname
+ GLfixed param
+
+
+ void glTexParameterxOES
+ GLenum target
+ GLenum pname
+ GLfixed param
+
+
+ void glTexParameterxv
+ GLenum target
+ GLenum pname
+ const GLfixed *params
+
+
+ void glTexParameterxvOES
+ GLenum target
+ GLenum pname
+ const GLfixed *params
+
+
+ void glTexRenderbufferNV
+ GLenum target
+ GLuint renderbuffer
+
+
+ void glTexStorage1D
+ GLenum target
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+
+
+ void glTexStorage1DEXT
+ GLenum target
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+
+
+
+ void glTexStorage2D
+ GLenum target
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glTexStorage2DEXT
+ GLenum target
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+
+ void glTexStorage2DMultisample
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLboolean fixedsamplelocations
+
+
+ void glTexStorage3D
+ GLenum target
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+
+
+ void glTexStorage3DEXT
+ GLenum target
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+
+
+
+ void glTexStorage3DMultisample
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean fixedsamplelocations
+
+
+ void glTexStorage3DMultisampleOES
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean fixedsamplelocations
+
+
+
+ void glTexStorageSparseAMD
+ GLenum target
+ GLenum internalFormat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLsizei layers
+ GLbitfield flags
+
+
+ void glTexSubImage1D
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexSubImage1DEXT
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexSubImage2D
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexSubImage2DEXT
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexSubImage3D
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexSubImage3DEXT
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+
+ void glTexSubImage3DOES
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+ void glTexSubImage4DSGIS
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLint woffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLsizei size4d
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+
+ void glTextureBarrier
+
+
+ void glTextureBarrierNV
+
+
+
+ void glTextureBuffer
+ GLuint texture
+ GLenum internalformat
+ GLuint buffer
+
+
+ void glTextureBufferEXT
+ GLuint texture
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+
+
+ void glTextureBufferRange
+ GLuint texture
+ GLenum internalformat
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+
+
+ void glTextureBufferRangeEXT
+ GLuint texture
+ GLenum target
+ GLenum internalformat
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+
+
+ void glTextureColorMaskSGIS
+ GLboolean red
+ GLboolean green
+ GLboolean blue
+ GLboolean alpha
+
+
+
+ void glTextureImage1DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint internalformat
+ GLsizei width
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glTextureImage2DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint internalformat
+ GLsizei width
+ GLsizei height
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glTextureImage2DMultisampleCoverageNV
+ GLuint texture
+ GLenum target
+ GLsizei coverageSamples
+ GLsizei colorSamples
+ GLint internalFormat
+ GLsizei width
+ GLsizei height
+ GLboolean fixedSampleLocations
+
+
+ void glTextureImage2DMultisampleNV
+ GLuint texture
+ GLenum target
+ GLsizei samples
+ GLint internalFormat
+ GLsizei width
+ GLsizei height
+ GLboolean fixedSampleLocations
+
+
+ void glTextureImage3DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLint border
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glTextureImage3DMultisampleCoverageNV
+ GLuint texture
+ GLenum target
+ GLsizei coverageSamples
+ GLsizei colorSamples
+ GLint internalFormat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean fixedSampleLocations
+
+
+ void glTextureImage3DMultisampleNV
+ GLuint texture
+ GLenum target
+ GLsizei samples
+ GLint internalFormat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean fixedSampleLocations
+
+
+ void glTextureLightEXT
+ GLenum pname
+
+
+ void glTextureMaterialEXT
+ GLenum face
+ GLenum mode
+
+
+ void glTextureNormalEXT
+ GLenum mode
+
+
+ void glTexturePageCommitmentEXT
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean commit
+
+
+ void glTextureParameterIiv
+ GLuint texture
+ GLenum pname
+ const GLint *params
+
+
+ void glTextureParameterIivEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+ void glTextureParameterIuiv
+ GLuint texture
+ GLenum pname
+ const GLuint *params
+
+
+ void glTextureParameterIuivEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ const GLuint *params
+
+
+ void glTextureParameterf
+ GLuint texture
+ GLenum pname
+ GLfloat param
+
+
+ void glTextureParameterfEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ GLfloat param
+
+
+
+ void glTextureParameterfv
+ GLuint texture
+ GLenum pname
+ const GLfloat *param
+
+
+ void glTextureParameterfvEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ const GLfloat *params
+
+
+ void glTextureParameteri
+ GLuint texture
+ GLenum pname
+ GLint param
+
+
+ void glTextureParameteriEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ GLint param
+
+
+
+ void glTextureParameteriv
+ GLuint texture
+ GLenum pname
+ const GLint *param
+
+
+ void glTextureParameterivEXT
+ GLuint texture
+ GLenum target
+ GLenum pname
+ const GLint *params
+
+
+ void glTextureRangeAPPLE
+ GLenum target
+ GLsizei length
+ const void *pointer
+
+
+ void glTextureRenderbufferEXT
+ GLuint texture
+ GLenum target
+ GLuint renderbuffer
+
+
+ void glTextureStorage1D
+ GLuint texture
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+
+
+ void glTextureStorage1DEXT
+ GLuint texture
+ GLenum target
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+
+
+ void glTextureStorage2D
+ GLuint texture
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glTextureStorage2DEXT
+ GLuint texture
+ GLenum target
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+
+
+ void glTextureStorage2DMultisample
+ GLuint texture
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLboolean fixedsamplelocations
+
+
+ void glTextureStorage2DMultisampleEXT
+ GLuint texture
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLboolean fixedsamplelocations
+
+
+ void glTextureStorage3D
+ GLuint texture
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+
+
+ void glTextureStorage3DEXT
+ GLuint texture
+ GLenum target
+ GLsizei levels
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+
+
+ void glTextureStorage3DMultisample
+ GLuint texture
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean fixedsamplelocations
+
+
+ void glTextureStorage3DMultisampleEXT
+ GLuint texture
+ GLenum target
+ GLsizei samples
+ GLenum internalformat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLboolean fixedsamplelocations
+
+
+ void glTextureStorageSparseAMD
+ GLuint texture
+ GLenum target
+ GLenum internalFormat
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLsizei layers
+ GLbitfield flags
+
+
+ void glTextureSubImage1D
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glTextureSubImage1DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLsizei width
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glTextureSubImage2D
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glTextureSubImage2DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLsizei width
+ GLsizei height
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glTextureSubImage3D
+ GLuint texture
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glTextureSubImage3DEXT
+ GLuint texture
+ GLenum target
+ GLint level
+ GLint xoffset
+ GLint yoffset
+ GLint zoffset
+ GLsizei width
+ GLsizei height
+ GLsizei depth
+ GLenum format
+ GLenum type
+ const void *pixels
+
+
+ void glTextureView
+ GLuint texture
+ GLenum target
+ GLuint origtexture
+ GLenum internalformat
+ GLuint minlevel
+ GLuint numlevels
+ GLuint minlayer
+ GLuint numlayers
+
+
+ void glTextureViewEXT
+ GLuint texture
+ GLenum target
+ GLuint origtexture
+ GLenum internalformat
+ GLuint minlevel
+ GLuint numlevels
+ GLuint minlayer
+ GLuint numlayers
+
+
+
+ void glTextureViewOES
+ GLuint texture
+ GLenum target
+ GLuint origtexture
+ GLenum internalformat
+ GLuint minlevel
+ GLuint numlevels
+ GLuint minlayer
+ GLuint numlayers
+
+
+
+ void glTrackMatrixNV
+ GLenum target
+ GLuint address
+ GLenum matrix
+ GLenum transform
+
+
+
+ void glTransformFeedbackAttribsNV
+ GLsizei count
+ const GLint *attribs
+ GLenum bufferMode
+
+
+ void glTransformFeedbackBufferBase
+ GLuint xfb
+ GLuint index
+ GLuint buffer
+
+
+ void glTransformFeedbackBufferRange
+ GLuint xfb
+ GLuint index
+ GLuint buffer
+ GLintptr offset
+ GLsizeiptr size
+
+
+ void glTransformFeedbackStreamAttribsNV
+ GLsizei count
+ const GLint *attribs
+ GLsizei nbuffers
+ const GLint *bufstreams
+ GLenum bufferMode
+
+
+ void glTransformFeedbackVaryings
+ GLuint program
+ GLsizei count
+ const GLchar *const*varyings
+ GLenum bufferMode
+
+
+ void glTransformFeedbackVaryingsEXT
+ GLuint program
+ GLsizei count
+ const GLchar *const*varyings
+ GLenum bufferMode
+
+
+
+ void glTransformFeedbackVaryingsNV
+ GLuint program
+ GLsizei count
+ const GLint *locations
+ GLenum bufferMode
+
+
+ void glTransformPathNV
+ GLuint resultPath
+ GLuint srcPath
+ GLenum transformType
+ const GLfloat *transformValues
+
+
+ void glTranslated
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+ void glTranslatef
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+ void glTranslatex
+ GLfixed x
+ GLfixed y
+ GLfixed z
+
+
+ void glTranslatexOES
+ GLfixed x
+ GLfixed y
+ GLfixed z
+
+
+ void glUniform1d
+ GLint location
+ GLdouble x
+
+
+ void glUniform1dv
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glUniform1f
+ GLint location
+ GLfloat v0
+
+
+ void glUniform1fARB
+ GLint location
+ GLfloat v0
+
+
+
+ void glUniform1fv
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+ void glUniform1fvARB
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+
+ void glUniform1i
+ GLint location
+ GLint v0
+
+
+ void glUniform1i64NV
+ GLint location
+ GLint64EXT x
+
+
+ void glUniform1i64vNV
+ GLint location
+ GLsizei count
+ const GLint64EXT *value
+
+
+ void glUniform1iARB
+ GLint location
+ GLint v0
+
+
+
+ void glUniform1iv
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+ void glUniform1ivARB
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+
+ void glUniform1ui
+ GLint location
+ GLuint v0
+
+
+ void glUniform1ui64NV
+ GLint location
+ GLuint64EXT x
+
+
+ void glUniform1ui64vNV
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glUniform1uiEXT
+ GLint location
+ GLuint v0
+
+
+
+ void glUniform1uiv
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+ void glUniform1uivEXT
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+
+ void glUniform2d
+ GLint location
+ GLdouble x
+ GLdouble y
+
+
+ void glUniform2dv
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glUniform2f
+ GLint location
+ GLfloat v0
+ GLfloat v1
+
+
+ void glUniform2fARB
+ GLint location
+ GLfloat v0
+ GLfloat v1
+
+
+
+ void glUniform2fv
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+ void glUniform2fvARB
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+
+ void glUniform2i
+ GLint location
+ GLint v0
+ GLint v1
+
+
+ void glUniform2i64NV
+ GLint location
+ GLint64EXT x
+ GLint64EXT y
+
+
+ void glUniform2i64vNV
+ GLint location
+ GLsizei count
+ const GLint64EXT *value
+
+
+ void glUniform2iARB
+ GLint location
+ GLint v0
+ GLint v1
+
+
+
+ void glUniform2iv
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+ void glUniform2ivARB
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+
+ void glUniform2ui
+ GLint location
+ GLuint v0
+ GLuint v1
+
+
+ void glUniform2ui64NV
+ GLint location
+ GLuint64EXT x
+ GLuint64EXT y
+
+
+ void glUniform2ui64vNV
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glUniform2uiEXT
+ GLint location
+ GLuint v0
+ GLuint v1
+
+
+
+ void glUniform2uiv
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+ void glUniform2uivEXT
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+
+ void glUniform3d
+ GLint location
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+ void glUniform3dv
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glUniform3f
+ GLint location
+ GLfloat v0
+ GLfloat v1
+ GLfloat v2
+
+
+ void glUniform3fARB
+ GLint location
+ GLfloat v0
+ GLfloat v1
+ GLfloat v2
+
+
+
+ void glUniform3fv
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+ void glUniform3fvARB
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+
+ void glUniform3i
+ GLint location
+ GLint v0
+ GLint v1
+ GLint v2
+
+
+ void glUniform3i64NV
+ GLint location
+ GLint64EXT x
+ GLint64EXT y
+ GLint64EXT z
+
+
+ void glUniform3i64vNV
+ GLint location
+ GLsizei count
+ const GLint64EXT *value
+
+
+ void glUniform3iARB
+ GLint location
+ GLint v0
+ GLint v1
+ GLint v2
+
+
+
+ void glUniform3iv
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+ void glUniform3ivARB
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+
+ void glUniform3ui
+ GLint location
+ GLuint v0
+ GLuint v1
+ GLuint v2
+
+
+ void glUniform3ui64NV
+ GLint location
+ GLuint64EXT x
+ GLuint64EXT y
+ GLuint64EXT z
+
+
+ void glUniform3ui64vNV
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glUniform3uiEXT
+ GLint location
+ GLuint v0
+ GLuint v1
+ GLuint v2
+
+
+
+ void glUniform3uiv
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+ void glUniform3uivEXT
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+
+ void glUniform4d
+ GLint location
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+ void glUniform4dv
+ GLint location
+ GLsizei count
+ const GLdouble *value
+
+
+ void glUniform4f
+ GLint location
+ GLfloat v0
+ GLfloat v1
+ GLfloat v2
+ GLfloat v3
+
+
+ void glUniform4fARB
+ GLint location
+ GLfloat v0
+ GLfloat v1
+ GLfloat v2
+ GLfloat v3
+
+
+
+ void glUniform4fv
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+ void glUniform4fvARB
+ GLint location
+ GLsizei count
+ const GLfloat *value
+
+
+
+ void glUniform4i
+ GLint location
+ GLint v0
+ GLint v1
+ GLint v2
+ GLint v3
+
+
+ void glUniform4i64NV
+ GLint location
+ GLint64EXT x
+ GLint64EXT y
+ GLint64EXT z
+ GLint64EXT w
+
+
+ void glUniform4i64vNV
+ GLint location
+ GLsizei count
+ const GLint64EXT *value
+
+
+ void glUniform4iARB
+ GLint location
+ GLint v0
+ GLint v1
+ GLint v2
+ GLint v3
+
+
+
+ void glUniform4iv
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+ void glUniform4ivARB
+ GLint location
+ GLsizei count
+ const GLint *value
+
+
+
+ void glUniform4ui
+ GLint location
+ GLuint v0
+ GLuint v1
+ GLuint v2
+ GLuint v3
+
+
+ void glUniform4ui64NV
+ GLint location
+ GLuint64EXT x
+ GLuint64EXT y
+ GLuint64EXT z
+ GLuint64EXT w
+
+
+ void glUniform4ui64vNV
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glUniform4uiEXT
+ GLint location
+ GLuint v0
+ GLuint v1
+ GLuint v2
+ GLuint v3
+
+
+
+ void glUniform4uiv
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+ void glUniform4uivEXT
+ GLint location
+ GLsizei count
+ const GLuint *value
+
+
+
+ void glUniformBlockBinding
+ GLuint program
+ GLuint uniformBlockIndex
+ GLuint uniformBlockBinding
+
+
+ void glUniformBufferEXT
+ GLuint program
+ GLint location
+ GLuint buffer
+
+
+ void glUniformHandleui64ARB
+ GLint location
+ GLuint64 value
+
+
+ void glUniformHandleui64NV
+ GLint location
+ GLuint64 value
+
+
+ void glUniformHandleui64vARB
+ GLint location
+ GLsizei count
+ const GLuint64 *value
+
+
+ void glUniformHandleui64vNV
+ GLint location
+ GLsizei count
+ const GLuint64 *value
+
+
+ void glUniformMatrix2dv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glUniformMatrix2fv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glUniformMatrix2fvARB
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix2x3dv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glUniformMatrix2x3fv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix2x3fvNV
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix2x4dv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glUniformMatrix2x4fv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix2x4fvNV
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix3dv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glUniformMatrix3fv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glUniformMatrix3fvARB
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix3x2dv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glUniformMatrix3x2fv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix3x2fvNV
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix3x4dv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glUniformMatrix3x4fv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix3x4fvNV
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix4dv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glUniformMatrix4fv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+ void glUniformMatrix4fvARB
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix4x2dv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glUniformMatrix4x2fv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix4x2fvNV
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix4x3dv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLdouble *value
+
+
+ void glUniformMatrix4x3fv
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformMatrix4x3fvNV
+ GLint location
+ GLsizei count
+ GLboolean transpose
+ const GLfloat *value
+
+
+
+ void glUniformSubroutinesuiv
+ GLenum shadertype
+ GLsizei count
+ const GLuint *indices
+
+
+ void glUniformui64NV
+ GLint location
+ GLuint64EXT value
+
+
+ void glUniformui64vNV
+ GLint location
+ GLsizei count
+ const GLuint64EXT *value
+
+
+ void glUnlockArraysEXT
+
+
+ GLboolean glUnmapBuffer
+ GLenum target
+
+
+ GLboolean glUnmapBufferARB
+ GLenum target
+
+
+
+ GLboolean glUnmapBufferOES
+ GLenum target
+
+
+
+ GLboolean glUnmapNamedBuffer
+ GLuint buffer
+
+
+ GLboolean glUnmapNamedBufferEXT
+ GLuint buffer
+
+
+ void glUnmapObjectBufferATI
+ GLuint buffer
+
+
+ void glUnmapTexture2DINTEL
+ GLuint texture
+ GLint level
+
+
+ void glUpdateObjectBufferATI
+ GLuint buffer
+ GLuint offset
+ GLsizei size
+ const void *pointer
+ GLenum preserve
+
+
+ void glUseProgram
+ GLuint program
+
+
+ void glUseProgramObjectARB
+ GLhandleARB programObj
+
+
+
+ void glUseProgramStages
+ GLuint pipeline
+ GLbitfield stages
+ GLuint program
+
+
+ void glUseProgramStagesEXT
+ GLuint pipeline
+ GLbitfield stages
+ GLuint program
+
+
+ void glUseShaderProgramEXT
+ GLenum type
+ GLuint program
+
+
+ void glVDPAUFiniNV
+
+
+ void glVDPAUGetSurfaceivNV
+ GLvdpauSurfaceNV surface
+ GLenum pname
+ GLsizei bufSize
+ GLsizei *length
+ GLint *values
+
+
+ void glVDPAUInitNV
+ const void *vdpDevice
+ const void *getProcAddress
+
+
+ GLboolean glVDPAUIsSurfaceNV
+ GLvdpauSurfaceNV surface
+
+
+ void glVDPAUMapSurfacesNV
+ GLsizei numSurfaces
+ const GLvdpauSurfaceNV *surfaces
+
+
+ GLvdpauSurfaceNV glVDPAURegisterOutputSurfaceNV
+ const void *vdpSurface
+ GLenum target
+ GLsizei numTextureNames
+ const GLuint *textureNames
+
+
+ GLvdpauSurfaceNV glVDPAURegisterVideoSurfaceNV
+ const void *vdpSurface
+ GLenum target
+ GLsizei numTextureNames
+ const GLuint *textureNames
+
+
+ void glVDPAUSurfaceAccessNV
+ GLvdpauSurfaceNV surface
+ GLenum access
+
+
+ void glVDPAUUnmapSurfacesNV
+ GLsizei numSurface
+ const GLvdpauSurfaceNV *surfaces
+
+
+ void glVDPAUUnregisterSurfaceNV
+ GLvdpauSurfaceNV surface
+
+
+ void glValidateProgram
+ GLuint program
+
+
+ void glValidateProgramARB
+ GLhandleARB programObj
+
+
+
+ void glValidateProgramPipeline
+ GLuint pipeline
+
+
+ void glValidateProgramPipelineEXT
+ GLuint pipeline
+
+
+ void glVariantArrayObjectATI
+ GLuint id
+ GLenum type
+ GLsizei stride
+ GLuint buffer
+ GLuint offset
+
+
+ void glVariantPointerEXT
+ GLuint id
+ GLenum type
+ GLuint stride
+ const void *addr
+
+
+ void glVariantbvEXT
+ GLuint id
+ const GLbyte *addr
+
+
+ void glVariantdvEXT
+ GLuint id
+ const GLdouble *addr
+
+
+ void glVariantfvEXT
+ GLuint id
+ const GLfloat *addr
+
+
+ void glVariantivEXT
+ GLuint id
+ const GLint *addr
+
+
+ void glVariantsvEXT
+ GLuint id
+ const GLshort *addr
+
+
+ void glVariantubvEXT
+ GLuint id
+ const GLubyte *addr
+
+
+ void glVariantuivEXT
+ GLuint id
+ const GLuint *addr
+
+
+ void glVariantusvEXT
+ GLuint id
+ const GLushort *addr
+
+
+ void glVertex2bOES
+ GLbyte x
+ GLbyte y
+
+
+ void glVertex2bvOES
+ const GLbyte *coords
+
+
+ void glVertex2d
+ GLdouble x
+ GLdouble y
+
+
+
+ void glVertex2dv
+ const GLdouble *v
+
+
+
+ void glVertex2f
+ GLfloat x
+ GLfloat y
+
+
+
+ void glVertex2fv
+ const GLfloat *v
+
+
+
+ void glVertex2hNV
+ GLhalfNV x
+ GLhalfNV y
+
+
+
+ void glVertex2hvNV
+ const GLhalfNV *v
+
+
+
+ void glVertex2i
+ GLint x
+ GLint y
+
+
+
+ void glVertex2iv
+ const GLint *v
+
+
+
+ void glVertex2s
+ GLshort x
+ GLshort y
+
+
+
+ void glVertex2sv
+ const GLshort *v
+
+
+
+ void glVertex2xOES
+ GLfixed x
+
+
+ void glVertex2xvOES
+ const GLfixed *coords
+
+
+ void glVertex3bOES
+ GLbyte x
+ GLbyte y
+ GLbyte z
+
+
+ void glVertex3bvOES
+ const GLbyte *coords
+
+
+ void glVertex3d
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+ void glVertex3dv
+ const GLdouble *v
+
+
+
+ void glVertex3f
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+ void glVertex3fv
+ const GLfloat *v
+
+
+
+ void glVertex3hNV
+ GLhalfNV x
+ GLhalfNV y
+ GLhalfNV z
+
+
+
+ void glVertex3hvNV
+ const GLhalfNV *v
+
+
+
+ void glVertex3i
+ GLint x
+ GLint y
+ GLint z
+
+
+
+ void glVertex3iv
+ const GLint *v
+
+
+
+ void glVertex3s
+ GLshort x
+ GLshort y
+ GLshort z
+
+
+
+ void glVertex3sv
+ const GLshort *v
+
+
+
+ void glVertex3xOES
+ GLfixed x
+ GLfixed y
+
+
+ void glVertex3xvOES
+ const GLfixed *coords
+
+
+ void glVertex4bOES
+ GLbyte x
+ GLbyte y
+ GLbyte z
+ GLbyte w
+
+
+ void glVertex4bvOES
+ const GLbyte *coords
+
+
+ void glVertex4d
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glVertex4dv
+ const GLdouble *v
+
+
+
+ void glVertex4f
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+ void glVertex4fv
+ const GLfloat *v
+
+
+
+ void glVertex4hNV
+ GLhalfNV x
+ GLhalfNV y
+ GLhalfNV z
+ GLhalfNV w
+
+
+
+ void glVertex4hvNV
+ const GLhalfNV *v
+
+
+
+ void glVertex4i
+ GLint x
+ GLint y
+ GLint z
+ GLint w
+
+
+
+ void glVertex4iv
+ const GLint *v
+
+
+
+ void glVertex4s
+ GLshort x
+ GLshort y
+ GLshort z
+ GLshort w
+
+
+
+ void glVertex4sv
+ const GLshort *v
+
+
+
+ void glVertex4xOES
+ GLfixed x
+ GLfixed y
+ GLfixed z
+
+
+ void glVertex4xvOES
+ const GLfixed *coords
+
+
+ void glVertexArrayAttribBinding
+ GLuint vaobj
+ GLuint attribindex
+ GLuint bindingindex
+
+
+ void glVertexArrayAttribFormat
+ GLuint vaobj
+ GLuint attribindex
+ GLint size
+ GLenum type
+ GLboolean normalized
+ GLuint relativeoffset
+
+
+ void glVertexArrayAttribIFormat
+ GLuint vaobj
+ GLuint attribindex
+ GLint size
+ GLenum type
+ GLuint relativeoffset
+
+
+ void glVertexArrayAttribLFormat
+ GLuint vaobj
+ GLuint attribindex
+ GLint size
+ GLenum type
+ GLuint relativeoffset
+
+
+ void glVertexArrayBindVertexBufferEXT
+ GLuint vaobj
+ GLuint bindingindex
+ GLuint buffer
+ GLintptr offset
+ GLsizei stride
+
+
+ void glVertexArrayBindingDivisor
+ GLuint vaobj
+ GLuint bindingindex
+ GLuint divisor
+
+
+ void glVertexArrayColorOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayEdgeFlagOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayElementBuffer
+ GLuint vaobj
+ GLuint buffer
+
+
+ void glVertexArrayFogCoordOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayIndexOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayMultiTexCoordOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLenum texunit
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayNormalOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayParameteriAPPLE
+ GLenum pname
+ GLint param
+
+
+ void glVertexArrayRangeAPPLE
+ GLsizei length
+ void *pointer
+
+
+ void glVertexArrayRangeNV
+ GLsizei length
+ const void *pointer
+
+
+ void glVertexArraySecondaryColorOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayTexCoordOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayVertexAttribBindingEXT
+ GLuint vaobj
+ GLuint attribindex
+ GLuint bindingindex
+
+
+ void glVertexArrayVertexAttribDivisorEXT
+ GLuint vaobj
+ GLuint index
+ GLuint divisor
+
+
+ void glVertexArrayVertexAttribFormatEXT
+ GLuint vaobj
+ GLuint attribindex
+ GLint size
+ GLenum type
+ GLboolean normalized
+ GLuint relativeoffset
+
+
+ void glVertexArrayVertexAttribIFormatEXT
+ GLuint vaobj
+ GLuint attribindex
+ GLint size
+ GLenum type
+ GLuint relativeoffset
+
+
+ void glVertexArrayVertexAttribIOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLuint index
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayVertexAttribLFormatEXT
+ GLuint vaobj
+ GLuint attribindex
+ GLint size
+ GLenum type
+ GLuint relativeoffset
+
+
+ void glVertexArrayVertexAttribLOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLuint index
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayVertexAttribOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLuint index
+ GLint size
+ GLenum type
+ GLboolean normalized
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexArrayVertexBindingDivisorEXT
+ GLuint vaobj
+ GLuint bindingindex
+ GLuint divisor
+
+
+ void glVertexArrayVertexBuffer
+ GLuint vaobj
+ GLuint bindingindex
+ GLuint buffer
+ GLintptr offset
+ GLsizei stride
+
+
+ void glVertexArrayVertexBuffers
+ GLuint vaobj
+ GLuint first
+ GLsizei count
+ const GLuint *buffers
+ const GLintptr *offsets
+ const GLsizei *strides
+
+
+ void glVertexArrayVertexOffsetEXT
+ GLuint vaobj
+ GLuint buffer
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLintptr offset
+
+
+ void glVertexAttrib1d
+ GLuint index
+ GLdouble x
+
+
+
+ void glVertexAttrib1dARB
+ GLuint index
+ GLdouble x
+
+
+
+
+ void glVertexAttrib1dNV
+ GLuint index
+ GLdouble x
+
+
+
+
+ void glVertexAttrib1dv
+ GLuint index
+ const GLdouble *v
+
+
+
+ void glVertexAttrib1dvARB
+ GLuint index
+ const GLdouble *v
+
+
+
+
+ void glVertexAttrib1dvNV
+ GLuint index
+ const GLdouble *v
+
+
+
+
+ void glVertexAttrib1f
+ GLuint index
+ GLfloat x
+
+
+
+ void glVertexAttrib1fARB
+ GLuint index
+ GLfloat x
+
+
+
+
+ void glVertexAttrib1fNV
+ GLuint index
+ GLfloat x
+
+
+
+
+ void glVertexAttrib1fv
+ GLuint index
+ const GLfloat *v
+
+
+
+ void glVertexAttrib1fvARB
+ GLuint index
+ const GLfloat *v
+
+
+
+
+ void glVertexAttrib1fvNV
+ GLuint index
+ const GLfloat *v
+
+
+
+
+ void glVertexAttrib1hNV
+ GLuint index
+ GLhalfNV x
+
+
+
+ void glVertexAttrib1hvNV
+ GLuint index
+ const GLhalfNV *v
+
+
+
+ void glVertexAttrib1s
+ GLuint index
+ GLshort x
+
+
+
+ void glVertexAttrib1sARB
+ GLuint index
+ GLshort x
+
+
+
+
+ void glVertexAttrib1sNV
+ GLuint index
+ GLshort x
+
+
+
+
+ void glVertexAttrib1sv
+ GLuint index
+ const GLshort *v
+
+
+
+ void glVertexAttrib1svARB
+ GLuint index
+ const GLshort *v
+
+
+
+
+ void glVertexAttrib1svNV
+ GLuint index
+ const GLshort *v
+
+
+
+
+ void glVertexAttrib2d
+ GLuint index
+ GLdouble x
+ GLdouble y
+
+
+
+ void glVertexAttrib2dARB
+ GLuint index
+ GLdouble x
+ GLdouble y
+
+
+
+
+ void glVertexAttrib2dNV
+ GLuint index
+ GLdouble x
+ GLdouble y
+
+
+
+
+ void glVertexAttrib2dv
+ GLuint index
+ const GLdouble *v
+
+
+
+ void glVertexAttrib2dvARB
+ GLuint index
+ const GLdouble *v
+
+
+
+
+ void glVertexAttrib2dvNV
+ GLuint index
+ const GLdouble *v
+
+
+
+
+ void glVertexAttrib2f
+ GLuint index
+ GLfloat x
+ GLfloat y
+
+
+
+ void glVertexAttrib2fARB
+ GLuint index
+ GLfloat x
+ GLfloat y
+
+
+
+
+ void glVertexAttrib2fNV
+ GLuint index
+ GLfloat x
+ GLfloat y
+
+
+
+
+ void glVertexAttrib2fv
+ GLuint index
+ const GLfloat *v
+
+
+
+ void glVertexAttrib2fvARB
+ GLuint index
+ const GLfloat *v
+
+
+
+
+ void glVertexAttrib2fvNV
+ GLuint index
+ const GLfloat *v
+
+
+
+
+ void glVertexAttrib2hNV
+ GLuint index
+ GLhalfNV x
+ GLhalfNV y
+
+
+
+ void glVertexAttrib2hvNV
+ GLuint index
+ const GLhalfNV *v
+
+
+
+ void glVertexAttrib2s
+ GLuint index
+ GLshort x
+ GLshort y
+
+
+
+ void glVertexAttrib2sARB
+ GLuint index
+ GLshort x
+ GLshort y
+
+
+
+
+ void glVertexAttrib2sNV
+ GLuint index
+ GLshort x
+ GLshort y
+
+
+
+
+ void glVertexAttrib2sv
+ GLuint index
+ const GLshort *v
+
+
+
+ void glVertexAttrib2svARB
+ GLuint index
+ const GLshort *v
+
+
+
+
+ void glVertexAttrib2svNV
+ GLuint index
+ const GLshort *v
+
+
+
+
+ void glVertexAttrib3d
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+ void glVertexAttrib3dARB
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+
+ void glVertexAttrib3dNV
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+
+ void glVertexAttrib3dv
+ GLuint index
+ const GLdouble *v
+
+
+
+ void glVertexAttrib3dvARB
+ GLuint index
+ const GLdouble *v
+
+
+
+
+ void glVertexAttrib3dvNV
+ GLuint index
+ const GLdouble *v
+
+
+
+
+ void glVertexAttrib3f
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+ void glVertexAttrib3fARB
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+
+ void glVertexAttrib3fNV
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+
+ void glVertexAttrib3fv
+ GLuint index
+ const GLfloat *v
+
+
+
+ void glVertexAttrib3fvARB
+ GLuint index
+ const GLfloat *v
+
+
+
+
+ void glVertexAttrib3fvNV
+ GLuint index
+ const GLfloat *v
+
+
+
+
+ void glVertexAttrib3hNV
+ GLuint index
+ GLhalfNV x
+ GLhalfNV y
+ GLhalfNV z
+
+
+
+ void glVertexAttrib3hvNV
+ GLuint index
+ const GLhalfNV *v
+
+
+
+ void glVertexAttrib3s
+ GLuint index
+ GLshort x
+ GLshort y
+ GLshort z
+
+
+
+ void glVertexAttrib3sARB
+ GLuint index
+ GLshort x
+ GLshort y
+ GLshort z
+
+
+
+
+ void glVertexAttrib3sNV
+ GLuint index
+ GLshort x
+ GLshort y
+ GLshort z
+
+
+
+
+ void glVertexAttrib3sv
+ GLuint index
+ const GLshort *v
+
+
+
+ void glVertexAttrib3svARB
+ GLuint index
+ const GLshort *v
+
+
+
+
+ void glVertexAttrib3svNV
+ GLuint index
+ const GLshort *v
+
+
+
+
+ void glVertexAttrib4Nbv
+ GLuint index
+ const GLbyte *v
+
+
+ void glVertexAttrib4NbvARB
+ GLuint index
+ const GLbyte *v
+
+
+
+ void glVertexAttrib4Niv
+ GLuint index
+ const GLint *v
+
+
+ void glVertexAttrib4NivARB
+ GLuint index
+ const GLint *v
+
+
+
+ void glVertexAttrib4Nsv
+ GLuint index
+ const GLshort *v
+
+
+ void glVertexAttrib4NsvARB
+ GLuint index
+ const GLshort *v
+
+
+
+ void glVertexAttrib4Nub
+ GLuint index
+ GLubyte x
+ GLubyte y
+ GLubyte z
+ GLubyte w
+
+
+ void glVertexAttrib4NubARB
+ GLuint index
+ GLubyte x
+ GLubyte y
+ GLubyte z
+ GLubyte w
+
+
+
+ void glVertexAttrib4Nubv
+ GLuint index
+ const GLubyte *v
+
+
+
+ void glVertexAttrib4NubvARB
+ GLuint index
+ const GLubyte *v
+
+
+
+
+ void glVertexAttrib4Nuiv
+ GLuint index
+ const GLuint *v
+
+
+ void glVertexAttrib4NuivARB
+ GLuint index
+ const GLuint *v
+
+
+
+ void glVertexAttrib4Nusv
+ GLuint index
+ const GLushort *v
+
+
+ void glVertexAttrib4NusvARB
+ GLuint index
+ const GLushort *v
+
+
+
+ void glVertexAttrib4bv
+ GLuint index
+ const GLbyte *v
+
+
+ void glVertexAttrib4bvARB
+ GLuint index
+ const GLbyte *v
+
+
+
+ void glVertexAttrib4d
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glVertexAttrib4dARB
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+
+ void glVertexAttrib4dNV
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+
+ void glVertexAttrib4dv
+ GLuint index
+ const GLdouble *v
+
+
+
+ void glVertexAttrib4dvARB
+ GLuint index
+ const GLdouble *v
+
+
+
+
+ void glVertexAttrib4dvNV
+ GLuint index
+ const GLdouble *v
+
+
+
+
+ void glVertexAttrib4f
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+ void glVertexAttrib4fARB
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+
+ void glVertexAttrib4fNV
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+
+ void glVertexAttrib4fv
+ GLuint index
+ const GLfloat *v
+
+
+
+ void glVertexAttrib4fvARB
+ GLuint index
+ const GLfloat *v
+
+
+
+
+ void glVertexAttrib4fvNV
+ GLuint index
+ const GLfloat *v
+
+
+
+
+ void glVertexAttrib4hNV
+ GLuint index
+ GLhalfNV x
+ GLhalfNV y
+ GLhalfNV z
+ GLhalfNV w
+
+
+
+ void glVertexAttrib4hvNV
+ GLuint index
+ const GLhalfNV *v
+
+
+
+ void glVertexAttrib4iv
+ GLuint index
+ const GLint *v
+
+
+ void glVertexAttrib4ivARB
+ GLuint index
+ const GLint *v
+
+
+
+ void glVertexAttrib4s
+ GLuint index
+ GLshort x
+ GLshort y
+ GLshort z
+ GLshort w
+
+
+
+ void glVertexAttrib4sARB
+ GLuint index
+ GLshort x
+ GLshort y
+ GLshort z
+ GLshort w
+
+
+
+
+ void glVertexAttrib4sNV
+ GLuint index
+ GLshort x
+ GLshort y
+ GLshort z
+ GLshort w
+
+
+
+
+ void glVertexAttrib4sv
+ GLuint index
+ const GLshort *v
+
+
+
+ void glVertexAttrib4svARB
+ GLuint index
+ const GLshort *v
+
+
+
+
+ void glVertexAttrib4svNV
+ GLuint index
+ const GLshort *v
+
+
+
+
+ void glVertexAttrib4ubNV
+ GLuint index
+ GLubyte x
+ GLubyte y
+ GLubyte z
+ GLubyte w
+
+
+
+
+ void glVertexAttrib4ubv
+ GLuint index
+ const GLubyte *v
+
+
+ void glVertexAttrib4ubvARB
+ GLuint index
+ const GLubyte *v
+
+
+
+ void glVertexAttrib4ubvNV
+ GLuint index
+ const GLubyte *v
+
+
+
+
+ void glVertexAttrib4uiv
+ GLuint index
+ const GLuint *v
+
+
+ void glVertexAttrib4uivARB
+ GLuint index
+ const GLuint *v
+
+
+
+ void glVertexAttrib4usv
+ GLuint index
+ const GLushort *v
+
+
+ void glVertexAttrib4usvARB
+ GLuint index
+ const GLushort *v
+
+
+
+ void glVertexAttribArrayObjectATI
+ GLuint index
+ GLint size
+ GLenum type
+ GLboolean normalized
+ GLsizei stride
+ GLuint buffer
+ GLuint offset
+
+
+ void glVertexAttribBinding
+ GLuint attribindex
+ GLuint bindingindex
+
+
+ void glVertexAttribDivisor
+ GLuint index
+ GLuint divisor
+
+
+ void glVertexAttribDivisorANGLE
+ GLuint index
+ GLuint divisor
+
+
+
+ void glVertexAttribDivisorARB
+ GLuint index
+ GLuint divisor
+
+
+
+ void glVertexAttribDivisorEXT
+ GLuint index
+ GLuint divisor
+
+
+
+ void glVertexAttribDivisorNV
+ GLuint index
+ GLuint divisor
+
+
+
+ void glVertexAttribFormat
+ GLuint attribindex
+ GLint size
+ GLenum type
+ GLboolean normalized
+ GLuint relativeoffset
+
+
+ void glVertexAttribFormatNV
+ GLuint index
+ GLint size
+ GLenum type
+ GLboolean normalized
+ GLsizei stride
+
+
+ void glVertexAttribI1i
+ GLuint index
+ GLint x
+
+
+
+ void glVertexAttribI1iEXT
+ GLuint index
+ GLint x
+
+
+
+
+ void glVertexAttribI1iv
+ GLuint index
+ const GLint *v
+
+
+ void glVertexAttribI1ivEXT
+ GLuint index
+ const GLint *v
+
+
+
+ void glVertexAttribI1ui
+ GLuint index
+ GLuint x
+
+
+
+ void glVertexAttribI1uiEXT
+ GLuint index
+ GLuint x
+
+
+
+
+ void glVertexAttribI1uiv
+ GLuint index
+ const GLuint *v
+
+
+ void glVertexAttribI1uivEXT
+ GLuint index
+ const GLuint *v
+
+
+
+ void glVertexAttribI2i
+ GLuint index
+ GLint x
+ GLint y
+
+
+
+ void glVertexAttribI2iEXT
+ GLuint index
+ GLint x
+ GLint y
+
+
+
+
+ void glVertexAttribI2iv
+ GLuint index
+ const GLint *v
+
+
+ void glVertexAttribI2ivEXT
+ GLuint index
+ const GLint *v
+
+
+
+ void glVertexAttribI2ui
+ GLuint index
+ GLuint x
+ GLuint y
+
+
+
+ void glVertexAttribI2uiEXT
+ GLuint index
+ GLuint x
+ GLuint y
+
+
+
+
+ void glVertexAttribI2uiv
+ GLuint index
+ const GLuint *v
+
+
+ void glVertexAttribI2uivEXT
+ GLuint index
+ const GLuint *v
+
+
+
+ void glVertexAttribI3i
+ GLuint index
+ GLint x
+ GLint y
+ GLint z
+
+
+
+ void glVertexAttribI3iEXT
+ GLuint index
+ GLint x
+ GLint y
+ GLint z
+
+
+
+
+ void glVertexAttribI3iv
+ GLuint index
+ const GLint *v
+
+
+ void glVertexAttribI3ivEXT
+ GLuint index
+ const GLint *v
+
+
+
+ void glVertexAttribI3ui
+ GLuint index
+ GLuint x
+ GLuint y
+ GLuint z
+
+
+
+ void glVertexAttribI3uiEXT
+ GLuint index
+ GLuint x
+ GLuint y
+ GLuint z
+
+
+
+
+ void glVertexAttribI3uiv
+ GLuint index
+ const GLuint *v
+
+
+ void glVertexAttribI3uivEXT
+ GLuint index
+ const GLuint *v
+
+
+
+ void glVertexAttribI4bv
+ GLuint index
+ const GLbyte *v
+
+
+ void glVertexAttribI4bvEXT
+ GLuint index
+ const GLbyte *v
+
+
+
+ void glVertexAttribI4i
+ GLuint index
+ GLint x
+ GLint y
+ GLint z
+ GLint w
+
+
+
+ void glVertexAttribI4iEXT
+ GLuint index
+ GLint x
+ GLint y
+ GLint z
+ GLint w
+
+
+
+
+ void glVertexAttribI4iv
+ GLuint index
+ const GLint *v
+
+
+ void glVertexAttribI4ivEXT
+ GLuint index
+ const GLint *v
+
+
+
+ void glVertexAttribI4sv
+ GLuint index
+ const GLshort *v
+
+
+ void glVertexAttribI4svEXT
+ GLuint index
+ const GLshort *v
+
+
+
+ void glVertexAttribI4ubv
+ GLuint index
+ const GLubyte *v
+
+
+ void glVertexAttribI4ubvEXT
+ GLuint index
+ const GLubyte *v
+
+
+
+ void glVertexAttribI4ui
+ GLuint index
+ GLuint x
+ GLuint y
+ GLuint z
+ GLuint w
+
+
+
+ void glVertexAttribI4uiEXT
+ GLuint index
+ GLuint x
+ GLuint y
+ GLuint z
+ GLuint w
+
+
+
+
+ void glVertexAttribI4uiv
+ GLuint index
+ const GLuint *v
+
+
+ void glVertexAttribI4uivEXT
+ GLuint index
+ const GLuint *v
+
+
+
+ void glVertexAttribI4usv
+ GLuint index
+ const GLushort *v
+
+
+ void glVertexAttribI4usvEXT
+ GLuint index
+ const GLushort *v
+
+
+
+ void glVertexAttribIFormat
+ GLuint attribindex
+ GLint size
+ GLenum type
+ GLuint relativeoffset
+
+
+ void glVertexAttribIFormatNV
+ GLuint index
+ GLint size
+ GLenum type
+ GLsizei stride
+
+
+ void glVertexAttribIPointer
+ GLuint index
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glVertexAttribIPointerEXT
+ GLuint index
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+
+ void glVertexAttribL1d
+ GLuint index
+ GLdouble x
+
+
+ void glVertexAttribL1dEXT
+ GLuint index
+ GLdouble x
+
+
+
+ void glVertexAttribL1dv
+ GLuint index
+ const GLdouble *v
+
+
+ void glVertexAttribL1dvEXT
+ GLuint index
+ const GLdouble *v
+
+
+
+ void glVertexAttribL1i64NV
+ GLuint index
+ GLint64EXT x
+
+
+ void glVertexAttribL1i64vNV
+ GLuint index
+ const GLint64EXT *v
+
+
+ void glVertexAttribL1ui64ARB
+ GLuint index
+ GLuint64EXT x
+
+
+ void glVertexAttribL1ui64NV
+ GLuint index
+ GLuint64EXT x
+
+
+ void glVertexAttribL1ui64vARB
+ GLuint index
+ const GLuint64EXT *v
+
+
+ void glVertexAttribL1ui64vNV
+ GLuint index
+ const GLuint64EXT *v
+
+
+ void glVertexAttribL2d
+ GLuint index
+ GLdouble x
+ GLdouble y
+
+
+ void glVertexAttribL2dEXT
+ GLuint index
+ GLdouble x
+ GLdouble y
+
+
+
+ void glVertexAttribL2dv
+ GLuint index
+ const GLdouble *v
+
+
+ void glVertexAttribL2dvEXT
+ GLuint index
+ const GLdouble *v
+
+
+
+ void glVertexAttribL2i64NV
+ GLuint index
+ GLint64EXT x
+ GLint64EXT y
+
+
+ void glVertexAttribL2i64vNV
+ GLuint index
+ const GLint64EXT *v
+
+
+ void glVertexAttribL2ui64NV
+ GLuint index
+ GLuint64EXT x
+ GLuint64EXT y
+
+
+ void glVertexAttribL2ui64vNV
+ GLuint index
+ const GLuint64EXT *v
+
+
+ void glVertexAttribL3d
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+ void glVertexAttribL3dEXT
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+ void glVertexAttribL3dv
+ GLuint index
+ const GLdouble *v
+
+
+ void glVertexAttribL3dvEXT
+ GLuint index
+ const GLdouble *v
+
+
+
+ void glVertexAttribL3i64NV
+ GLuint index
+ GLint64EXT x
+ GLint64EXT y
+ GLint64EXT z
+
+
+ void glVertexAttribL3i64vNV
+ GLuint index
+ const GLint64EXT *v
+
+
+ void glVertexAttribL3ui64NV
+ GLuint index
+ GLuint64EXT x
+ GLuint64EXT y
+ GLuint64EXT z
+
+
+ void glVertexAttribL3ui64vNV
+ GLuint index
+ const GLuint64EXT *v
+
+
+ void glVertexAttribL4d
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+ void glVertexAttribL4dEXT
+ GLuint index
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glVertexAttribL4dv
+ GLuint index
+ const GLdouble *v
+
+
+ void glVertexAttribL4dvEXT
+ GLuint index
+ const GLdouble *v
+
+
+
+ void glVertexAttribL4i64NV
+ GLuint index
+ GLint64EXT x
+ GLint64EXT y
+ GLint64EXT z
+ GLint64EXT w
+
+
+ void glVertexAttribL4i64vNV
+ GLuint index
+ const GLint64EXT *v
+
+
+ void glVertexAttribL4ui64NV
+ GLuint index
+ GLuint64EXT x
+ GLuint64EXT y
+ GLuint64EXT z
+ GLuint64EXT w
+
+
+ void glVertexAttribL4ui64vNV
+ GLuint index
+ const GLuint64EXT *v
+
+
+ void glVertexAttribLFormat
+ GLuint attribindex
+ GLint size
+ GLenum type
+ GLuint relativeoffset
+
+
+ void glVertexAttribLFormatNV
+ GLuint index
+ GLint size
+ GLenum type
+ GLsizei stride
+
+
+ void glVertexAttribLPointer
+ GLuint index
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glVertexAttribLPointerEXT
+ GLuint index
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+
+ void glVertexAttribP1ui
+ GLuint index
+ GLenum type
+ GLboolean normalized
+ GLuint value
+
+
+ void glVertexAttribP1uiv
+ GLuint index
+ GLenum type
+ GLboolean normalized
+ const GLuint *value
+
+
+ void glVertexAttribP2ui
+ GLuint index
+ GLenum type
+ GLboolean normalized
+ GLuint value
+
+
+ void glVertexAttribP2uiv
+ GLuint index
+ GLenum type
+ GLboolean normalized
+ const GLuint *value
+
+
+ void glVertexAttribP3ui
+ GLuint index
+ GLenum type
+ GLboolean normalized
+ GLuint value
+
+
+ void glVertexAttribP3uiv
+ GLuint index
+ GLenum type
+ GLboolean normalized
+ const GLuint *value
+
+
+ void glVertexAttribP4ui
+ GLuint index
+ GLenum type
+ GLboolean normalized
+ GLuint value
+
+
+ void glVertexAttribP4uiv
+ GLuint index
+ GLenum type
+ GLboolean normalized
+ const GLuint *value
+
+
+ void glVertexAttribParameteriAMD
+ GLuint index
+ GLenum pname
+ GLint param
+
+
+ void glVertexAttribPointer
+ GLuint index
+ GLint size
+ GLenum type
+ GLboolean normalized
+ GLsizei stride
+ const void *pointer
+
+
+ void glVertexAttribPointerARB
+ GLuint index
+ GLint size
+ GLenum type
+ GLboolean normalized
+ GLsizei stride
+ const void *pointer
+
+
+
+ void glVertexAttribPointerNV
+ GLuint index
+ GLint fsize
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glVertexAttribs1dvNV
+ GLuint index
+ GLsizei count
+ const GLdouble *v
+
+
+
+ void glVertexAttribs1fvNV
+ GLuint index
+ GLsizei count
+ const GLfloat *v
+
+
+
+ void glVertexAttribs1hvNV
+ GLuint index
+ GLsizei n
+ const GLhalfNV *v
+
+
+
+ void glVertexAttribs1svNV
+ GLuint index
+ GLsizei count
+ const GLshort *v
+
+
+
+ void glVertexAttribs2dvNV
+ GLuint index
+ GLsizei count
+ const GLdouble *v
+
+
+
+ void glVertexAttribs2fvNV
+ GLuint index
+ GLsizei count
+ const GLfloat *v
+
+
+
+ void glVertexAttribs2hvNV
+ GLuint index
+ GLsizei n
+ const GLhalfNV *v
+
+
+
+ void glVertexAttribs2svNV
+ GLuint index
+ GLsizei count
+ const GLshort *v
+
+
+
+ void glVertexAttribs3dvNV
+ GLuint index
+ GLsizei count
+ const GLdouble *v
+
+
+
+ void glVertexAttribs3fvNV
+ GLuint index
+ GLsizei count
+ const GLfloat *v
+
+
+
+ void glVertexAttribs3hvNV
+ GLuint index
+ GLsizei n
+ const GLhalfNV *v
+
+
+
+ void glVertexAttribs3svNV
+ GLuint index
+ GLsizei count
+ const GLshort *v
+
+
+
+ void glVertexAttribs4dvNV
+ GLuint index
+ GLsizei count
+ const GLdouble *v
+
+
+
+ void glVertexAttribs4fvNV
+ GLuint index
+ GLsizei count
+ const GLfloat *v
+
+
+
+ void glVertexAttribs4hvNV
+ GLuint index
+ GLsizei n
+ const GLhalfNV *v
+
+
+
+ void glVertexAttribs4svNV
+ GLuint index
+ GLsizei count
+ const GLshort *v
+
+
+
+ void glVertexAttribs4ubvNV
+ GLuint index
+ GLsizei count
+ const GLubyte *v
+
+
+
+ void glVertexBindingDivisor
+ GLuint bindingindex
+ GLuint divisor
+
+
+ void glVertexBlendARB
+ GLint count
+
+
+
+ void glVertexBlendEnvfATI
+ GLenum pname
+ GLfloat param
+
+
+ void glVertexBlendEnviATI
+ GLenum pname
+ GLint param
+
+
+ void glVertexFormatNV
+ GLint size
+ GLenum type
+ GLsizei stride
+
+
+ void glVertexP2ui
+ GLenum type
+ GLuint value
+
+
+ void glVertexP2uiv
+ GLenum type
+ const GLuint *value
+
+
+ void glVertexP3ui
+ GLenum type
+ GLuint value
+
+
+ void glVertexP3uiv
+ GLenum type
+ const GLuint *value
+
+
+ void glVertexP4ui
+ GLenum type
+ GLuint value
+
+
+ void glVertexP4uiv
+ GLenum type
+ const GLuint *value
+
+
+ void glVertexPointer
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glVertexPointerEXT
+ GLint size
+ GLenum type
+ GLsizei stride
+ GLsizei count
+ const void *pointer
+
+
+ void glVertexPointerListIBM
+ GLint size
+ GLenum type
+ GLint stride
+ const void **pointer
+ GLint ptrstride
+
+
+ void glVertexPointervINTEL
+ GLint size
+ GLenum type
+ const void **pointer
+
+
+ void glVertexStream1dATI
+ GLenum stream
+ GLdouble x
+
+
+ void glVertexStream1dvATI
+ GLenum stream
+ const GLdouble *coords
+
+
+ void glVertexStream1fATI
+ GLenum stream
+ GLfloat x
+
+
+ void glVertexStream1fvATI
+ GLenum stream
+ const GLfloat *coords
+
+
+ void glVertexStream1iATI
+ GLenum stream
+ GLint x
+
+
+ void glVertexStream1ivATI
+ GLenum stream
+ const GLint *coords
+
+
+ void glVertexStream1sATI
+ GLenum stream
+ GLshort x
+
+
+ void glVertexStream1svATI
+ GLenum stream
+ const GLshort *coords
+
+
+ void glVertexStream2dATI
+ GLenum stream
+ GLdouble x
+ GLdouble y
+
+
+ void glVertexStream2dvATI
+ GLenum stream
+ const GLdouble *coords
+
+
+ void glVertexStream2fATI
+ GLenum stream
+ GLfloat x
+ GLfloat y
+
+
+ void glVertexStream2fvATI
+ GLenum stream
+ const GLfloat *coords
+
+
+ void glVertexStream2iATI
+ GLenum stream
+ GLint x
+ GLint y
+
+
+ void glVertexStream2ivATI
+ GLenum stream
+ const GLint *coords
+
+
+ void glVertexStream2sATI
+ GLenum stream
+ GLshort x
+ GLshort y
+
+
+ void glVertexStream2svATI
+ GLenum stream
+ const GLshort *coords
+
+
+ void glVertexStream3dATI
+ GLenum stream
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+ void glVertexStream3dvATI
+ GLenum stream
+ const GLdouble *coords
+
+
+ void glVertexStream3fATI
+ GLenum stream
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+ void glVertexStream3fvATI
+ GLenum stream
+ const GLfloat *coords
+
+
+ void glVertexStream3iATI
+ GLenum stream
+ GLint x
+ GLint y
+ GLint z
+
+
+ void glVertexStream3ivATI
+ GLenum stream
+ const GLint *coords
+
+
+ void glVertexStream3sATI
+ GLenum stream
+ GLshort x
+ GLshort y
+ GLshort z
+
+
+ void glVertexStream3svATI
+ GLenum stream
+ const GLshort *coords
+
+
+ void glVertexStream4dATI
+ GLenum stream
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+ void glVertexStream4dvATI
+ GLenum stream
+ const GLdouble *coords
+
+
+ void glVertexStream4fATI
+ GLenum stream
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+ void glVertexStream4fvATI
+ GLenum stream
+ const GLfloat *coords
+
+
+ void glVertexStream4iATI
+ GLenum stream
+ GLint x
+ GLint y
+ GLint z
+ GLint w
+
+
+ void glVertexStream4ivATI
+ GLenum stream
+ const GLint *coords
+
+
+ void glVertexStream4sATI
+ GLenum stream
+ GLshort x
+ GLshort y
+ GLshort z
+ GLshort w
+
+
+ void glVertexStream4svATI
+ GLenum stream
+ const GLshort *coords
+
+
+ void glVertexWeightPointerEXT
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glVertexWeightfEXT
+ GLfloat weight
+
+
+
+ void glVertexWeightfvEXT
+ const GLfloat *weight
+
+
+
+ void glVertexWeighthNV
+ GLhalfNV weight
+
+
+
+ void glVertexWeighthvNV
+ const GLhalfNV *weight
+
+
+
+ GLenum glVideoCaptureNV
+ GLuint video_capture_slot
+ GLuint *sequence_num
+ GLuint64EXT *capture_time
+
+
+ void glVideoCaptureStreamParameterdvNV
+ GLuint video_capture_slot
+ GLuint stream
+ GLenum pname
+ const GLdouble *params
+
+
+ void glVideoCaptureStreamParameterfvNV
+ GLuint video_capture_slot
+ GLuint stream
+ GLenum pname
+ const GLfloat *params
+
+
+ void glVideoCaptureStreamParameterivNV
+ GLuint video_capture_slot
+ GLuint stream
+ GLenum pname
+ const GLint *params
+
+
+ void glViewport
+ GLint x
+ GLint y
+ GLsizei width
+ GLsizei height
+
+
+
+ void glViewportArrayv
+ GLuint first
+ GLsizei count
+ const GLfloat *v
+
+
+ void glViewportArrayvNV
+ GLuint first
+ GLsizei count
+ const GLfloat *v
+
+
+
+ void glViewportIndexedf
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat w
+ GLfloat h
+
+
+ void glViewportIndexedfNV
+ GLuint index
+ GLfloat x
+ GLfloat y
+ GLfloat w
+ GLfloat h
+
+
+
+ void glViewportIndexedfv
+ GLuint index
+ const GLfloat *v
+
+
+ void glViewportIndexedfvNV
+ GLuint index
+ const GLfloat *v
+
+
+
+ void glWaitSync
+ GLsync sync
+ GLbitfield flags
+ GLuint64 timeout
+
+
+ void glWaitSyncAPPLE
+ GLsync sync
+ GLbitfield flags
+ GLuint64 timeout
+
+
+
+ void glWeightPathsNV
+ GLuint resultPath
+ GLsizei numPaths
+ const GLuint *paths
+ const GLfloat *weights
+
+
+ void glWeightPointerARB
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glWeightPointerOES
+ GLint size
+ GLenum type
+ GLsizei stride
+ const void *pointer
+
+
+ void glWeightbvARB
+ GLint size
+ const GLbyte *weights
+
+
+
+ void glWeightdvARB
+ GLint size
+ const GLdouble *weights
+
+
+
+ void glWeightfvARB
+ GLint size
+ const GLfloat *weights
+
+
+
+ void glWeightivARB
+ GLint size
+ const GLint *weights
+
+
+
+ void glWeightsvARB
+ GLint size
+ const GLshort *weights
+
+
+
+ void glWeightubvARB
+ GLint size
+ const GLubyte *weights
+
+
+
+ void glWeightuivARB
+ GLint size
+ const GLuint *weights
+
+
+
+ void glWeightusvARB
+ GLint size
+ const GLushort *weights
+
+
+
+ void glWindowPos2d
+ GLdouble x
+ GLdouble y
+
+
+
+ void glWindowPos2dARB
+ GLdouble x
+ GLdouble y
+
+
+
+
+ void glWindowPos2dMESA
+ GLdouble x
+ GLdouble y
+
+
+
+
+ void glWindowPos2dv
+ const GLdouble *v
+
+
+
+ void glWindowPos2dvARB
+ const GLdouble *v
+
+
+
+
+ void glWindowPos2dvMESA
+ const GLdouble *v
+
+
+
+ void glWindowPos2f
+ GLfloat x
+ GLfloat y
+
+
+
+ void glWindowPos2fARB
+ GLfloat x
+ GLfloat y
+
+
+
+
+ void glWindowPos2fMESA
+ GLfloat x
+ GLfloat y
+
+
+
+
+ void glWindowPos2fv
+ const GLfloat *v
+
+
+
+ void glWindowPos2fvARB
+ const GLfloat *v
+
+
+
+
+ void glWindowPos2fvMESA
+ const GLfloat *v
+
+
+
+ void glWindowPos2i
+ GLint x
+ GLint y
+
+
+
+ void glWindowPos2iARB
+ GLint x
+ GLint y
+
+
+
+
+ void glWindowPos2iMESA
+ GLint x
+ GLint y
+
+
+
+
+ void glWindowPos2iv
+ const GLint *v
+
+
+
+ void glWindowPos2ivARB
+ const GLint *v
+
+
+
+
+ void glWindowPos2ivMESA
+ const GLint *v
+
+
+
+ void glWindowPos2s
+ GLshort x
+ GLshort y
+
+
+
+ void glWindowPos2sARB
+ GLshort x
+ GLshort y
+
+
+
+
+ void glWindowPos2sMESA
+ GLshort x
+ GLshort y
+
+
+
+
+ void glWindowPos2sv
+ const GLshort *v
+
+
+
+ void glWindowPos2svARB
+ const GLshort *v
+
+
+
+
+ void glWindowPos2svMESA
+ const GLshort *v
+
+
+
+ void glWindowPos3d
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+ void glWindowPos3dARB
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+
+ void glWindowPos3dMESA
+ GLdouble x
+ GLdouble y
+ GLdouble z
+
+
+
+
+ void glWindowPos3dv
+ const GLdouble *v
+
+
+
+ void glWindowPos3dvARB
+ const GLdouble *v
+
+
+
+
+ void glWindowPos3dvMESA
+ const GLdouble *v
+
+
+
+ void glWindowPos3f
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+ void glWindowPos3fARB
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+
+ void glWindowPos3fMESA
+ GLfloat x
+ GLfloat y
+ GLfloat z
+
+
+
+
+ void glWindowPos3fv
+ const GLfloat *v
+
+
+
+ void glWindowPos3fvARB
+ const GLfloat *v
+
+
+
+
+ void glWindowPos3fvMESA
+ const GLfloat *v
+
+
+
+ void glWindowPos3i
+ GLint x
+ GLint y
+ GLint z
+
+
+
+ void glWindowPos3iARB
+ GLint x
+ GLint y
+ GLint z
+
+
+
+
+ void glWindowPos3iMESA
+ GLint x
+ GLint y
+ GLint z
+
+
+
+
+ void glWindowPos3iv
+ const GLint *v
+
+
+
+ void glWindowPos3ivARB
+ const GLint *v
+
+
+
+
+ void glWindowPos3ivMESA
+ const GLint *v
+
+
+
+ void glWindowPos3s
+ GLshort x
+ GLshort y
+ GLshort z
+
+
+
+ void glWindowPos3sARB
+ GLshort x
+ GLshort y
+ GLshort z
+
+
+
+
+ void glWindowPos3sMESA
+ GLshort x
+ GLshort y
+ GLshort z
+
+
+
+
+ void glWindowPos3sv
+ const GLshort *v
+
+
+
+ void glWindowPos3svARB
+ const GLshort *v
+
+
+
+
+ void glWindowPos3svMESA
+ const GLshort *v
+
+
+
+ void glWindowPos4dMESA
+ GLdouble x
+ GLdouble y
+ GLdouble z
+ GLdouble w
+
+
+
+ void glWindowPos4dvMESA
+ const GLdouble *v
+
+
+ void glWindowPos4fMESA
+ GLfloat x
+ GLfloat y
+ GLfloat z
+ GLfloat w
+
+
+
+ void glWindowPos4fvMESA
+ const GLfloat *v
+
+
+ void glWindowPos4iMESA
+ GLint x
+ GLint y
+ GLint z
+ GLint w
+
+
+
+ void glWindowPos4ivMESA
+ const GLint *v
+
+
+ void glWindowPos4sMESA
+ GLshort x
+ GLshort y
+ GLshort z
+ GLshort w
+
+
+
+ void glWindowPos4svMESA
+ const GLshort *v
+
+
+ void glWriteMaskEXT
+ GLuint res
+ GLuint in
+ GLenum outX
+ GLenum outY
+ GLenum outZ
+ GLenum outW
+
+
+ void glCoverageModulationNV
+ GLenum components
+
+
+ void glCoverageModulationTableNV
+ GLsizei n
+ const GLfloat *v
+
+
+ void glFragmentCoverageColorNV
+ GLuint color
+
+
+ void glFramebufferSampleLocationsfvNV
+ GLenum target
+ GLuint start
+ GLsizei count
+ const GLfloat *v
+
+
+ void glGetCoverageModulationTableNV
+ GLsizei bufsize
+ GLfloat *v
+
+
+ void glNamedFramebufferSampleLocationsfvNV
+ GLuint framebuffer
+ GLuint start
+ GLsizei count
+ const GLfloat *v
+
+
+ void glRasterSamplesEXT
+ GLuint samples
+ GLboolean fixedsamplelocations
+
+
+ void glResolveDepthValuesNV
+
+
+ void glSubpixelPrecisionBiasNV
+ GLuint xbits
+ GLuint ybits
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mesa/Android.gen.mk b/src/mesa/Android.gen.mk
index 145f2594cda..a985f0a64b1 100644
--- a/src/mesa/Android.gen.mk
+++ b/src/mesa/Android.gen.mk
@@ -102,7 +102,7 @@ $(intermediates)/main/remap_helper.h: $(dispatch_deps)
$(call es-gen, $*)
$(intermediates)/main/enums.c: PRIVATE_SCRIPT :=$(MESA_PYTHON2) $(glapi)/gl_enums.py
-$(intermediates)/main/enums.c: PRIVATE_XML := -f $(glapi)/gl_and_es_API.xml
+$(intermediates)/main/enums.c: PRIVATE_XML := -f $(glapi)/../registry/gl.xml
$(intermediates)/main/enums.c: $(dispatch_deps)
$(call es-gen)
diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index 778b92d9892..13a05f53b22 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -465,6 +465,8 @@ STATETRACKER_FILES = \
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 \
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 0ffcd9c2c3f..5610e9ff80f 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -95,9 +95,12 @@ static struct blit_shader *
choose_blit_shader(GLenum target, struct blit_shader_table *table);
static void cleanup_temp_texture(struct temp_texture *tex);
-static void meta_glsl_clear_cleanup(struct clear_state *clear);
-static void meta_decompress_cleanup(struct decompress_state *decompress);
-static void meta_drawpix_cleanup(struct drawpix_state *drawpix);
+static void meta_glsl_clear_cleanup(struct gl_context *ctx,
+ struct clear_state *clear);
+static void meta_decompress_cleanup(struct gl_context *ctx,
+ struct decompress_state *decompress);
+static void meta_drawpix_cleanup(struct gl_context *ctx,
+ struct drawpix_state *drawpix);
void
_mesa_meta_bind_fbo_image(GLenum fboTarget, GLenum attachment,
@@ -310,13 +313,13 @@ _mesa_meta_setup_blit_shader(struct gl_context *ctx,
/**
* Configure vertex buffer and vertex array objects for tests
*
- * Regardless of whether a new VAO and new VBO are created, the objects
- * referenced by \c VAO and \c VBO will be bound into the GL state vector
- * when this function terminates.
+ * Regardless of whether a new VAO is created, the object referenced by \c VAO
+ * will be bound into the GL state vector when this function terminates. The
+ * object referenced by \c VBO will \b not be bound.
*
* \param VAO Storage for vertex array object handle. If 0, a new VAO
* will be created.
- * \param VBO Storage for vertex buffer object handle. If 0, a new VBO
+ * \param buf_obj Storage for vertex buffer object pointer. If \c NULL, a new VBO
* will be created. The new VBO will have storage for 4
* \c vertex structures.
* \param use_generic_attributes Should generic attributes 0 and 1 be used,
@@ -333,57 +336,84 @@ _mesa_meta_setup_blit_shader(struct gl_context *ctx,
* Use \c texcoord_size instead.
*/
void
-_mesa_meta_setup_vertex_objects(GLuint *VAO, GLuint *VBO,
+_mesa_meta_setup_vertex_objects(struct gl_context *ctx,
+ GLuint *VAO, struct gl_buffer_object **buf_obj,
bool use_generic_attributes,
unsigned vertex_size, unsigned texcoord_size,
unsigned color_size)
{
if (*VAO == 0) {
- assert(*VBO == 0);
+ struct gl_vertex_array_object *array_obj;
+ assert(*buf_obj == NULL);
/* create vertex array object */
_mesa_GenVertexArrays(1, VAO);
_mesa_BindVertexArray(*VAO);
+ array_obj = _mesa_lookup_vao(ctx, *VAO);
+ assert(array_obj != NULL);
+
/* create vertex array buffer */
- _mesa_GenBuffers(1, VBO);
- _mesa_BindBuffer(GL_ARRAY_BUFFER, *VBO);
- _mesa_BufferData(GL_ARRAY_BUFFER, 4 * sizeof(struct vertex), NULL,
- GL_DYNAMIC_DRAW);
+ *buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
+ if (*buf_obj == NULL)
+ return;
+
+ _mesa_buffer_data(ctx, *buf_obj, GL_NONE, 4 * sizeof(struct vertex), NULL,
+ GL_DYNAMIC_DRAW, __func__);
/* setup vertex arrays */
if (use_generic_attributes) {
assert(color_size == 0);
- _mesa_VertexAttribPointer(0, vertex_size, GL_FLOAT, GL_FALSE,
- sizeof(struct vertex), OFFSET(x));
- _mesa_EnableVertexAttribArray(0);
-
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_GENERIC(0),
+ vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, x), true);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_GENERIC(0),
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj,
+ VERT_ATTRIB_GENERIC(0));
if (texcoord_size > 0) {
- _mesa_VertexAttribPointer(1, texcoord_size, GL_FLOAT, GL_FALSE,
- sizeof(struct vertex), OFFSET(tex));
- _mesa_EnableVertexAttribArray(1);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_GENERIC(1),
+ texcoord_size, GL_FLOAT, GL_RGBA,
+ GL_FALSE, GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, tex), false);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_GENERIC(1),
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj,
+ VERT_ATTRIB_GENERIC(1));
}
} else {
- _mesa_VertexPointer(vertex_size, GL_FLOAT, sizeof(struct vertex),
- OFFSET(x));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_POS,
+ vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, x), true);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_POS,
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_POS);
if (texcoord_size > 0) {
- _mesa_TexCoordPointer(texcoord_size, GL_FLOAT,
- sizeof(struct vertex), OFFSET(tex));
- _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_TEX(0),
+ vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, tex), false);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_TEX(0),
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_TEX(0));
}
if (color_size > 0) {
- _mesa_ColorPointer(color_size, GL_FLOAT,
- sizeof(struct vertex), OFFSET(r));
- _mesa_EnableClientState(GL_COLOR_ARRAY);
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_COLOR0,
+ vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, r), false);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_COLOR0,
+ *buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_COLOR0);
}
}
} else {
_mesa_BindVertexArray(*VAO);
- _mesa_BindBuffer(GL_ARRAY_BUFFER, *VBO);
}
}
@@ -408,12 +438,12 @@ _mesa_meta_free(struct gl_context *ctx)
{
GET_CURRENT_CONTEXT(old_context);
_mesa_make_current(ctx, NULL, NULL);
- _mesa_meta_glsl_blit_cleanup(&ctx->Meta->Blit);
- meta_glsl_clear_cleanup(&ctx->Meta->Clear);
- _mesa_meta_glsl_generate_mipmap_cleanup(&ctx->Meta->Mipmap);
+ _mesa_meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit);
+ meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear);
+ _mesa_meta_glsl_generate_mipmap_cleanup(ctx, &ctx->Meta->Mipmap);
cleanup_temp_texture(&ctx->Meta->TempTex);
- meta_decompress_cleanup(&ctx->Meta->Decompress);
- meta_drawpix_cleanup(&ctx->Meta->DrawPix);
+ meta_decompress_cleanup(ctx, &ctx->Meta->Decompress);
+ meta_drawpix_cleanup(ctx, &ctx->Meta->DrawPix);
if (old_context)
_mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer);
else
@@ -630,7 +660,6 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
GLuint u, tgt;
save->ActiveUnit = ctx->Texture.CurrentUnit;
- save->ClientActiveUnit = ctx->Array.ActiveTexture;
save->EnvMode = ctx->Texture.Unit[0].EnvMode;
/* Disable all texture units */
@@ -663,7 +692,6 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
/* set defaults for unit[0] */
_mesa_ActiveTexture(GL_TEXTURE0);
- _mesa_ClientActiveTexture(GL_TEXTURE0);
_mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
@@ -715,8 +743,6 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
/* save vertex array object state */
_mesa_reference_vao(ctx, &save->VAO,
ctx->Array.VAO);
- _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
- ctx->Array.ArrayBufferObj);
/* set some default state? */
}
@@ -1092,7 +1118,6 @@ _mesa_meta_end(struct gl_context *ctx)
/* restore current unit state */
_mesa_ActiveTexture(GL_TEXTURE0 + save->ActiveUnit);
- _mesa_ClientActiveTexture(GL_TEXTURE0 + save->ClientActiveUnit);
}
if (state & MESA_META_TRANSFORM) {
@@ -1126,10 +1151,6 @@ _mesa_meta_end(struct gl_context *ctx)
}
if (state & MESA_META_VERTEX) {
- /* restore vertex buffer object */
- _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
- _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
-
/* restore vertex array object */
_mesa_BindVertexArray(save->VAO->Name);
_mesa_reference_vao(ctx, &save->VAO, NULL);
@@ -1490,10 +1511,12 @@ _mesa_meta_setup_drawpix_texture(struct gl_context *ctx,
}
void
-_mesa_meta_setup_ff_tnl_for_blit(GLuint *VAO, GLuint *VBO,
+_mesa_meta_setup_ff_tnl_for_blit(struct gl_context *ctx,
+ GLuint *VAO, struct gl_buffer_object **buf_obj,
unsigned texcoord_size)
{
- _mesa_meta_setup_vertex_objects(VAO, VBO, false, 2, texcoord_size, 0);
+ _mesa_meta_setup_vertex_objects(ctx, VAO, buf_obj, false, 2, texcoord_size,
+ 0);
/* setup projection matrix */
_mesa_MatrixMode(GL_PROJECTION);
@@ -1538,7 +1561,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
GLuint vs, fs;
bool has_integer_textures;
- _mesa_meta_setup_vertex_objects(&clear->VAO, &clear->VBO, true, 3, 0, 0);
+ _mesa_meta_setup_vertex_objects(ctx, &clear->VAO, &clear->buf_obj, true,
+ 3, 0, 0);
if (clear->ShaderProg != 0)
return;
@@ -1619,14 +1643,13 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
}
static void
-meta_glsl_clear_cleanup(struct clear_state *clear)
+meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear)
{
if (clear->VAO == 0)
return;
_mesa_DeleteVertexArrays(1, &clear->VAO);
clear->VAO = 0;
- _mesa_DeleteBuffers(1, &clear->VBO);
- clear->VBO = 0;
+ _mesa_reference_buffer_object(ctx, &clear->buf_obj, NULL);
_mesa_DeleteProgram(clear->ShaderProg);
clear->ShaderProg = 0;
@@ -1734,7 +1757,8 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl)
y1 = ((float) fb->_Ymax / fb->Height) * 2.0f - 1.0f;
z = -invert_z(ctx->Depth.Clear);
} else {
- _mesa_meta_setup_vertex_objects(&clear->VAO, &clear->VBO, false, 3, 0, 4);
+ _mesa_meta_setup_vertex_objects(ctx, &clear->VAO, &clear->buf_obj, false,
+ 3, 0, 4);
x0 = (float) fb->_Xmin;
y0 = (float) fb->_Ymin;
@@ -1817,8 +1841,8 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl)
}
/* upload new vertex data */
- _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
- GL_DYNAMIC_DRAW_ARB);
+ _mesa_buffer_data(ctx, clear->buf_obj, GL_NONE, sizeof(verts), verts,
+ GL_DYNAMIC_DRAW, __func__);
/* draw quad(s) */
if (fb->MaxNumLayers > 0) {
@@ -1864,7 +1888,7 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
MESA_META_VERTEX |
MESA_META_VIEWPORT));
- _mesa_meta_setup_vertex_objects(©pix->VAO, ©pix->VBO, false,
+ _mesa_meta_setup_vertex_objects(ctx, ©pix->VAO, ©pix->buf_obj, false,
3, 2, 0);
/* Silence valgrind warnings about reading uninitialized stack. */
@@ -1904,7 +1928,8 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
verts[3].tex[1] = tex->Ttop;
/* upload new vertex data */
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, copypix->buf_obj, 0, sizeof(verts), verts,
+ __func__);
}
_mesa_set_enable(ctx, tex->Target, GL_TRUE);
@@ -1918,14 +1943,13 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
}
static void
-meta_drawpix_cleanup(struct drawpix_state *drawpix)
+meta_drawpix_cleanup(struct gl_context *ctx, struct drawpix_state *drawpix)
{
if (drawpix->VAO != 0) {
_mesa_DeleteVertexArrays(1, &drawpix->VAO);
drawpix->VAO = 0;
- _mesa_DeleteBuffers(1, &drawpix->VBO);
- drawpix->VBO = 0;
+ _mesa_reference_buffer_object(ctx, &drawpix->buf_obj, NULL);
}
if (drawpix->StencilFP != 0) {
@@ -2185,7 +2209,7 @@ _mesa_meta_DrawPixels(struct gl_context *ctx,
newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat);
- _mesa_meta_setup_vertex_objects(&drawpix->VAO, &drawpix->VBO, false,
+ _mesa_meta_setup_vertex_objects(ctx, &drawpix->VAO, &drawpix->buf_obj, false,
3, 2, 0);
/* Silence valgrind warnings about reading uninitialized stack. */
@@ -2222,8 +2246,8 @@ _mesa_meta_DrawPixels(struct gl_context *ctx,
}
/* upload new vertex data */
- _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
- verts, GL_DYNAMIC_DRAW_ARB);
+ _mesa_buffer_data(ctx, drawpix->buf_obj, GL_NONE, sizeof(verts), verts,
+ GL_DYNAMIC_DRAW, __func__);
/* set given unpack params */
ctx->Unpack = *unpack;
@@ -2378,7 +2402,8 @@ _mesa_meta_Bitmap(struct gl_context *ctx,
MESA_META_VERTEX |
MESA_META_VIEWPORT));
- _mesa_meta_setup_vertex_objects(&bitmap->VAO, &bitmap->VBO, false, 3, 2, 4);
+ _mesa_meta_setup_vertex_objects(ctx, &bitmap->VAO, &bitmap->buf_obj, false,
+ 3, 2, 4);
newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat);
@@ -2423,7 +2448,8 @@ _mesa_meta_Bitmap(struct gl_context *ctx,
}
/* upload new vertex data */
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, bitmap->buf_obj, 0, sizeof(verts), verts,
+ __func__);
}
/* choose different foreground/background alpha values */
@@ -2952,14 +2978,15 @@ meta_decompress_fbo_cleanup(struct decompress_fbo_state *decompress_fbo)
}
static void
-meta_decompress_cleanup(struct decompress_state *decompress)
+meta_decompress_cleanup(struct gl_context *ctx,
+ struct decompress_state *decompress)
{
meta_decompress_fbo_cleanup(&decompress->byteFBO);
meta_decompress_fbo_cleanup(&decompress->floatFBO);
if (decompress->VAO != 0) {
_mesa_DeleteVertexArrays(1, &decompress->VAO);
- _mesa_DeleteBuffers(1, &decompress->VBO);
+ _mesa_reference_buffer_object(ctx, &decompress->buf_obj, NULL);
}
if (decompress->Sampler != 0)
@@ -3079,12 +3106,14 @@ decompress_texture_image(struct gl_context *ctx,
}
if (use_glsl_version) {
- _mesa_meta_setup_vertex_objects(&decompress->VAO, &decompress->VBO, true,
+ _mesa_meta_setup_vertex_objects(ctx, &decompress->VAO,
+ &decompress->buf_obj, true,
2, 4, 0);
_mesa_meta_setup_blit_shader(ctx, target, false, &decompress->shaders);
} else {
- _mesa_meta_setup_ff_tnl_for_blit(&decompress->VAO, &decompress->VBO, 3);
+ _mesa_meta_setup_ff_tnl_for_blit(ctx, &decompress->VAO,
+ &decompress->buf_obj, 3);
}
if (!decompress->Sampler) {
@@ -3128,7 +3157,8 @@ decompress_texture_image(struct gl_context *ctx,
_mesa_set_viewport(ctx, 0, 0, 0, width, height);
/* upload new vertex data */
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, decompress->buf_obj, 0, sizeof(verts), verts,
+ __func__);
/* setup texture state */
_mesa_BindTexture(target, texObj->Name);
@@ -3272,36 +3302,45 @@ _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
if (drawtex->VAO == 0) {
/* one-time setup */
- GLint active_texture;
+ struct gl_vertex_array_object *array_obj;
/* create vertex array object */
_mesa_GenVertexArrays(1, &drawtex->VAO);
_mesa_BindVertexArray(drawtex->VAO);
- /* create vertex array buffer */
- _mesa_GenBuffers(1, &drawtex->VBO);
- _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
- _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
- NULL, GL_DYNAMIC_DRAW_ARB);
+ array_obj = _mesa_lookup_vao(ctx, drawtex->VAO);
+ assert(array_obj != NULL);
- /* client active texture is not part of the array object */
- active_texture = ctx->Array.ActiveTexture;
+ /* create vertex array buffer */
+ drawtex->buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
+ if (drawtex->buf_obj == NULL)
+ return;
+
+ _mesa_buffer_data(ctx, drawtex->buf_obj, GL_NONE, sizeof(verts), verts,
+ GL_DYNAMIC_DRAW, __func__);
/* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
- for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- _mesa_ClientActiveTexture(GL_TEXTURE0 + i);
- _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i]));
- _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
- }
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_POS,
+ 3, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, x), true);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_POS,
+ drawtex->buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_POS);
- /* restore client active texture */
- _mesa_ClientActiveTexture(GL_TEXTURE0 + active_texture);
+
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_TEX(i),
+ 2, GL_FLOAT, GL_RGBA, GL_FALSE,
+ GL_FALSE, GL_FALSE,
+ offsetof(struct vertex, st[i]), true);
+ _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_TEX(i),
+ drawtex->buf_obj, 0, sizeof(struct vertex));
+ _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_TEX(i));
+ }
}
else {
_mesa_BindVertexArray(drawtex->VAO);
- _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
}
/* vertex positions, texcoords */
@@ -3366,7 +3405,8 @@ _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
verts[3].st[i][1] = t1;
}
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, drawtex->buf_obj, 0, sizeof(verts), verts,
+ __func__);
}
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h
index d4bf0b65524..21495eecd27 100644
--- a/src/mesa/drivers/common/meta.h
+++ b/src/mesa/drivers/common/meta.h
@@ -146,7 +146,6 @@ struct save_state
/** MESA_META_TEXTURE */
GLuint ActiveUnit;
- GLuint ClientActiveUnit;
/** for unit[0] only */
struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
/** mask of TEXTURE_2D_BIT, etc */
@@ -156,7 +155,6 @@ struct save_state
/** MESA_META_VERTEX */
struct gl_vertex_array_object *VAO;
- struct gl_buffer_object *ArrayBufferObj;
/** MESA_META_VIEWPORT */
GLfloat ViewportX, ViewportY, ViewportW, ViewportH;
@@ -300,7 +298,7 @@ enum blit_msaa_shader {
struct blit_state
{
GLuint VAO;
- GLuint VBO;
+ struct gl_buffer_object *buf_obj;
struct blit_shader_table shaders_with_depth;
struct blit_shader_table shaders_without_depth;
GLuint msaa_shaders[BLIT_MSAA_SHADER_COUNT];
@@ -322,7 +320,7 @@ struct fb_tex_blit_state
struct clear_state
{
GLuint VAO;
- GLuint VBO;
+ struct gl_buffer_object *buf_obj;
GLuint ShaderProg;
GLint ColorLocation;
GLint LayerLocation;
@@ -339,7 +337,7 @@ struct clear_state
struct copypix_state
{
GLuint VAO;
- GLuint VBO;
+ struct gl_buffer_object *buf_obj;
};
@@ -349,7 +347,7 @@ struct copypix_state
struct drawpix_state
{
GLuint VAO;
- GLuint VBO;
+ struct gl_buffer_object *buf_obj;
GLuint StencilFP; /**< Fragment program for drawing stencil images */
GLuint DepthFP; /**< Fragment program for drawing depth images */
@@ -362,7 +360,7 @@ struct drawpix_state
struct bitmap_state
{
GLuint VAO;
- GLuint VBO;
+ struct gl_buffer_object *buf_obj;
struct temp_texture Tex; /**< separate texture from other meta ops */
};
@@ -372,7 +370,7 @@ struct bitmap_state
struct gen_mipmap_state
{
GLuint VAO;
- GLuint VBO;
+ struct gl_buffer_object *buf_obj;
GLuint FBO;
GLuint Sampler;
@@ -396,7 +394,8 @@ struct decompress_state
{
GLuint VAO;
struct decompress_fbo_state byteFBO, floatFBO;
- GLuint VBO, Sampler;
+ struct gl_buffer_object *buf_obj;
+ GLuint Sampler;
struct blit_shader_table shaders;
};
@@ -407,7 +406,7 @@ struct decompress_state
struct drawtex_state
{
GLuint VAO;
- GLuint VBO;
+ struct gl_buffer_object *buf_obj;
};
#define MAX_META_OPS_DEPTH 8
@@ -620,13 +619,15 @@ struct temp_texture *
_mesa_meta_get_temp_depth_texture(struct gl_context *ctx);
void
-_mesa_meta_setup_vertex_objects(GLuint *VAO, GLuint *VBO,
+_mesa_meta_setup_vertex_objects(struct gl_context *ctx,
+ GLuint *VAO, struct gl_buffer_object **buf_obj,
bool use_generic_attributes,
unsigned vertex_size, unsigned texcoord_size,
unsigned color_size);
void
-_mesa_meta_setup_ff_tnl_for_blit(GLuint *VAO, GLuint *VBO,
+_mesa_meta_setup_ff_tnl_for_blit(struct gl_context *ctx,
+ GLuint *VAO, struct gl_buffer_object **buf_obj,
unsigned texcoord_size);
void
@@ -652,13 +653,14 @@ _mesa_meta_setup_blit_shader(struct gl_context *ctx,
struct blit_shader_table *table);
void
-_mesa_meta_glsl_blit_cleanup(struct blit_state *blit);
+_mesa_meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit);
void
_mesa_meta_blit_shader_table_cleanup(struct blit_shader_table *table);
void
-_mesa_meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap);
+_mesa_meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx,
+ struct gen_mipmap_state *mipmap);
void
_mesa_meta_bind_fbo_image(GLenum target, GLenum attachment,
diff --git a/src/mesa/drivers/common/meta_blit.c b/src/mesa/drivers/common/meta_blit.c
index 4a2444af0f9..4dbf0a76308 100644
--- a/src/mesa/drivers/common/meta_blit.c
+++ b/src/mesa/drivers/common/meta_blit.c
@@ -325,7 +325,7 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
}
break;
default:
- _mesa_problem(ctx, "Unkown texture target %s\n",
+ _mesa_problem(ctx, "Unknown texture target %s\n",
_mesa_enum_to_string(target));
shader_index = BLIT_2X_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE;
}
@@ -565,7 +565,7 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx,
texcoord_size = 2 + (src_rb->Depth > 1 ? 1 : 0);
- _mesa_meta_setup_vertex_objects(&blit->VAO, &blit->VBO, true,
+ _mesa_meta_setup_vertex_objects(ctx, &blit->VAO, &blit->buf_obj, true,
2, texcoord_size, 0);
if (is_target_multisample && is_filter_scaled_resolve && is_scaled_blit) {
@@ -691,8 +691,9 @@ blitframebuffer_texture(struct gl_context *ctx,
do_depth);
}
else {
- _mesa_meta_setup_ff_tnl_for_blit(&ctx->Meta->Blit.VAO,
- &ctx->Meta->Blit.VBO,
+ _mesa_meta_setup_ff_tnl_for_blit(ctx,
+ &ctx->Meta->Blit.VAO,
+ &ctx->Meta->Blit.buf_obj,
2);
}
@@ -789,7 +790,8 @@ blitframebuffer_texture(struct gl_context *ctx,
verts[3].tex[1] = t1;
verts[3].tex[2] = readAtt->Zoffset;
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, blit->buf_obj, 0, sizeof(verts), verts,
+ __func__);
}
/* setup viewport */
@@ -1004,13 +1006,12 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
}
void
-_mesa_meta_glsl_blit_cleanup(struct blit_state *blit)
+_mesa_meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit)
{
if (blit->VAO) {
_mesa_DeleteVertexArrays(1, &blit->VAO);
blit->VAO = 0;
- _mesa_DeleteBuffers(1, &blit->VBO);
- blit->VBO = 0;
+ _mesa_reference_buffer_object(ctx, &blit->buf_obj, NULL);
}
_mesa_meta_blit_shader_table_cleanup(&blit->shaders_with_depth);
diff --git a/src/mesa/drivers/common/meta_generate_mipmap.c b/src/mesa/drivers/common/meta_generate_mipmap.c
index bde170fcf6f..d38e6b88953 100644
--- a/src/mesa/drivers/common/meta_generate_mipmap.c
+++ b/src/mesa/drivers/common/meta_generate_mipmap.c
@@ -120,14 +120,14 @@ fallback_required(struct gl_context *ctx, GLenum target,
}
void
-_mesa_meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap)
+_mesa_meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx,
+ struct gen_mipmap_state *mipmap)
{
if (mipmap->VAO == 0)
return;
_mesa_DeleteVertexArrays(1, &mipmap->VAO);
mipmap->VAO = 0;
- _mesa_DeleteBuffers(1, &mipmap->VBO);
- mipmap->VBO = 0;
+ _mesa_reference_buffer_object(ctx, &mipmap->buf_obj, NULL);
_mesa_DeleteSamplers(1, &mipmap->Sampler);
mipmap->Sampler = 0;
@@ -196,11 +196,11 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
* GenerateMipmap function.
*/
if (use_glsl_version) {
- _mesa_meta_setup_vertex_objects(&mipmap->VAO, &mipmap->VBO, true,
+ _mesa_meta_setup_vertex_objects(ctx, &mipmap->VAO, &mipmap->buf_obj, true,
2, 4, 0);
_mesa_meta_setup_blit_shader(ctx, target, false, &mipmap->shaders);
} else {
- _mesa_meta_setup_ff_tnl_for_blit(&mipmap->VAO, &mipmap->VBO, 3);
+ _mesa_meta_setup_ff_tnl_for_blit(ctx, &mipmap->VAO, &mipmap->buf_obj, 3);
_mesa_set_enable(ctx, target, GL_TRUE);
}
@@ -335,8 +335,8 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
verts[3].tex);
/* upload vertex data */
- _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
- verts, GL_DYNAMIC_DRAW_ARB);
+ _mesa_buffer_data(ctx, mipmap->buf_obj, GL_NONE, sizeof(verts), verts,
+ GL_DYNAMIC_DRAW, __func__);
_mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstImage, layer);
diff --git a/src/mesa/drivers/common/meta_tex_subimage.c b/src/mesa/drivers/common/meta_tex_subimage.c
index 181dde9d045..4adaad7777b 100644
--- a/src/mesa/drivers/common/meta_tex_subimage.c
+++ b/src/mesa/drivers/common/meta_tex_subimage.c
@@ -69,7 +69,7 @@ create_texture_for_pbo(struct gl_context *ctx,
int dims, int width, int height, int depth,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
- GLuint *tmp_pbo, GLuint *tmp_tex)
+ struct gl_buffer_object **tmp_pbo, GLuint *tmp_tex)
{
uint32_t pbo_format;
GLenum internal_format;
@@ -101,7 +101,7 @@ create_texture_for_pbo(struct gl_context *ctx,
row_stride = _mesa_image_row_stride(packing, width, format, type);
if (_mesa_is_bufferobj(packing->BufferObj)) {
- *tmp_pbo = 0;
+ *tmp_pbo = NULL;
buffer_obj = packing->BufferObj;
first_pixel += (intptr_t)pixels;
} else {
@@ -109,32 +109,28 @@ create_texture_for_pbo(struct gl_context *ctx,
assert(create_pbo);
- _mesa_GenBuffers(1, tmp_pbo);
-
- /* We are not doing this inside meta_begin/end. However, we know the
- * client doesn't have the given target bound, so we can go ahead and
- * squash it. We'll set it back when we're done.
- */
- _mesa_BindBuffer(pbo_target, *tmp_pbo);
+ *tmp_pbo = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
+ if (*tmp_pbo == NULL)
+ return NULL;
/* In case of GL_PIXEL_PACK_BUFFER, pass null pointer for the pixel
- * data to avoid unnecessary data copying in _mesa_BufferData().
+ * data to avoid unnecessary data copying in _mesa_buffer_data.
*/
if (is_pixel_pack)
- _mesa_BufferData(pbo_target,
- last_pixel - first_pixel,
- NULL,
- GL_STREAM_READ);
+ _mesa_buffer_data(ctx, *tmp_pbo, GL_NONE,
+ last_pixel - first_pixel,
+ NULL,
+ GL_STREAM_READ,
+ __func__);
else
- _mesa_BufferData(pbo_target,
- last_pixel - first_pixel,
- (char *)pixels + first_pixel,
- GL_STREAM_DRAW);
+ _mesa_buffer_data(ctx, *tmp_pbo, GL_NONE,
+ last_pixel - first_pixel,
+ (char *)pixels + first_pixel,
+ GL_STREAM_DRAW,
+ __func__);
- buffer_obj = packing->BufferObj;
+ buffer_obj = *tmp_pbo;
first_pixel = 0;
-
- _mesa_BindBuffer(pbo_target, 0);
}
_mesa_GenTextures(1, tmp_tex);
@@ -165,7 +161,7 @@ create_texture_for_pbo(struct gl_context *ctx,
row_stride,
read_only)) {
_mesa_DeleteTextures(1, tmp_tex);
- _mesa_DeleteBuffers(1, tmp_pbo);
+ _mesa_reference_buffer_object(ctx, tmp_pbo, NULL);
return NULL;
}
@@ -181,7 +177,8 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
bool allocate_storage, bool create_pbo,
const struct gl_pixelstore_attrib *packing)
{
- GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 };
+ struct gl_buffer_object *pbo = NULL;
+ GLuint pbo_tex = 0, fbos[2] = { 0, 0 };
int image_height;
struct gl_texture_image *pbo_tex_image;
GLenum status;
@@ -284,7 +281,7 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
fail:
_mesa_DeleteFramebuffers(2, fbos);
_mesa_DeleteTextures(1, &pbo_tex);
- _mesa_DeleteBuffers(1, &pbo);
+ _mesa_reference_buffer_object(ctx, &pbo, NULL);
_mesa_meta_end(ctx);
@@ -299,7 +296,8 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing)
{
- GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 };
+ struct gl_buffer_object *pbo = NULL;
+ GLuint pbo_tex = 0, fbos[2] = { 0, 0 };
int image_height;
struct gl_texture_image *pbo_tex_image;
struct gl_renderbuffer *rb = NULL;
@@ -456,7 +454,7 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
fail:
_mesa_DeleteFramebuffers(2, fbos);
_mesa_DeleteTextures(1, &pbo_tex);
- _mesa_DeleteBuffers(1, &pbo);
+ _mesa_reference_buffer_object(ctx, &pbo, NULL);
_mesa_meta_end(ctx);
diff --git a/src/mesa/drivers/dri/i965/Makefile.am b/src/mesa/drivers/dri/i965/Makefile.am
index 9d003e48bd8..ad687bf59a4 100644
--- a/src/mesa/drivers/dri/i965/Makefile.am
+++ b/src/mesa/drivers/dri/i965/Makefile.am
@@ -51,7 +51,8 @@ libi965_compiler_la_SOURCES = $(i965_compiler_FILES)
TEST_LIBS = \
libi965_compiler.la \
../../../libmesa.la \
- -lpthread -ldl \
+ $(PTHREAD_LIBS) \
+ $(DLOPEN_LIBS) \
../common/libdri_test_stubs.la
TESTS = \
diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources
index 595903dd572..7a2f43b1fe8 100644
--- a/src/mesa/drivers/dri/i965/Makefile.sources
+++ b/src/mesa/drivers/dri/i965/Makefile.sources
@@ -163,7 +163,6 @@ i965_FILES = \
brw_wm_state.c \
brw_wm_surface_state.c \
gen6_blorp.cpp \
- gen6_blorp.h \
gen6_cc.c \
gen6_clip_state.c \
gen6_depth_state.c \
@@ -181,13 +180,15 @@ i965_FILES = \
gen6_vs_state.c \
gen6_wm_state.c \
gen7_blorp.cpp \
- gen7_blorp.h \
gen7_cs_state.c \
- gen7_disable.c \
+ gen7_ds_state.c \
gen7_gs_state.c \
+ gen7_hs_state.c \
+ gen7_l3_state.c \
gen7_misc_state.c \
gen7_sf_state.c \
gen7_sol_state.c \
+ gen7_te_state.c \
gen7_urb.c \
gen7_viewport_state.c \
gen7_vs_state.c \
@@ -197,7 +198,9 @@ i965_FILES = \
gen8_depth_state.c \
gen8_disable.c \
gen8_draw_upload.c \
+ gen8_ds_state.c \
gen8_gs_state.c \
+ gen8_hs_state.c \
gen8_misc_state.c \
gen8_multisample_state.c \
gen8_ps_state.c \
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.cpp b/src/mesa/drivers/dri/i965/brw_blorp.cpp
index df2969dbb76..1bc6d15969f 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp.cpp
@@ -26,10 +26,7 @@
#include "intel_fbo.h"
#include "brw_blorp.h"
-#include "brw_defines.h"
#include "brw_state.h"
-#include "gen6_blorp.h"
-#include "gen7_blorp.h"
#define FILE_DEBUG_FLAG DEBUG_BLORP
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h
index dd28d810f7f..a04a1dfa719 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.h
+++ b/src/mesa/drivers/dri/i965/brw_blorp.h
@@ -25,7 +25,6 @@
#include
-#include "brw_context.h"
#include "brw_reg.h"
#include "intel_mipmap_tree.h"
@@ -238,6 +237,13 @@ public:
void
brw_blorp_exec(struct brw_context *brw, const brw_blorp_params *params);
+void
+gen6_blorp_exec(struct brw_context *brw,
+ const brw_blorp_params *params);
+
+void
+gen7_blorp_exec(struct brw_context *brw,
+ const brw_blorp_params *params);
/**
* Parameters for a HiZ or depth resolve operation.
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
index ba11d3dd07f..c7cb3944870 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
@@ -23,7 +23,6 @@
#include "main/teximage.h"
#include "main/fbobject.h"
-#include "main/renderbuffer.h"
#include "intel_fbo.h"
@@ -1344,7 +1343,7 @@ brw_blorp_blit_program::single_to_blend()
* count_trailing_one_bits(7) == 3
* count_trailing_one_bits(11) == 2
*/
-inline int count_trailing_one_bits(unsigned value)
+static inline int count_trailing_one_bits(unsigned value)
{
#ifdef HAVE___BUILTIN_CTZ
return __builtin_ctz(~value);
@@ -1769,7 +1768,7 @@ brw_blorp_blit_program::render_target_write()
/* Now write to the render target and terminate the thread */
emit_render_target_write(
mrf_rt_write,
- base_mrf,
+ base_mrf,
mrf_offset /* msg_length. TODO: Should be smaller for non-RGBA formats. */,
use_header);
}
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit_eu.h b/src/mesa/drivers/dri/i965/brw_blorp_blit_eu.h
index 8e44eb482c4..14a8e50611b 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit_eu.h
@@ -24,7 +24,6 @@
#ifndef BRW_BLORP_BLIT_EU_H
#define BRW_BLORP_BLIT_EU_H
-#include "brw_context.h"
#include "brw_fs.h"
class brw_blorp_eu_emitter
diff --git a/src/mesa/drivers/dri/i965/brw_cfg.h b/src/mesa/drivers/dri/i965/brw_cfg.h
index 69e39e8964d..405020b77e5 100644
--- a/src/mesa/drivers/dri/i965/brw_cfg.h
+++ b/src/mesa/drivers/dri/i965/brw_cfg.h
@@ -314,6 +314,9 @@ struct cfg_t {
#define foreach_block_safe(__block, __cfg) \
foreach_list_typed_safe (bblock_t, __block, link, &(__cfg)->block_list)
+#define foreach_block_reverse_safe(__block, __cfg) \
+ foreach_list_typed_reverse_safe (bblock_t, __block, link, &(__cfg)->block_list)
+
#define foreach_inst_in_block(__type, __inst, __block) \
foreach_in_list(__type, __inst, &(__block)->instructions)
diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c
index b0119558c3a..841ba5d5a3f 100644
--- a/src/mesa/drivers/dri/i965/brw_clear.c
+++ b/src/mesa/drivers/dri/i965/brw_clear.c
@@ -24,7 +24,6 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "main/glheader.h"
#include "main/mtypes.h"
#include "main/condrender.h"
#include "swrast/swrast.h"
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 2d5abc70cb9..9db35ce3467 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -29,7 +29,6 @@
* Keith Whitwell
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c
index 8e34f7c987b..d59e8849314 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_line.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_line.c
@@ -29,7 +29,6 @@
* Keith Whitwell
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
#include "program/program.h"
diff --git a/src/mesa/drivers/dri/i965/brw_clip_point.c b/src/mesa/drivers/dri/i965/brw_clip_point.c
index 81487d342b5..5cf2f5eeee6 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_point.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_point.c
@@ -29,7 +29,6 @@
* Keith Whitwell
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
#include "program/program.h"
diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c
index cca7eb1e717..0bac76096f8 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_tri.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c
@@ -29,7 +29,6 @@
* Keith Whitwell
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
#include "program/program.h"
@@ -307,7 +306,7 @@ void brw_clip_tri( struct brw_clip_compile *c )
brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
else
brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
-
+
brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
@@ -352,7 +351,7 @@ void brw_clip_tri( struct brw_clip_compile *c )
brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
}
brw_ENDIF(p);
-
+
}
brw_ELSE(p);
{
@@ -392,11 +391,11 @@ void brw_clip_tri( struct brw_clip_compile *c )
brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
- }
+ }
brw_ENDIF(p);
}
brw_ENDIF(p);
-
+
/* vtxPrev = vtx;
* inlist_ptr++;
*/
diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
index 9a4d2a9d6f9..3c18858abf1 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
@@ -29,7 +29,6 @@
* Keith Whitwell
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
#include "program/program.h"
@@ -302,9 +301,9 @@ static void emit_lines(struct brw_clip_compile *c,
{
brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
-
+
apply_one_offset(c, v0);
-
+
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_G);
}
@@ -534,6 +533,3 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
emit_unfilled_primitives(c);
brw_clip_kill_thread(c);
}
-
-
-
diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c
index 73ba85e2a61..7ef3305a25f 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_util.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_util.c
@@ -30,7 +30,6 @@
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
#include "program/program.h"
@@ -119,7 +118,7 @@ static void brw_clip_project_vertex( struct brw_clip_compile *c,
brw_MOV(p, tmp, deref_4f(vert_addr, hpos_offset));
brw_clip_project_position(c, tmp);
brw_MOV(p, deref_4f(vert_addr, ndc_offset), tmp);
-
+
release_tmp(c, tmp);
}
diff --git a/src/mesa/drivers/dri/i965/brw_compiler.h b/src/mesa/drivers/dri/i965/brw_compiler.h
index 7af8036b4ee..0e25ae78a69 100644
--- a/src/mesa/drivers/dri/i965/brw_compiler.h
+++ b/src/mesa/drivers/dri/i965/brw_compiler.h
@@ -303,6 +303,7 @@ struct brw_stage_prog_data {
unsigned curb_read_length;
unsigned total_scratch;
+ unsigned total_shared;
/**
* Register where the thread expects to find input data from the URB
@@ -551,6 +552,24 @@ struct brw_vs_prog_data {
bool uses_instanceid;
};
+struct brw_tcs_prog_data
+{
+ struct brw_vue_prog_data base;
+
+ /** Number vertices in output patch */
+ int instances;
+};
+
+
+struct brw_tes_prog_data
+{
+ struct brw_vue_prog_data base;
+
+ enum brw_tess_partitioning partitioning;
+ enum brw_tess_output_topology output_topology;
+ enum brw_tess_domain domain;
+};
+
struct brw_gs_prog_data
{
struct brw_vue_prog_data base;
diff --git a/src/mesa/drivers/dri/i965/brw_compute.c b/src/mesa/drivers/dri/i965/brw_compute.c
index fe991a46153..d9f181a1cbf 100644
--- a/src/mesa/drivers/dri/i965/brw_compute.c
+++ b/src/mesa/drivers/dri/i965/brw_compute.c
@@ -24,7 +24,6 @@
#include
#include "main/condrender.h"
-#include "main/glheader.h"
#include "main/mtypes.h"
#include "main/state.h"
#include "brw_context.h"
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 2ea0a9eca92..1511dd59f42 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -69,6 +69,7 @@
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "util/ralloc.h"
+#include "util/debug.h"
/***************************************
* Mesa's Driver Functions
@@ -196,6 +197,24 @@ intel_update_state(struct gl_context * ctx, GLuint new_state)
brw_render_cache_set_check_flush(brw, tex_obj->mt->bo);
}
+ /* Resolve color for each active shader image. */
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ const struct gl_shader *shader = ctx->_Shader->CurrentProgram[i] ?
+ ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i] : NULL;
+
+ if (unlikely(shader && shader->NumImages)) {
+ for (unsigned j = 0; j < shader->NumImages; j++) {
+ struct gl_image_unit *u = &ctx->ImageUnits[shader->ImageUnits[j]];
+ tex_obj = intel_texture_object(u->TexObj);
+
+ if (tex_obj && tex_obj->mt) {
+ intel_miptree_resolve_color(brw, tex_obj->mt);
+ brw_render_cache_set_check_flush(brw, tex_obj->mt->bo);
+ }
+ }
+ }
+ }
+
_mesa_lock_context_textures(ctx);
}
@@ -326,11 +345,13 @@ brw_initialize_context_constants(struct brw_context *brw)
const bool stage_exists[MESA_SHADER_STAGES] = {
[MESA_SHADER_VERTEX] = true,
- [MESA_SHADER_TESS_CTRL] = false,
- [MESA_SHADER_TESS_EVAL] = false,
+ [MESA_SHADER_TESS_CTRL] = brw->gen >= 8,
+ [MESA_SHADER_TESS_EVAL] = brw->gen >= 8,
[MESA_SHADER_GEOMETRY] = brw->gen >= 6,
[MESA_SHADER_FRAGMENT] = true,
- [MESA_SHADER_COMPUTE] = _mesa_extension_override_enables.ARB_compute_shader,
+ [MESA_SHADER_COMPUTE] =
+ (ctx->Const.MaxComputeWorkGroupSize[0] >= 1024) ||
+ _mesa_extension_override_enables.ARB_compute_shader,
};
unsigned num_stages = 0;
@@ -483,6 +504,8 @@ brw_initialize_context_constants(struct brw_context *brw)
if (brw->gen >= 5 || brw->is_g4x)
ctx->Const.MaxClipPlanes = 8;
+ ctx->Const.LowerTessLevel = true;
+
ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeInstructions = 16 * 1024;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxAluInstructions = 0;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxTexInstructions = 0;
@@ -582,6 +605,10 @@ brw_initialize_context_constants(struct brw_context *brw)
ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents = 64;
ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxInputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxOutputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxInputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxOutputComponents = 128;
}
/* We want the GLSL compiler to emit code that uses condition codes */
@@ -613,7 +640,7 @@ brw_initialize_context_constants(struct brw_context *brw)
}
static void
-brw_adjust_cs_context_constants(struct brw_context *brw)
+brw_initialize_cs_context_constants(struct brw_context *brw, unsigned max_threads)
{
struct gl_context *ctx = &brw->ctx;
@@ -627,7 +654,7 @@ brw_adjust_cs_context_constants(struct brw_context *brw)
*/
const int simd_size = ctx->API == API_OPENGL_CORE ? 16 : 8;
- const uint32_t max_invocations = simd_size * brw->max_cs_threads;
+ const uint32_t max_invocations = simd_size * max_threads;
ctx->Const.MaxComputeWorkGroupSize[0] = max_invocations;
ctx->Const.MaxComputeWorkGroupSize[1] = max_invocations;
ctx->Const.MaxComputeWorkGroupSize[2] = max_invocations;
@@ -757,6 +784,8 @@ brwCreateContext(gl_api api,
brw->has_swizzling = screen->hw_has_swizzling;
brw->vs.base.stage = MESA_SHADER_VERTEX;
+ brw->tcs.base.stage = MESA_SHADER_TESS_CTRL;
+ brw->tes.base.stage = MESA_SHADER_TESS_EVAL;
brw->gs.base.stage = MESA_SHADER_GEOMETRY;
brw->wm.base.stage = MESA_SHADER_FRAGMENT;
if (brw->gen >= 8) {
@@ -817,6 +846,7 @@ brwCreateContext(gl_api api,
if (INTEL_DEBUG & DEBUG_PERF)
brw->perf_debug = true;
+ brw_initialize_cs_context_constants(brw, devinfo->max_cs_threads);
brw_initialize_context_constants(brw);
ctx->Const.ResetStrategy = notify_reset
@@ -871,8 +901,6 @@ brwCreateContext(gl_api api,
brw->urb.max_ds_entries = devinfo->urb.max_ds_entries;
brw->urb.max_gs_entries = devinfo->urb.max_gs_entries;
- brw_adjust_cs_context_constants(brw);
-
/* Estimate the size of the mappable aperture into the GTT. There's an
* ioctl to get the whole GTT size, but not one to get the mappable subset.
* It turns out it's basically always 256MB, though some ancient hardware
@@ -899,8 +927,8 @@ brwCreateContext(gl_api api,
brw->predicate.state = BRW_PREDICATE_STATE_RENDER;
brw->use_resource_streamer = screen->has_resource_streamer &&
- (brw_env_var_as_boolean("INTEL_USE_HW_BT", false) ||
- brw_env_var_as_boolean("INTEL_USE_GATHER", false));
+ (env_var_as_boolean("INTEL_USE_HW_BT", false) ||
+ env_var_as_boolean("INTEL_USE_GATHER", false));
ctx->VertexProgram._MaintainTnlProgram = true;
ctx->FragmentProgram._MaintainTexEnvProgram = true;
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index fe45edb89ff..a8455413e36 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -34,15 +34,11 @@
#define BRWCONTEXT_INC
#include
-#include
-#include "main/imports.h"
#include "main/macros.h"
-#include "main/mm.h"
#include "main/mtypes.h"
#include "brw_structs.h"
#include "brw_compiler.h"
#include "intel_aub.h"
-#include "program/prog_parameter.h"
#ifdef __cplusplus
extern "C" {
@@ -50,9 +46,7 @@ extern "C" {
#define virtual virt
#endif
-#include
#include
-#include
#ifdef __cplusplus
#undef virtual
}
@@ -116,6 +110,12 @@ extern "C" {
* enabled, it first passes them to a VS thread which is a good place
* for the driver to implement any active vertex shader.
*
+ * HS - Hull Shader (Tessellation Control Shader)
+ *
+ * TE - Tessellation Engine (Tessellation Primitive Generation)
+ *
+ * DS - Domain Shader (Tessellation Evaluation Shader)
+ *
* GS - Geometry Shader. This corresponds to a new DX10 concept. If
* enabled, incoming strips etc are passed to GS threads in individual
* line/triangle/point units. The GS thread may perform arbitary
@@ -166,6 +166,8 @@ enum brw_cache_id {
BRW_CACHE_VS_PROG,
BRW_CACHE_FF_GS_PROG,
BRW_CACHE_GS_PROG,
+ BRW_CACHE_TCS_PROG,
+ BRW_CACHE_TES_PROG,
BRW_CACHE_CLIP_PROG,
BRW_CACHE_CS_PROG,
@@ -177,9 +179,12 @@ enum brw_state_id {
BRW_STATE_URB_FENCE = BRW_MAX_CACHE,
BRW_STATE_FRAGMENT_PROGRAM,
BRW_STATE_GEOMETRY_PROGRAM,
+ BRW_STATE_TESS_CTRL_PROGRAM,
+ BRW_STATE_TESS_EVAL_PROGRAM,
BRW_STATE_VERTEX_PROGRAM,
BRW_STATE_CURBE_OFFSETS,
BRW_STATE_REDUCED_PRIMITIVE,
+ BRW_STATE_PATCH_PRIMITIVE,
BRW_STATE_PRIMITIVE,
BRW_STATE_CONTEXT,
BRW_STATE_PSP,
@@ -213,6 +218,7 @@ enum brw_state_id {
BRW_STATE_VS_ATTRIB_WORKAROUNDS,
BRW_STATE_COMPUTE_PROGRAM,
BRW_STATE_CS_WORK_GROUPS,
+ BRW_STATE_URB_SIZE,
BRW_NUM_STATE_BITS
};
@@ -247,14 +253,19 @@ enum brw_state_id {
#define BRW_NEW_VS_PROG_DATA (1ull << BRW_CACHE_VS_PROG)
#define BRW_NEW_FF_GS_PROG_DATA (1ull << BRW_CACHE_FF_GS_PROG)
#define BRW_NEW_GS_PROG_DATA (1ull << BRW_CACHE_GS_PROG)
+#define BRW_NEW_TCS_PROG_DATA (1ull << BRW_CACHE_TCS_PROG)
+#define BRW_NEW_TES_PROG_DATA (1ull << BRW_CACHE_TES_PROG)
#define BRW_NEW_CLIP_PROG_DATA (1ull << BRW_CACHE_CLIP_PROG)
#define BRW_NEW_CS_PROG_DATA (1ull << BRW_CACHE_CS_PROG)
#define BRW_NEW_URB_FENCE (1ull << BRW_STATE_URB_FENCE)
#define BRW_NEW_FRAGMENT_PROGRAM (1ull << BRW_STATE_FRAGMENT_PROGRAM)
#define BRW_NEW_GEOMETRY_PROGRAM (1ull << BRW_STATE_GEOMETRY_PROGRAM)
+#define BRW_NEW_TESS_EVAL_PROGRAM (1ull << BRW_STATE_TESS_EVAL_PROGRAM)
+#define BRW_NEW_TESS_CTRL_PROGRAM (1ull << BRW_STATE_TESS_CTRL_PROGRAM)
#define BRW_NEW_VERTEX_PROGRAM (1ull << BRW_STATE_VERTEX_PROGRAM)
#define BRW_NEW_CURBE_OFFSETS (1ull << BRW_STATE_CURBE_OFFSETS)
#define BRW_NEW_REDUCED_PRIMITIVE (1ull << BRW_STATE_REDUCED_PRIMITIVE)
+#define BRW_NEW_PATCH_PRIMITIVE (1ull << BRW_STATE_PATCH_PRIMITIVE)
#define BRW_NEW_PRIMITIVE (1ull << BRW_STATE_PRIMITIVE)
#define BRW_NEW_CONTEXT (1ull << BRW_STATE_CONTEXT)
#define BRW_NEW_PSP (1ull << BRW_STATE_PSP)
@@ -293,6 +304,7 @@ enum brw_state_id {
#define BRW_NEW_VS_ATTRIB_WORKAROUNDS (1ull << BRW_STATE_VS_ATTRIB_WORKAROUNDS)
#define BRW_NEW_COMPUTE_PROGRAM (1ull << BRW_STATE_COMPUTE_PROGRAM)
#define BRW_NEW_CS_WORK_GROUPS (1ull << BRW_STATE_CS_WORK_GROUPS)
+#define BRW_NEW_URB_SIZE (1ull << BRW_STATE_URB_SIZE)
struct brw_state_flags {
/** State update flags signalled by mesa internals */
@@ -310,6 +322,20 @@ struct brw_vertex_program {
};
+/** Subclass of Mesa tessellation control program */
+struct brw_tess_ctrl_program {
+ struct gl_tess_ctrl_program program;
+ unsigned id; /**< serial no. to identify tess ctrl progs, never re-used */
+};
+
+
+/** Subclass of Mesa tessellation evaluation program */
+struct brw_tess_eval_program {
+ struct gl_tess_eval_program program;
+ unsigned id; /**< serial no. to identify tess eval progs, never re-used */
+};
+
+
/** Subclass of Mesa geometry program */
struct brw_geometry_program {
struct gl_geometry_program program;
@@ -420,7 +446,7 @@ struct brw_ff_gs_prog_data {
#define BRW_MAX_DRAW_BUFFERS 8
/** Max number of UBOs in a shader */
-#define BRW_MAX_UBO 12
+#define BRW_MAX_UBO 14
/** Max number of SSBOs in a shader */
#define BRW_MAX_SSBO 12
@@ -676,6 +702,8 @@ enum brw_predicate_state {
struct shader_times;
+struct brw_l3_config;
+
/**
* brw_context is derived from gl_context.
*/
@@ -841,6 +869,11 @@ struct brw_context
bool use_rep_send;
bool use_resource_streamer;
+ /**
+ * Whether LRI can be used to write register values from the batch buffer.
+ */
+ bool can_do_pipelined_register_writes;
+
/**
* Some versions of Gen hardware don't do centroid interpolation correctly
* on unlit pixels, causing incorrect values for derivatives near triangle
@@ -944,6 +977,8 @@ struct brw_context
*/
const struct gl_vertex_program *vertex_program;
const struct gl_geometry_program *geometry_program;
+ const struct gl_tess_ctrl_program *tess_ctrl_program;
+ const struct gl_tess_eval_program *tess_eval_program;
const struct gl_fragment_program *fragment_program;
const struct gl_compute_program *compute_program;
@@ -991,7 +1026,13 @@ struct brw_context
GLuint clip_start;
GLuint sf_start;
GLuint cs_start;
- GLuint size; /* Hardware URB size, in KB. */
+ /**
+ * URB size in the current configuration. The units this is expressed
+ * in are somewhat inconsistent, see brw_device_info::urb::size.
+ *
+ * FINISHME: Represent the URB size consistently in KB on all platforms.
+ */
+ GLuint size;
/* True if the most recently sent _3DSTATE_URB message allocated
* URB space for the GS.
@@ -1033,6 +1074,28 @@ struct brw_context
struct brw_vs_prog_data *prog_data;
} vs;
+ struct {
+ struct brw_stage_state base;
+ struct brw_tcs_prog_data *prog_data;
+
+ /**
+ * True if the 3DSTATE_HS command most recently emitted to the 3D
+ * pipeline enabled the HS; false otherwise.
+ */
+ bool enabled;
+ } tcs;
+
+ struct {
+ struct brw_stage_state base;
+ struct brw_tes_prog_data *prog_data;
+
+ /**
+ * True if the 3DSTATE_DS command most recently emitted to the 3D
+ * pipeline enabled the DS; false otherwise.
+ */
+ bool enabled;
+ } tes;
+
struct {
struct brw_stage_state base;
struct brw_gs_prog_data *prog_data;
@@ -1169,8 +1232,8 @@ struct brw_context
} perfmon;
int num_atoms[BRW_NUM_PIPELINES];
- const struct brw_tracked_state render_atoms[60];
- const struct brw_tracked_state compute_atoms[9];
+ const struct brw_tracked_state render_atoms[62];
+ const struct brw_tracked_state compute_atoms[10];
/* If (INTEL_DEBUG & DEBUG_BATCH) */
struct {
@@ -1212,6 +1275,10 @@ struct brw_context
uint32_t num_instances;
int basevertex;
+ struct {
+ const struct brw_l3_config *config;
+ } l3;
+
struct {
drm_intel_bo *bo;
const char **names;
@@ -1362,6 +1429,16 @@ void brw_validate_textures( struct brw_context *brw );
/*======================================================================
* brw_program.c
*/
+static inline bool
+key_debug(struct brw_context *brw, const char *name, int a, int b)
+{
+ if (a != b) {
+ perf_debug(" %s %d->%d\n", name, a, b);
+ return true;
+ }
+ return false;
+}
+
void brwInitFragProgFuncs( struct dd_function_table *functions );
/* Per-thread scratch space is a power-of-two multiple of 1KB. */
@@ -1434,14 +1511,12 @@ void brw_create_constant_surface(struct brw_context *brw,
drm_intel_bo *bo,
uint32_t offset,
uint32_t size,
- uint32_t *out_offset,
- bool dword_pitch);
+ uint32_t *out_offset);
void brw_create_buffer_surface(struct brw_context *brw,
drm_intel_bo *bo,
uint32_t offset,
uint32_t size,
- uint32_t *out_offset,
- bool dword_pitch);
+ uint32_t *out_offset);
void brw_update_buffer_texture_surface(struct gl_context *ctx,
unsigned unit,
uint32_t *surf_offset);
@@ -1453,8 +1528,7 @@ brw_update_sol_surface(struct brw_context *brw,
void brw_upload_ubo_surfaces(struct brw_context *brw,
struct gl_shader *shader,
struct brw_stage_state *stage_state,
- struct brw_stage_prog_data *prog_data,
- bool dword_pitch);
+ struct brw_stage_prog_data *prog_data);
void brw_upload_abo_surfaces(struct brw_context *brw,
struct gl_shader *shader,
struct brw_stage_state *stage_state,
diff --git a/src/mesa/drivers/dri/i965/brw_cs.c b/src/mesa/drivers/dri/i965/brw_cs.c
index 263d224e882..d88e822a9e7 100644
--- a/src/mesa/drivers/dri/i965/brw_cs.c
+++ b/src/mesa/drivers/dri/i965/brw_cs.c
@@ -31,6 +31,44 @@
#include "brw_state.h"
#include "intel_batchbuffer.h"
#include "brw_nir.h"
+#include "brw_program.h"
+#include "glsl/ir_uniform.h"
+
+void
+brw_cs_fill_local_id_payload(const struct brw_cs_prog_data *prog_data,
+ void *buffer, uint32_t threads, uint32_t stride)
+{
+ if (prog_data->local_invocation_id_regs == 0)
+ return;
+
+ /* 'stride' should be an integer number of registers, that is, a multiple
+ * of 32 bytes.
+ */
+ assert(stride % 32 == 0);
+
+ unsigned x = 0, y = 0, z = 0;
+ for (unsigned t = 0; t < threads; t++) {
+ uint32_t *param = (uint32_t *) buffer + stride * t / 4;
+
+ for (unsigned i = 0; i < prog_data->simd_size; i++) {
+ param[0 * prog_data->simd_size + i] = x;
+ param[1 * prog_data->simd_size + i] = y;
+ param[2 * prog_data->simd_size + i] = z;
+
+ x++;
+ if (x == prog_data->local_size[0]) {
+ x = 0;
+ y++;
+ if (y == prog_data->local_size[1]) {
+ y = 0;
+ z++;
+ if (z == prog_data->local_size[2])
+ z = 0;
+ }
+ }
+ }
+ }
+}
static void
assign_cs_binding_table_offsets(const struct brw_device_info *devinfo,
@@ -69,6 +107,19 @@ brw_codegen_cs_prog(struct brw_context *brw,
memset(&prog_data, 0, sizeof(prog_data));
+ if (prog->Comp.SharedSize > 64 * 1024) {
+ prog->LinkStatus = false;
+ const char *error_str =
+ "Compute shader used more than 64KB of shared variables";
+ ralloc_strcat(&prog->InfoLog, error_str);
+ _mesa_problem(NULL, "Failed to link compute shader: %s\n", error_str);
+
+ ralloc_free(mem_ctx);
+ return false;
+ } else {
+ prog_data.base.total_shared = prog->Comp.SharedSize;
+ }
+
assign_cs_binding_table_offsets(brw->intelScreen->devinfo, prog,
&cp->program.Base, &prog_data);
diff --git a/src/mesa/drivers/dri/i965/brw_cs.h b/src/mesa/drivers/dri/i965/brw_cs.h
index f0b3f97dedc..890a0c8a807 100644
--- a/src/mesa/drivers/dri/i965/brw_cs.h
+++ b/src/mesa/drivers/dri/i965/brw_cs.h
@@ -25,8 +25,6 @@
#ifndef BRW_CS_H
#define BRW_CS_H
-#include "brw_program.h"
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index a149ce3ba12..b777bce70c1 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -50,7 +50,6 @@
*/
-#include "main/glheader.h"
#include "main/context.h"
#include "main/macros.h"
#include "main/enums.h"
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 36d9f716e03..7d8723efd5e 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -41,6 +41,12 @@
#define GET_BITS(data, high, low) ((data & INTEL_MASK((high), (low))) >> (low))
#define GET_FIELD(word, field) (((word) & field ## _MASK) >> field ## _SHIFT)
+/**
+ * For use with masked MMIO registers where the upper 16 bits control which
+ * of the lower bits are committed to the register.
+ */
+#define REG_MASK(value) ((value) << 16)
+
#ifndef BRW_DEFINES_H
#define BRW_DEFINES_H
@@ -1722,6 +1728,19 @@ enum brw_message_target {
#define HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2 12
#define HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE 13
+/* Dataport special binding table indices: */
+#define BRW_BTI_STATELESS 255
+#define GEN7_BTI_SLM 254
+/* Note that on Gen8+ BTI 255 was redefined to be IA-coherent according to the
+ * hardware spec, however because the DRM sets bit 4 of HDC_CHICKEN0 on BDW,
+ * CHV and at least some pre-production steppings of SKL due to
+ * WaForceEnableNonCoherent, HDC memory access may have been overridden by the
+ * kernel to be non-coherent (matching the behavior of the same BTI on
+ * pre-Gen8 hardware) and BTI 255 may actually be an alias for BTI 253.
+ */
+#define GEN8_BTI_STATELESS_IA_COHERENT 255
+#define GEN8_BTI_STATELESS_NON_COHERENT 253
+
/* dataport atomic operations. */
#define BRW_AOP_AND 1
#define BRW_AOP_OR 2
@@ -2554,6 +2573,25 @@ enum brw_wm_barycentric_interp_mode {
#define _3DSTATE_CONSTANT_HS 0x7819 /* GEN7+ */
#define _3DSTATE_CONSTANT_DS 0x781A /* GEN7+ */
+/* Resource streamer gather constants */
+#define _3DSTATE_GATHER_POOL_ALLOC 0x791A /* GEN7.5+ */
+#define HSW_GATHER_POOL_ALLOC_MUST_BE_ONE (3 << 4) /* GEN7.5 only */
+
+#define _3DSTATE_GATHER_CONSTANT_VS 0x7834 /* GEN7.5+ */
+#define _3DSTATE_GATHER_CONSTANT_GS 0x7835
+#define _3DSTATE_GATHER_CONSTANT_HS 0x7836
+#define _3DSTATE_GATHER_CONSTANT_DS 0x7837
+#define _3DSTATE_GATHER_CONSTANT_PS 0x7838
+#define HSW_GATHER_CONSTANT_ENABLE (1 << 11)
+#define HSW_GATHER_CONSTANT_BUFFER_VALID_SHIFT 16
+#define HSW_GATHER_CONSTANT_BUFFER_VALID_MASK INTEL_MASK(31, 16)
+#define HSW_GATHER_CONSTANT_BINDING_TABLE_BLOCK_SHIFT 12
+#define HSW_GATHER_CONSTANT_BINDING_TABLE_BLOCK_MASK INTEL_MASK(15, 12)
+#define HSW_GATHER_CONSTANT_CONST_BUFFER_OFFSET_SHIFT 8
+#define HSW_GATHER_CONSTANT_CONST_BUFFER_OFFSET_MASK INTEL_MASK(15, 8)
+#define HSW_GATHER_CONSTANT_CHANNEL_MASK_SHIFT 4
+#define HSW_GATHER_CONSTANT_CHANNEL_MASK_MASK INTEL_MASK(7, 4)
+
#define _3DSTATE_STREAMOUT 0x781e /* GEN7+ */
/* DW1 */
# define SO_FUNCTION_ENABLE (1 << 31)
@@ -2848,6 +2886,8 @@ enum brw_wm_barycentric_interp_mode {
/* GEN7 DW5, GEN8+ DW6 */
# define MEDIA_BARRIER_ENABLE_SHIFT 21
# define MEDIA_BARRIER_ENABLE_MASK INTEL_MASK(21, 21)
+# define MEDIA_SHARED_LOCAL_MEMORY_SIZE_SHIFT 16
+# define MEDIA_SHARED_LOCAL_MEMORY_SIZE_MASK INTEL_MASK(20, 16)
# define MEDIA_GPGPU_THREAD_COUNT_SHIFT 0
# define MEDIA_GPGPU_THREAD_COUNT_MASK INTEL_MASK(7, 0)
# define GEN8_MEDIA_GPGPU_THREAD_COUNT_SHIFT 0
diff --git a/src/mesa/drivers/dri/i965/brw_device_info.c b/src/mesa/drivers/dri/i965/brw_device_info.c
index 541c7958d5e..db9acd64f4e 100644
--- a/src/mesa/drivers/dri/i965/brw_device_info.c
+++ b/src/mesa/drivers/dri/i965/brw_device_info.c
@@ -28,6 +28,7 @@
static const struct brw_device_info brw_device_info_i965 = {
.gen = 4,
.has_negative_rhw_bug = true,
+ .num_slices = 1,
.max_vs_threads = 16,
.max_gs_threads = 2,
.max_wm_threads = 8 * 4,
@@ -42,6 +43,7 @@ static const struct brw_device_info brw_device_info_g4x = {
.has_compr4 = true,
.has_surface_tile_offset = true,
.is_g4x = true,
+ .num_slices = 1,
.max_vs_threads = 32,
.max_gs_threads = 2,
.max_wm_threads = 10 * 5,
@@ -55,6 +57,7 @@ static const struct brw_device_info brw_device_info_ilk = {
.has_pln = true,
.has_compr4 = true,
.has_surface_tile_offset = true,
+ .num_slices = 1,
.max_vs_threads = 72,
.max_gs_threads = 32,
.max_wm_threads = 12 * 6,
@@ -71,6 +74,7 @@ static const struct brw_device_info brw_device_info_snb_gt1 = {
.has_pln = true,
.has_surface_tile_offset = true,
.needs_unlit_centroid_workaround = true,
+ .num_slices = 1,
.max_vs_threads = 24,
.max_gs_threads = 21, /* conservative; 24 if rendering disabled. */
.max_wm_threads = 40,
@@ -90,6 +94,7 @@ static const struct brw_device_info brw_device_info_snb_gt2 = {
.has_pln = true,
.has_surface_tile_offset = true,
.needs_unlit_centroid_workaround = true,
+ .num_slices = 1,
.max_vs_threads = 60,
.max_gs_threads = 60,
.max_wm_threads = 80,
@@ -112,6 +117,7 @@ static const struct brw_device_info brw_device_info_snb_gt2 = {
static const struct brw_device_info brw_device_info_ivb_gt1 = {
GEN7_FEATURES, .is_ivybridge = true, .gt = 1,
.needs_unlit_centroid_workaround = true,
+ .num_slices = 1,
.max_vs_threads = 36,
.max_hs_threads = 36,
.max_ds_threads = 36,
@@ -123,6 +129,7 @@ static const struct brw_device_info brw_device_info_ivb_gt1 = {
.min_vs_entries = 32,
.max_vs_entries = 512,
.max_hs_entries = 32,
+ .min_ds_entries = 10,
.max_ds_entries = 288,
.max_gs_entries = 192,
},
@@ -131,6 +138,7 @@ static const struct brw_device_info brw_device_info_ivb_gt1 = {
static const struct brw_device_info brw_device_info_ivb_gt2 = {
GEN7_FEATURES, .is_ivybridge = true, .gt = 2,
.needs_unlit_centroid_workaround = true,
+ .num_slices = 1,
.max_vs_threads = 128,
.max_hs_threads = 128,
.max_ds_threads = 128,
@@ -142,6 +150,7 @@ static const struct brw_device_info brw_device_info_ivb_gt2 = {
.min_vs_entries = 32,
.max_vs_entries = 704,
.max_hs_entries = 64,
+ .min_ds_entries = 10,
.max_ds_entries = 448,
.max_gs_entries = 320,
},
@@ -150,6 +159,7 @@ static const struct brw_device_info brw_device_info_ivb_gt2 = {
static const struct brw_device_info brw_device_info_byt = {
GEN7_FEATURES, .is_baytrail = true, .gt = 1,
.needs_unlit_centroid_workaround = true,
+ .num_slices = 1,
.has_llc = false,
.max_vs_threads = 36,
.max_hs_threads = 36,
@@ -162,6 +172,7 @@ static const struct brw_device_info brw_device_info_byt = {
.min_vs_entries = 32,
.max_vs_entries = 512,
.max_hs_entries = 32,
+ .min_ds_entries = 10,
.max_ds_entries = 288,
.max_gs_entries = 192,
},
@@ -175,6 +186,7 @@ static const struct brw_device_info brw_device_info_byt = {
static const struct brw_device_info brw_device_info_hsw_gt1 = {
HSW_FEATURES, .gt = 1,
+ .num_slices = 1,
.max_vs_threads = 70,
.max_hs_threads = 70,
.max_ds_threads = 70,
@@ -186,6 +198,7 @@ static const struct brw_device_info brw_device_info_hsw_gt1 = {
.min_vs_entries = 32,
.max_vs_entries = 640,
.max_hs_entries = 64,
+ .min_ds_entries = 10,
.max_ds_entries = 384,
.max_gs_entries = 256,
},
@@ -193,6 +206,7 @@ static const struct brw_device_info brw_device_info_hsw_gt1 = {
static const struct brw_device_info brw_device_info_hsw_gt2 = {
HSW_FEATURES, .gt = 2,
+ .num_slices = 1,
.max_vs_threads = 280,
.max_hs_threads = 256,
.max_ds_threads = 280,
@@ -204,6 +218,7 @@ static const struct brw_device_info brw_device_info_hsw_gt2 = {
.min_vs_entries = 64,
.max_vs_entries = 1664,
.max_hs_entries = 128,
+ .min_ds_entries = 10,
.max_ds_entries = 960,
.max_gs_entries = 640,
},
@@ -211,6 +226,7 @@ static const struct brw_device_info brw_device_info_hsw_gt2 = {
static const struct brw_device_info brw_device_info_hsw_gt3 = {
HSW_FEATURES, .gt = 3,
+ .num_slices = 2,
.max_vs_threads = 280,
.max_hs_threads = 256,
.max_ds_threads = 280,
@@ -222,6 +238,7 @@ static const struct brw_device_info brw_device_info_hsw_gt3 = {
.min_vs_entries = 64,
.max_vs_entries = 1664,
.max_hs_entries = 128,
+ .min_ds_entries = 10,
.max_ds_entries = 960,
.max_gs_entries = 640,
},
@@ -243,12 +260,14 @@ static const struct brw_device_info brw_device_info_hsw_gt3 = {
static const struct brw_device_info brw_device_info_bdw_gt1 = {
GEN8_FEATURES, .gt = 1,
+ .num_slices = 1,
.max_cs_threads = 42,
.urb = {
.size = 192,
.min_vs_entries = 64,
.max_vs_entries = 2560,
.max_hs_entries = 504,
+ .min_ds_entries = 34,
.max_ds_entries = 1536,
.max_gs_entries = 960,
}
@@ -256,12 +275,14 @@ static const struct brw_device_info brw_device_info_bdw_gt1 = {
static const struct brw_device_info brw_device_info_bdw_gt2 = {
GEN8_FEATURES, .gt = 2,
+ .num_slices = 1,
.max_cs_threads = 56,
.urb = {
.size = 384,
.min_vs_entries = 64,
.max_vs_entries = 2560,
.max_hs_entries = 504,
+ .min_ds_entries = 34,
.max_ds_entries = 1536,
.max_gs_entries = 960,
}
@@ -269,12 +290,14 @@ static const struct brw_device_info brw_device_info_bdw_gt2 = {
static const struct brw_device_info brw_device_info_bdw_gt3 = {
GEN8_FEATURES, .gt = 3,
+ .num_slices = 2,
.max_cs_threads = 56,
.urb = {
.size = 384,
.min_vs_entries = 64,
.max_vs_entries = 2560,
.max_hs_entries = 504,
+ .min_ds_entries = 34,
.max_ds_entries = 1536,
.max_gs_entries = 960,
}
@@ -283,6 +306,7 @@ static const struct brw_device_info brw_device_info_bdw_gt3 = {
static const struct brw_device_info brw_device_info_chv = {
GEN8_FEATURES, .is_cherryview = 1, .gt = 1,
.has_llc = false,
+ .num_slices = 1,
.max_vs_threads = 80,
.max_hs_threads = 80,
.max_ds_threads = 80,
@@ -294,6 +318,7 @@ static const struct brw_device_info brw_device_info_chv = {
.min_vs_entries = 34,
.max_vs_entries = 640,
.max_hs_entries = 80,
+ .min_ds_entries = 34,
.max_ds_entries = 384,
.max_gs_entries = 256,
}
@@ -318,25 +343,30 @@ static const struct brw_device_info brw_device_info_chv = {
.min_vs_entries = 64, \
.max_vs_entries = 1856, \
.max_hs_entries = 672, \
+ .min_ds_entries = 34, \
.max_ds_entries = 1120, \
.max_gs_entries = 640, \
}
static const struct brw_device_info brw_device_info_skl_gt1 = {
GEN9_FEATURES, .gt = 1,
+ .num_slices = 1,
.urb.size = 192,
};
static const struct brw_device_info brw_device_info_skl_gt2 = {
GEN9_FEATURES, .gt = 2,
+ .num_slices = 1,
};
static const struct brw_device_info brw_device_info_skl_gt3 = {
GEN9_FEATURES, .gt = 3,
+ .num_slices = 2,
};
static const struct brw_device_info brw_device_info_skl_gt4 = {
GEN9_FEATURES, .gt = 4,
+ .num_slices = 3,
/* From the "L3 Allocation and Programming" documentation:
*
* "URB is limited to 1008KB due to programming restrictions. This is not a
@@ -355,6 +385,7 @@ static const struct brw_device_info brw_device_info_bxt = {
.has_llc = false,
/* XXX: These are preliminary thread counts and URB sizes. */
+ .num_slices = 1,
.max_vs_threads = 56,
.max_hs_threads = 56,
.max_ds_threads = 56,
diff --git a/src/mesa/drivers/dri/i965/brw_device_info.h b/src/mesa/drivers/dri/i965/brw_device_info.h
index 6f4a250e874..48e0dee9084 100644
--- a/src/mesa/drivers/dri/i965/brw_device_info.h
+++ b/src/mesa/drivers/dri/i965/brw_device_info.h
@@ -68,6 +68,11 @@ struct brw_device_info
* GPU Limits:
* @{
*/
+ /**
+ * Total number of slices present on the device whether or not they've been
+ * fused off.
+ */
+ unsigned num_slices;
unsigned max_vs_threads;
unsigned max_hs_threads;
unsigned max_ds_threads;
@@ -76,10 +81,16 @@ struct brw_device_info
unsigned max_cs_threads;
struct {
+ /**
+ * Hardware default URB size. The units this is expressed in are
+ * somewhat inconsistent: 512b units on Gen4-5, KB on Gen6-7, and KB
+ * times the slice count on Gen8+.
+ */
unsigned size;
unsigned min_vs_entries;
unsigned max_vs_entries;
unsigned max_hs_entries;
+ unsigned min_ds_entries;
unsigned max_ds_entries;
unsigned max_gs_entries;
} urb;
diff --git a/src/mesa/drivers/dri/i965/brw_disasm.c b/src/mesa/drivers/dri/i965/brw_disasm.c
index 650bdeea344..09eb2392836 100644
--- a/src/mesa/drivers/dri/i965/brw_disasm.c
+++ b/src/mesa/drivers/dri/i965/brw_disasm.c
@@ -21,10 +21,7 @@
*/
#include
-#include
#include
-#include
-#include
#include
#include "brw_context.h"
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index a2eaf8fb1e0..bc013963eee 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -25,7 +25,6 @@
#include
-#include "main/glheader.h"
#include "main/context.h"
#include "main/condrender.h"
#include "main/samplerobj.h"
@@ -116,14 +115,17 @@ gen6_set_prim(struct brw_context *brw, const struct _mesa_prim *prim)
DBG("PRIM: %s\n", _mesa_enum_to_string(prim->mode));
- if (prim->mode == GL_PATCHES)
+ if (prim->mode == GL_PATCHES) {
hw_prim = _3DPRIM_PATCHLIST(ctx->TessCtrlProgram.patch_vertices);
- else
+ } else {
hw_prim = get_hw_prim_for_gl_prim(prim->mode);
+ }
if (hw_prim != brw->primitive) {
brw->primitive = hw_prim;
brw->ctx.NewDriverState |= BRW_NEW_PRIMITIVE;
+ if (prim->mode == GL_PATCHES)
+ brw->ctx.NewDriverState |= BRW_NEW_PATCH_PRIMITIVE;
}
}
@@ -397,6 +399,10 @@ brw_try_draw_prims(struct gl_context *ctx,
_mesa_fls(ctx->FragmentProgram._Current->Base.SamplersUsed);
brw->gs.base.sampler_count = ctx->GeometryProgram._Current ?
_mesa_fls(ctx->GeometryProgram._Current->Base.SamplersUsed) : 0;
+ brw->tes.base.sampler_count = ctx->TessEvalProgram._Current ?
+ _mesa_fls(ctx->TessEvalProgram._Current->Base.SamplersUsed) : 0;
+ brw->tcs.base.sampler_count = ctx->TessCtrlProgram._Current ?
+ _mesa_fls(ctx->TessCtrlProgram._Current->Base.SamplersUsed) : 0;
brw->vs.base.sampler_count =
_mesa_fls(ctx->VertexProgram._Current->Base.SamplersUsed);
diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h
index 695973b5bec..23d98ef8b4b 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.h
+++ b/src/mesa/drivers/dri/i965/brw_draw.h
@@ -27,7 +27,6 @@
#define BRW_DRAW_H
#include "main/mtypes.h" /* for struct gl_context... */
-#include "vbo/vbo.h"
struct brw_context;
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index a0ae0151306..ea0f6f29c4f 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -23,7 +23,6 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "main/glheader.h"
#include "main/bufferobj.h"
#include "main/context.h"
#include "main/enums.h"
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 829e39330f2..686b42be11e 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -35,11 +35,9 @@
#include
#include "brw_inst.h"
-#include "brw_structs.h"
#include "brw_defines.h"
#include "brw_reg.h"
#include "intel_asm_annotation.h"
-#include "program/prog_instruction.h"
#ifdef __cplusplus
extern "C" {
@@ -317,6 +315,8 @@ void brw_oword_block_read(struct brw_codegen *p,
uint32_t offset,
uint32_t bind_table_index);
+unsigned brw_scratch_surface_idx(const struct brw_codegen *p);
+
void brw_oword_block_read_scratch(struct brw_codegen *p,
struct brw_reg dest,
struct brw_reg mrf,
@@ -543,6 +543,15 @@ is_3src(enum opcode opcode)
return opcode_descs[opcode].nsrc == 3;
}
+/** Maximum SEND message length */
+#define BRW_MAX_MSG_LENGTH 15
+
+/** First MRF register used by pull loads */
+#define FIRST_SPILL_MRF(gen) ((gen) == 6 ? 21 : 13)
+
+/** First MRF register used by spills */
+#define FIRST_PULL_LOAD_MRF(gen) ((gen) == 6 ? 16 : 13)
+
#ifdef __cplusplus
}
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index da1ddfddb50..25064c0eb87 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1997,6 +1997,19 @@ void gen6_math(struct brw_codegen *p,
brw_set_src1(p, insn, src1);
}
+/**
+ * Return the right surface index to access the thread scratch space using
+ * stateless dataport messages.
+ */
+unsigned
+brw_scratch_surface_idx(const struct brw_codegen *p)
+{
+ /* The scratch space is thread-local so IA coherency is unnecessary. */
+ if (p->devinfo->gen >= 8)
+ return GEN8_BTI_STATELESS_NON_COHERENT;
+ else
+ return BRW_BTI_STATELESS;
+}
/**
* Write a block of OWORDs (half a GRF each) from the scratch buffer,
@@ -2097,7 +2110,7 @@ void brw_oword_block_write_scratch(struct brw_codegen *p,
brw_set_dp_write_message(p,
insn,
- 255, /* binding table index (255=stateless) */
+ brw_scratch_surface_idx(p),
msg_control,
msg_type,
mlen,
@@ -2183,7 +2196,7 @@ brw_oword_block_read_scratch(struct brw_codegen *p,
brw_set_dp_read_message(p,
insn,
- 255, /* binding table index (255=stateless) */
+ brw_scratch_surface_idx(p),
msg_control,
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
BRW_DATAPORT_READ_TARGET_RENDER_CACHE,
@@ -2604,17 +2617,27 @@ brw_find_next_block_end(struct brw_codegen *p, int start_offset)
void *store = p->store;
const struct brw_device_info *devinfo = p->devinfo;
+ int depth = 0;
+
for (offset = next_offset(devinfo, store, start_offset);
offset < p->next_insn_offset;
offset = next_offset(devinfo, store, offset)) {
brw_inst *insn = store + offset;
switch (brw_inst_opcode(devinfo, insn)) {
+ case BRW_OPCODE_IF:
+ depth++;
+ break;
case BRW_OPCODE_ENDIF:
+ if (depth == 0)
+ return offset;
+ depth--;
+ break;
case BRW_OPCODE_ELSE:
case BRW_OPCODE_WHILE:
case BRW_OPCODE_HALT:
- return offset;
+ if (depth == 0)
+ return offset;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_ff_gs.c b/src/mesa/drivers/dri/i965/brw_ff_gs.c
index f72f37f4d02..c329ecedaaf 100644
--- a/src/mesa/drivers/dri/i965/brw_ff_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_ff_gs.c
@@ -29,7 +29,6 @@
* Keith Whitwell
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
#include "main/transformfeedback.h"
diff --git a/src/mesa/drivers/dri/i965/brw_ff_gs.h b/src/mesa/drivers/dri/i965/brw_ff_gs.h
index 9e016b883ca..e952b6413de 100644
--- a/src/mesa/drivers/dri/i965/brw_ff_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_ff_gs.h
@@ -37,7 +37,7 @@
#include "brw_context.h"
#include "brw_eu.h"
-#define MAX_GS_VERTS (4)
+#define MAX_GS_VERTS (4)
struct brw_ff_gs_prog_key {
GLbitfield64 attrs;
diff --git a/src/mesa/drivers/dri/i965/brw_ff_gs_emit.c b/src/mesa/drivers/dri/i965/brw_ff_gs_emit.c
index 830fc6e41df..8589dabe4c5 100644
--- a/src/mesa/drivers/dri/i965/brw_ff_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_ff_gs_emit.c
@@ -30,7 +30,6 @@
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 419168966de..8dc260c51b9 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -28,29 +28,17 @@
* from the LIR.
*/
-#include
-
-#include "util/hash_table.h"
#include "main/macros.h"
-#include "main/shaderobj.h"
-#include "main/fbobject.h"
-#include "program/prog_parameter.h"
-#include "program/prog_print.h"
-#include "util/register_allocate.h"
-#include "program/hash_table.h"
#include "brw_context.h"
#include "brw_eu.h"
-#include "brw_wm.h"
#include "brw_fs.h"
#include "brw_cs.h"
#include "brw_nir.h"
#include "brw_vec4_gs_visitor.h"
#include "brw_cfg.h"
+#include "brw_program.h"
#include "brw_dead_control_flow.h"
-#include "main/uniforms.h"
-#include "brw_fs_live_variables.h"
#include "glsl/nir/glsl_types.h"
-#include "program/sampler.h"
using namespace brw;
@@ -187,7 +175,7 @@ fs_visitor::VARYING_PULL_CONSTANT_LOAD(const fs_builder &bld,
* the redundant ones.
*/
fs_reg vec4_offset = vgrf(glsl_type::int_type);
- bld.ADD(vec4_offset, varying_offset, brw_imm_ud(const_offset & ~3));
+ bld.ADD(vec4_offset, varying_offset, brw_imm_ud(const_offset & ~0xf));
int scale = 1;
if (devinfo->gen == 4 && bld.dispatch_width() == 8) {
@@ -219,7 +207,7 @@ fs_visitor::VARYING_PULL_CONSTANT_LOAD(const fs_builder &bld,
inst->mlen = 1 + bld.dispatch_width() / 8;
}
- bld.MOV(dst, offset(vec4_result, bld, (const_offset & 3) * scale));
+ bld.MOV(dst, offset(vec4_result, bld, ((const_offset & 0xf) / 4) * scale));
}
/**
@@ -300,6 +288,71 @@ fs_inst::is_send_from_grf() const
}
}
+/**
+ * Returns true if this instruction's sources and destinations cannot
+ * safely be the same register.
+ *
+ * In most cases, a register can be written over safely by the same
+ * instruction that is its last use. For a single instruction, the
+ * sources are dereferenced before writing of the destination starts
+ * (naturally).
+ *
+ * However, there are a few cases where this can be problematic:
+ *
+ * - Virtual opcodes that translate to multiple instructions in the
+ * code generator: if src == dst and one instruction writes the
+ * destination before a later instruction reads the source, then
+ * src will have been clobbered.
+ *
+ * - SIMD16 compressed instructions with certain regioning (see below).
+ *
+ * The register allocator uses this information to set up conflicts between
+ * GRF sources and the destination.
+ */
+bool
+fs_inst::has_source_and_destination_hazard() const
+{
+ switch (opcode) {
+ case FS_OPCODE_PACK_HALF_2x16_SPLIT:
+ /* Multiple partial writes to the destination */
+ return true;
+ default:
+ /* The SIMD16 compressed instruction
+ *
+ * add(16) g4<1>F g4<8,8,1>F g6<8,8,1>F
+ *
+ * is actually decoded in hardware as:
+ *
+ * add(8) g4<1>F g4<8,8,1>F g6<8,8,1>F
+ * add(8) g5<1>F g5<8,8,1>F g7<8,8,1>F
+ *
+ * Which is safe. However, if we have uniform accesses
+ * happening, we get into trouble:
+ *
+ * add(8) g4<1>F g4<0,1,0>F g6<8,8,1>F
+ * add(8) g5<1>F g4<0,1,0>F g7<8,8,1>F
+ *
+ * Now our destination for the first instruction overwrote the
+ * second instruction's src0, and we get garbage for those 8
+ * pixels. There's a similar issue for the pre-gen6
+ * pixel_x/pixel_y, which are registers of 16-bit values and thus
+ * would get stomped by the first decode as well.
+ */
+ if (exec_size == 16) {
+ for (int i = 0; i < sources; i++) {
+ if (src[i].file == VGRF && (src[i].stride == 0 ||
+ src[i].type == BRW_REGISTER_TYPE_UW ||
+ src[i].type == BRW_REGISTER_TYPE_W ||
+ src[i].type == BRW_REGISTER_TYPE_UB ||
+ src[i].type == BRW_REGISTER_TYPE_B)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
+
bool
fs_inst::is_copy_payload(const brw::simple_allocator &grf_alloc) const
{
@@ -375,7 +428,7 @@ fs_reg::fs_reg()
this->file = BAD_FILE;
}
-fs_reg::fs_reg(struct brw_reg reg) :
+fs_reg::fs_reg(struct ::brw_reg reg) :
backend_reg(reg)
{
this->reg_offset = 0;
@@ -393,8 +446,7 @@ fs_reg::fs_reg(struct brw_reg reg) :
bool
fs_reg::equals(const fs_reg &r) const
{
- return (memcmp((brw_reg *)this, (brw_reg *)&r, sizeof(brw_reg)) == 0 &&
- reg_offset == r.reg_offset &&
+ return (this->backend_reg::equals(r) &&
subreg_offset == r.subreg_offset &&
!reladdr && !r.reladdr &&
stride == r.stride);
@@ -1057,33 +1109,19 @@ fs_visitor::emit_linterp(const fs_reg &attr, const fs_reg &interp,
}
void
-fs_visitor::emit_general_interpolation(fs_reg attr, const char *name,
+fs_visitor::emit_general_interpolation(fs_reg *attr, const char *name,
const glsl_type *type,
glsl_interp_qualifier interpolation_mode,
- int location, bool mod_centroid,
+ int *location, bool mod_centroid,
bool mod_sample)
{
- attr.type = brw_type_for_base_type(type->get_scalar_type());
-
assert(stage == MESA_SHADER_FRAGMENT);
brw_wm_prog_data *prog_data = (brw_wm_prog_data*) this->prog_data;
brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
- unsigned int array_elements;
-
- if (type->is_array()) {
- array_elements = type->arrays_of_arrays_size();
- if (array_elements == 0) {
- fail("dereferenced array '%s' has length 0\n", name);
- }
- type = type->without_array();
- } else {
- array_elements = 1;
- }
-
if (interpolation_mode == INTERP_QUALIFIER_NONE) {
bool is_gl_Color =
- location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1;
+ *location == VARYING_SLOT_COL0 || *location == VARYING_SLOT_COL1;
if (key->flat_shade && is_gl_Color) {
interpolation_mode = INTERP_QUALIFIER_FLAT;
} else {
@@ -1091,71 +1129,86 @@ fs_visitor::emit_general_interpolation(fs_reg attr, const char *name,
}
}
- for (unsigned int i = 0; i < array_elements; i++) {
- for (unsigned int j = 0; j < type->matrix_columns; j++) {
- if (prog_data->urb_setup[location] == -1) {
- /* If there's no incoming setup data for this slot, don't
- * emit interpolation for it.
- */
- attr = offset(attr, bld, type->vector_elements);
- location++;
- continue;
- }
+ if (type->is_array() || type->is_matrix()) {
+ const glsl_type *elem_type = glsl_get_array_element(type);
+ const unsigned length = glsl_get_length(type);
- if (interpolation_mode == INTERP_QUALIFIER_FLAT) {
- /* Constant interpolation (flat shading) case. The SF has
- * handed us defined values in only the constant offset
- * field of the setup reg.
- */
- for (unsigned int k = 0; k < type->vector_elements; k++) {
- struct brw_reg interp = interp_reg(location, k);
- interp = suboffset(interp, 3);
- interp.type = attr.type;
- bld.emit(FS_OPCODE_CINTERP, attr, fs_reg(interp));
- attr = offset(attr, bld, 1);
- }
- } else {
- /* Smooth/noperspective interpolation case. */
- for (unsigned int k = 0; k < type->vector_elements; k++) {
- struct brw_reg interp = interp_reg(location, k);
- if (devinfo->needs_unlit_centroid_workaround && mod_centroid) {
- /* Get the pixel/sample mask into f0 so that we know
- * which pixels are lit. Then, for each channel that is
- * unlit, replace the centroid data with non-centroid
- * data.
- */
- bld.emit(FS_OPCODE_MOV_DISPATCH_TO_FLAGS);
-
- fs_inst *inst;
- inst = emit_linterp(attr, fs_reg(interp), interpolation_mode,
- false, false);
- inst->predicate = BRW_PREDICATE_NORMAL;
- inst->predicate_inverse = true;
- if (devinfo->has_pln)
- inst->no_dd_clear = true;
-
- inst = emit_linterp(attr, fs_reg(interp), interpolation_mode,
- mod_centroid && !key->persample_shading,
- mod_sample || key->persample_shading);
- inst->predicate = BRW_PREDICATE_NORMAL;
- inst->predicate_inverse = false;
- if (devinfo->has_pln)
- inst->no_dd_check = true;
-
- } else {
- emit_linterp(attr, fs_reg(interp), interpolation_mode,
- mod_centroid && !key->persample_shading,
- mod_sample || key->persample_shading);
- }
- if (devinfo->gen < 6 && interpolation_mode == INTERP_QUALIFIER_SMOOTH) {
- bld.MUL(attr, attr, this->pixel_w);
- }
- attr = offset(attr, bld, 1);
- }
-
- }
- location++;
+ for (unsigned i = 0; i < length; i++) {
+ emit_general_interpolation(attr, name, elem_type, interpolation_mode,
+ location, mod_centroid, mod_sample);
}
+ } else if (type->is_record()) {
+ for (unsigned i = 0; i < type->length; i++) {
+ const glsl_type *field_type = type->fields.structure[i].type;
+ emit_general_interpolation(attr, name, field_type, interpolation_mode,
+ location, mod_centroid, mod_sample);
+ }
+ } else {
+ assert(type->is_scalar() || type->is_vector());
+
+ if (prog_data->urb_setup[*location] == -1) {
+ /* If there's no incoming setup data for this slot, don't
+ * emit interpolation for it.
+ */
+ *attr = offset(*attr, bld, type->vector_elements);
+ (*location)++;
+ return;
+ }
+
+ attr->type = brw_type_for_base_type(type->get_scalar_type());
+
+ if (interpolation_mode == INTERP_QUALIFIER_FLAT) {
+ /* Constant interpolation (flat shading) case. The SF has
+ * handed us defined values in only the constant offset
+ * field of the setup reg.
+ */
+ for (unsigned int i = 0; i < type->vector_elements; i++) {
+ struct brw_reg interp = interp_reg(*location, i);
+ interp = suboffset(interp, 3);
+ interp.type = attr->type;
+ bld.emit(FS_OPCODE_CINTERP, *attr, fs_reg(interp));
+ *attr = offset(*attr, bld, 1);
+ }
+ } else {
+ /* Smooth/noperspective interpolation case. */
+ for (unsigned int i = 0; i < type->vector_elements; i++) {
+ struct brw_reg interp = interp_reg(*location, i);
+ if (devinfo->needs_unlit_centroid_workaround && mod_centroid) {
+ /* Get the pixel/sample mask into f0 so that we know
+ * which pixels are lit. Then, for each channel that is
+ * unlit, replace the centroid data with non-centroid
+ * data.
+ */
+ bld.emit(FS_OPCODE_MOV_DISPATCH_TO_FLAGS);
+
+ fs_inst *inst;
+ inst = emit_linterp(*attr, fs_reg(interp), interpolation_mode,
+ false, false);
+ inst->predicate = BRW_PREDICATE_NORMAL;
+ inst->predicate_inverse = true;
+ if (devinfo->has_pln)
+ inst->no_dd_clear = true;
+
+ inst = emit_linterp(*attr, fs_reg(interp), interpolation_mode,
+ mod_centroid && !key->persample_shading,
+ mod_sample || key->persample_shading);
+ inst->predicate = BRW_PREDICATE_NORMAL;
+ inst->predicate_inverse = false;
+ if (devinfo->has_pln)
+ inst->no_dd_check = true;
+
+ } else {
+ emit_linterp(*attr, fs_reg(interp), interpolation_mode,
+ mod_centroid && !key->persample_shading,
+ mod_sample || key->persample_shading);
+ }
+ if (devinfo->gen < 6 && interpolation_mode == INTERP_QUALIFIER_SMOOTH) {
+ bld.MUL(*attr, *attr, this->pixel_w);
+ }
+ *attr = offset(*attr, bld, 1);
+ }
+ }
+ (*location)++;
}
}
@@ -2003,7 +2056,7 @@ fs_visitor::demote_pull_constants()
VARYING_PULL_CONSTANT_LOAD(ibld, dst,
brw_imm_ud(index),
*inst->src[i].reladdr,
- pull_index);
+ pull_index * 4);
inst->src[i].reladdr = NULL;
inst->src[i].stride = 1;
} else {
@@ -2039,7 +2092,8 @@ fs_visitor::opt_algebraic()
if (inst->dst.type != inst->src[0].type)
assert(!"unimplemented: saturate mixed types");
- if (brw_saturate_immediate(inst->dst.type, &inst->src[0])) {
+ if (brw_saturate_immediate(inst->dst.type,
+ &inst->src[0].as_brw_reg())) {
inst->saturate = false;
progress = true;
}
@@ -3054,13 +3108,11 @@ fs_visitor::lower_uniform_pull_constant_loads()
continue;
if (devinfo->gen >= 7) {
- /* The offset arg before was a vec4-aligned byte offset. We need to
- * turn it into a dword offset.
- */
+ /* The offset arg is a vec4-aligned immediate byte offset. */
fs_reg const_offset_reg = inst->src[1];
assert(const_offset_reg.file == IMM &&
const_offset_reg.type == BRW_REGISTER_TYPE_UD);
- const_offset_reg.ud /= 4;
+ assert(const_offset_reg.ud % 16 == 0);
fs_reg payload, offset;
if (devinfo->gen >= 9) {
@@ -5542,42 +5594,6 @@ brw_compile_fs(const struct brw_compiler *compiler, void *log_data,
return g.get_assembly(final_assembly_size);
}
-void
-brw_cs_fill_local_id_payload(const struct brw_cs_prog_data *prog_data,
- void *buffer, uint32_t threads, uint32_t stride)
-{
- if (prog_data->local_invocation_id_regs == 0)
- return;
-
- /* 'stride' should be an integer number of registers, that is, a multiple
- * of 32 bytes.
- */
- assert(stride % 32 == 0);
-
- unsigned x = 0, y = 0, z = 0;
- for (unsigned t = 0; t < threads; t++) {
- uint32_t *param = (uint32_t *) buffer + stride * t / 4;
-
- for (unsigned i = 0; i < prog_data->simd_size; i++) {
- param[0 * prog_data->simd_size + i] = x;
- param[1 * prog_data->simd_size + i] = y;
- param[2 * prog_data->simd_size + i] = z;
-
- x++;
- if (x == prog_data->local_size[0]) {
- x = 0;
- y++;
- if (y == prog_data->local_size[1]) {
- y = 0;
- z++;
- if (z == prog_data->local_size[2])
- z = 0;
- }
- }
- }
- }
-}
-
fs_reg *
fs_visitor::emit_cs_local_invocation_id_setup()
{
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 658608f9951..dff86a97a14 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -30,28 +30,8 @@
#include "brw_shader.h"
#include "brw_ir_fs.h"
#include "brw_fs_builder.h"
-
-extern "C" {
-
-#include
-
-#include "main/macros.h"
-#include "main/shaderobj.h"
-#include "main/uniforms.h"
-#include "program/prog_parameter.h"
-#include "program/prog_print.h"
-#include "program/prog_optimize.h"
-#include "util/register_allocate.h"
-#include "program/hash_table.h"
-#include "brw_context.h"
-#include "brw_eu.h"
-#include "brw_wm.h"
-#include "intel_asm_annotation.h"
-}
-#include "glsl/nir/glsl_types.h"
#include "glsl/ir.h"
#include "glsl/nir/nir.h"
-#include "program/sampler.h"
struct bblock_t;
namespace {
@@ -205,10 +185,10 @@ public:
fs_reg *emit_frontfacing_interpolation();
fs_reg *emit_samplepos_setup();
fs_reg *emit_sampleid_setup();
- void emit_general_interpolation(fs_reg attr, const char *name,
+ void emit_general_interpolation(fs_reg *attr, const char *name,
const glsl_type *type,
glsl_interp_qualifier interpolation_mode,
- int location, bool mod_centroid,
+ int *location, bool mod_centroid,
bool mod_sample);
fs_reg *emit_vs_system_value(int location);
void emit_interpolation_setup_gen4();
@@ -245,6 +225,8 @@ public:
void emit_nir_code();
void nir_setup_inputs();
+ void nir_setup_single_output_varying(fs_reg *reg, const glsl_type *type,
+ unsigned *location);
void nir_setup_outputs();
void nir_setup_uniforms();
void nir_emit_system_values();
@@ -271,6 +253,8 @@ public:
nir_intrinsic_instr *instr);
void nir_emit_ssbo_atomic(const brw::fs_builder &bld,
int op, nir_intrinsic_instr *instr);
+ void nir_emit_shared_atomic(const brw::fs_builder &bld,
+ int op, nir_intrinsic_instr *instr);
void nir_emit_texture(const brw::fs_builder &bld,
nir_tex_instr *instr);
void nir_emit_jump(const brw::fs_builder &bld,
@@ -298,7 +282,7 @@ public:
unsigned stream_id);
void emit_gs_thread_end();
void emit_gs_input_load(const fs_reg &dst, const nir_src &vertex_src,
- const fs_reg &indirect_offset, unsigned imm_offset,
+ unsigned base_offset, const nir_src &offset_src,
unsigned num_components);
void emit_cs_terminate();
fs_reg *emit_cs_local_invocation_id_setup();
diff --git a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
index a13d001291c..b3fb0c6fd6e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
@@ -41,8 +41,6 @@
* we do retain the vector types in that case.
*/
-#include "main/core.h"
-#include "brw_wm.h"
#include "glsl/ir.h"
#include "glsl/ir_expression_flattening.h"
#include "glsl/nir/glsl_types.h"
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp
index 7c01f1e3d62..b5badaef977 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp
@@ -22,8 +22,8 @@
*/
#include "brw_fs.h"
-#include "brw_fs_live_variables.h"
#include "brw_cfg.h"
+#include "brw_eu.h"
/** @file brw_fs_cmod_propagation.cpp
*
diff --git a/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp b/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp
index c3ad7ad4771..c5280ac8726 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp
@@ -35,7 +35,6 @@
*/
#include "brw_fs.h"
-#include "brw_fs_live_variables.h"
#include "brw_cfg.h"
using namespace brw;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
index 62ae9abede7..fd25307c587 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
@@ -37,6 +37,7 @@
#include "util/bitset.h"
#include "brw_fs.h"
#include "brw_cfg.h"
+#include "brw_eu.h"
namespace { /* avoid conflict with opt_copy_propagation_elements */
struct acp_entry : public exec_node {
@@ -532,14 +533,14 @@ fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry)
if (inst->src[i].abs) {
if ((devinfo->gen >= 8 && is_logic_op(inst->opcode)) ||
- !brw_abs_immediate(val.type, &val)) {
+ !brw_abs_immediate(val.type, &val.as_brw_reg())) {
continue;
}
}
if (inst->src[i].negate) {
if ((devinfo->gen >= 8 && is_logic_op(inst->opcode)) ||
- !brw_negate_immediate(val.type, &val)) {
+ !brw_negate_immediate(val.type, &val.as_brw_reg())) {
continue;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp b/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp
index a50cf6f24f1..bd57e09fe0c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp
@@ -45,13 +45,13 @@ fs_visitor::dead_code_eliminate()
BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
BITSET_WORD *flag_live = ralloc_array(NULL, BITSET_WORD, 1);
- foreach_block (block, cfg) {
+ foreach_block_reverse_safe(block, cfg) {
memcpy(live, live_intervals->block_data[block->num].liveout,
sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout,
sizeof(BITSET_WORD));
- foreach_inst_in_block_reverse(fs_inst, inst, block) {
+ foreach_inst_in_block_reverse_safe(fs_inst, inst, block) {
if (inst->dst.file == VGRF && !inst->has_side_effects()) {
bool result_live = false;
@@ -72,7 +72,6 @@ fs_visitor::dead_code_eliminate()
inst->dst = fs_reg(retype(brw_null_reg(), inst->dst.type));
} else {
inst->opcode = BRW_OPCODE_NOP;
- continue;
}
}
}
@@ -81,7 +80,6 @@ fs_visitor::dead_code_eliminate()
if (!BITSET_TEST(flag_live, inst->flag_subreg)) {
inst->opcode = BRW_OPCODE_NOP;
progress = true;
- continue;
}
}
@@ -93,7 +91,6 @@ fs_visitor::dead_code_eliminate()
!inst->writes_accumulator) {
inst->opcode = BRW_OPCODE_NOP;
progress = true;
- continue;
}
if (inst->dst.file == VGRF) {
@@ -109,6 +106,11 @@ fs_visitor::dead_code_eliminate()
BITSET_CLEAR(flag_live, inst->flag_subreg);
}
+ if (inst->opcode == BRW_OPCODE_NOP) {
+ inst->remove(block);
+ continue;
+ }
+
for (int i = 0; i < inst->sources; i++) {
if (inst->src[i].file == VGRF) {
int var = live_intervals->var_from_reg(inst->src[i]);
@@ -128,15 +130,8 @@ fs_visitor::dead_code_eliminate()
ralloc_free(live);
ralloc_free(flag_live);
- if (progress) {
- foreach_block_and_inst_safe (block, backend_instruction, inst, cfg) {
- if (inst->opcode == BRW_OPCODE_NOP) {
- inst->remove(block);
- }
- }
-
+ if (progress)
invalidate_live_intervals();
- }
return progress;
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index 8528f391941..68c6443306e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -27,11 +27,10 @@
* native instructions.
*/
-#include "main/macros.h"
-#include "brw_context.h"
#include "brw_eu.h"
#include "brw_fs.h"
#include "brw_cfg.h"
+#include "brw_program.h"
static enum brw_reg_file
brw_file_from_reg(fs_reg *reg)
@@ -92,7 +91,7 @@ brw_reg_from_fs_reg(fs_inst *inst, fs_reg *reg, unsigned gen)
case ARF:
case FIXED_GRF:
case IMM:
- brw_reg = *static_cast(reg);
+ brw_reg = reg->as_brw_reg();
break;
case BAD_FILE:
/* Probably unused. */
diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
index 80fb8c28f81..66b70a9144b 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
@@ -59,42 +59,8 @@ fs_live_variables::setup_one_read(struct block_data *bd, fs_inst *inst,
int var = var_from_reg(reg);
assert(var < num_vars);
- /* In most cases, a register can be written over safely by the
- * same instruction that is its last use. For a single
- * instruction, the sources are dereferenced before writing of the
- * destination starts (naturally). This gets more complicated for
- * simd16, because the instruction:
- *
- * add(16) g4<1>F g4<8,8,1>F g6<8,8,1>F
- *
- * is actually decoded in hardware as:
- *
- * add(8) g4<1>F g4<8,8,1>F g6<8,8,1>F
- * add(8) g5<1>F g5<8,8,1>F g7<8,8,1>F
- *
- * Which is safe. However, if we have uniform accesses
- * happening, we get into trouble:
- *
- * add(8) g4<1>F g4<0,1,0>F g6<8,8,1>F
- * add(8) g5<1>F g4<0,1,0>F g7<8,8,1>F
- *
- * Now our destination for the first instruction overwrote the
- * second instruction's src0, and we get garbage for those 8
- * pixels. There's a similar issue for the pre-gen6
- * pixel_x/pixel_y, which are registers of 16-bit values and thus
- * would get stomped by the first decode as well.
- */
- int end_ip = ip;
- if (inst->exec_size == 16 && (reg.stride == 0 ||
- reg.type == BRW_REGISTER_TYPE_UW ||
- reg.type == BRW_REGISTER_TYPE_W ||
- reg.type == BRW_REGISTER_TYPE_UB ||
- reg.type == BRW_REGISTER_TYPE_B)) {
- end_ip++;
- }
-
start[var] = MIN2(start[var], ip);
- end[var] = MAX2(end[var], end_ip);
+ end[var] = MAX2(end[var], ip);
/* The use[] bitset marks when the block makes use of a variable (VGRF
* channel) without having completely defined that variable within the
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 6b0c4a5b36e..fdf2f5be2a6 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -22,16 +22,11 @@
*/
#include "glsl/ir.h"
-#include "glsl/ir_optimization.h"
-#include "glsl/nir/glsl_to_nir.h"
#include "main/shaderimage.h"
-#include "program/prog_to_nir.h"
#include "brw_fs.h"
#include "brw_fs_surface_builder.h"
-#include "brw_vec4_gs_visitor.h"
#include "brw_nir.h"
-#include "brw_fs_surface_builder.h"
-#include "brw_vec4_gs_visitor.h"
+#include "brw_program.h"
using namespace brw;
using namespace brw::surface_access;
@@ -81,14 +76,41 @@ fs_visitor::nir_setup_inputs()
reg.type = BRW_REGISTER_TYPE_D;
bld.emit(FS_OPCODE_CINTERP, retype(input, BRW_REGISTER_TYPE_D), reg);
} else {
- emit_general_interpolation(input, var->name, var->type,
+ int location = var->data.location;
+ emit_general_interpolation(&input, var->name, var->type,
(glsl_interp_qualifier) var->data.interpolation,
- var->data.location, var->data.centroid,
+ &location, var->data.centroid,
var->data.sample);
}
}
}
+void
+fs_visitor::nir_setup_single_output_varying(fs_reg *reg,
+ const glsl_type *type,
+ unsigned *location)
+{
+ if (type->is_array() || type->is_matrix()) {
+ const struct glsl_type *elem_type = glsl_get_array_element(type);
+ const unsigned length = glsl_get_length(type);
+
+ for (unsigned i = 0; i < length; i++) {
+ nir_setup_single_output_varying(reg, elem_type, location);
+ }
+ } else if (type->is_record()) {
+ for (unsigned i = 0; i < type->length; i++) {
+ const struct glsl_type *field_type = type->fields.structure[i].type;
+ nir_setup_single_output_varying(reg, field_type, location);
+ }
+ } else {
+ assert(type->is_scalar() || type->is_vector());
+ this->outputs[*location] = *reg;
+ this->output_components[*location] = type->vector_elements;
+ *reg = offset(*reg, bld, 4);
+ (*location)++;
+ }
+}
+
void
fs_visitor::nir_setup_outputs()
{
@@ -99,17 +121,13 @@ fs_visitor::nir_setup_outputs()
nir_foreach_variable(var, &nir->outputs) {
fs_reg reg = offset(nir_outputs, bld, var->data.driver_location);
- int vector_elements = var->type->without_array()->vector_elements;
-
switch (stage) {
case MESA_SHADER_VERTEX:
- case MESA_SHADER_GEOMETRY:
- for (int i = 0; i < type_size_vec4(var->type); i++) {
- int output = var->data.location + i;
- this->outputs[output] = offset(reg, bld, 4 * i);
- this->output_components[output] = vector_elements;
- }
+ case MESA_SHADER_GEOMETRY: {
+ unsigned location = var->data.location;
+ nir_setup_single_output_varying(®, var->type, &location);
break;
+ }
case MESA_SHADER_FRAGMENT:
if (var->data.index > 0) {
assert(var->data.location == FRAG_RESULT_DATA0);
@@ -129,6 +147,8 @@ fs_visitor::nir_setup_outputs()
} else if (var->data.location == FRAG_RESULT_SAMPLE_MASK) {
this->sample_mask = reg;
} else {
+ int vector_elements = var->type->without_array()->vector_elements;
+
/* gl_FragData or a user-defined FS output */
assert(var->data.location >= FRAG_RESULT_DATA0 &&
var->data.location < FRAG_RESULT_DATA0+BRW_MAX_DRAW_BUFFERS);
@@ -153,7 +173,7 @@ fs_visitor::nir_setup_uniforms()
if (dispatch_width != 8)
return;
- uniforms = nir->num_uniforms;
+ uniforms = nir->num_uniforms / 4;
nir_foreach_variable(var, &nir->uniforms) {
/* UBO's and atomics don't take up space in the uniform file */
@@ -161,7 +181,7 @@ fs_visitor::nir_setup_uniforms()
continue;
if (type_size_scalar(var->type) > 0)
- param_size[var->data.driver_location] = type_size_scalar(var->type);
+ param_size[var->data.driver_location / 4] = type_size_scalar(var->type);
}
}
@@ -1076,28 +1096,6 @@ fs_visitor::nir_emit_undef(const fs_builder &bld, nir_ssa_undef_instr *instr)
instr->def.num_components);
}
-static fs_reg
-fs_reg_for_nir_reg(fs_visitor *v, nir_register *nir_reg,
- unsigned base_offset, nir_src *indirect)
-{
- fs_reg reg;
-
- assert(!nir_reg->is_global);
-
- reg = v->nir_locals[nir_reg->index];
-
- reg = offset(reg, v->bld, base_offset * nir_reg->num_components);
- if (indirect) {
- int multiplier = nir_reg->num_components * (v->dispatch_width / 8);
-
- reg.reladdr = new(v->mem_ctx) fs_reg(v->vgrf(glsl_type::int_type));
- v->bld.MUL(*reg.reladdr, v->get_nir_src(*indirect),
- brw_imm_d(multiplier));
- }
-
- return reg;
-}
-
fs_reg
fs_visitor::get_nir_src(nir_src src)
{
@@ -1105,8 +1103,10 @@ fs_visitor::get_nir_src(nir_src src)
if (src.is_ssa) {
reg = nir_ssa_values[src.ssa->index];
} else {
- reg = fs_reg_for_nir_reg(this, src.reg.reg, src.reg.base_offset,
- src.reg.indirect);
+ /* We don't handle indirects on locals */
+ assert(src.reg.indirect == NULL);
+ reg = offset(nir_locals[src.reg.reg->index], bld,
+ src.reg.base_offset * src.reg.reg->num_components);
}
/* to avoid floating-point denorm flushing problems, set the type by
@@ -1123,16 +1123,18 @@ fs_visitor::get_nir_dest(nir_dest dest)
nir_ssa_values[dest.ssa.index] = bld.vgrf(BRW_REGISTER_TYPE_F,
dest.ssa.num_components);
return nir_ssa_values[dest.ssa.index];
+ } else {
+ /* We don't handle indirects on locals */
+ assert(dest.reg.indirect == NULL);
+ return offset(nir_locals[dest.reg.reg->index], bld,
+ dest.reg.base_offset * dest.reg.reg->num_components);
}
-
- return fs_reg_for_nir_reg(this, dest.reg.reg, dest.reg.base_offset,
- dest.reg.indirect);
}
fs_reg
fs_visitor::get_nir_image_deref(const nir_deref_var *deref)
{
- fs_reg image(UNIFORM, deref->var->data.driver_location,
+ fs_reg image(UNIFORM, deref->var->data.driver_location / 4,
BRW_REGISTER_TYPE_UD);
for (const nir_deref *tail = &deref->deref; tail->child;
@@ -1163,7 +1165,7 @@ fs_visitor::get_nir_image_deref(const nir_deref_var *deref)
bld.MOV(tmp, get_nir_src(deref_array->indirect));
}
- bld.MUL(tmp, tmp, brw_imm_ud(element_size));
+ bld.MUL(tmp, tmp, brw_imm_ud(element_size * 4));
if (image.reladdr)
bld.ADD(*image.reladdr, *image.reladdr, tmp);
else
@@ -1601,28 +1603,30 @@ fs_visitor::emit_gs_vertex(const nir_src &vertex_count_nir_src,
void
fs_visitor::emit_gs_input_load(const fs_reg &dst,
const nir_src &vertex_src,
- const fs_reg &indirect_offset,
- unsigned imm_offset,
+ unsigned base_offset,
+ const nir_src &offset_src,
unsigned num_components)
{
struct brw_gs_prog_data *gs_prog_data = (struct brw_gs_prog_data *) prog_data;
+ nir_const_value *vertex_const = nir_src_as_const_value(vertex_src);
+ nir_const_value *offset_const = nir_src_as_const_value(offset_src);
+ const unsigned push_reg_count = gs_prog_data->base.urb_read_length * 8;
+
/* Offset 0 is the VUE header, which contains VARYING_SLOT_LAYER [.y],
* VARYING_SLOT_VIEWPORT [.z], and VARYING_SLOT_PSIZ [.w]. Only
* gl_PointSize is available as a GS input, however, so it must be that.
*/
- const bool is_point_size =
- indirect_offset.file == BAD_FILE && imm_offset == 0;
+ const bool is_point_size = (base_offset == 0);
- nir_const_value *vertex_const = nir_src_as_const_value(vertex_src);
- const unsigned push_reg_count = gs_prog_data->base.urb_read_length * 8;
-
- if (indirect_offset.file == BAD_FILE && vertex_const != NULL &&
- 4 * imm_offset < push_reg_count) {
- imm_offset = 4 * imm_offset + vertex_const->u[0] * push_reg_count;
+ if (offset_const != NULL && vertex_const != NULL &&
+ 4 * (base_offset + offset_const->u[0]) < push_reg_count) {
+ int imm_offset = (base_offset + offset_const->u[0]) * 4 +
+ vertex_const->u[0] * push_reg_count;
/* This input was pushed into registers. */
if (is_point_size) {
/* gl_PointSize comes in .w */
+ assert(imm_offset == 0);
bld.MOV(dst, fs_reg(ATTR, imm_offset + 3, dst.type));
} else {
for (unsigned i = 0; i < num_components; i++) {
@@ -1681,21 +1685,21 @@ fs_visitor::emit_gs_input_load(const fs_reg &dst,
}
fs_inst *inst;
- if (indirect_offset.file == BAD_FILE) {
+ if (offset_const) {
/* Constant indexing - use global offset. */
inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8, dst, icp_handle);
- inst->offset = imm_offset;
+ inst->offset = base_offset + offset_const->u[0];
inst->base_mrf = -1;
inst->mlen = 1;
inst->regs_written = num_components;
} else {
/* Indirect indexing - use per-slot offsets as well. */
- const fs_reg srcs[] = { icp_handle, indirect_offset };
+ const fs_reg srcs[] = { icp_handle, get_nir_src(offset_src) };
fs_reg payload = bld.vgrf(BRW_REGISTER_TYPE_UD, 2);
bld.LOAD_PAYLOAD(payload, srcs, ARRAY_SIZE(srcs), 0);
inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8_PER_SLOT, dst, payload);
- inst->offset = imm_offset;
+ inst->offset = base_offset;
inst->base_mrf = -1;
inst->mlen = 2;
inst->regs_written = num_components;
@@ -1761,17 +1765,12 @@ fs_visitor::nir_emit_gs_intrinsic(const fs_builder &bld,
retype(fs_reg(brw_vec8_grf(2, 0)), BRW_REGISTER_TYPE_UD));
break;
- case nir_intrinsic_load_input_indirect:
case nir_intrinsic_load_input:
unreachable("load_input intrinsics are invalid for the GS stage");
- case nir_intrinsic_load_per_vertex_input_indirect:
- indirect_offset = retype(get_nir_src(instr->src[1]), BRW_REGISTER_TYPE_D);
- /* fallthrough */
case nir_intrinsic_load_per_vertex_input:
- emit_gs_input_load(dest, instr->src[0],
- indirect_offset, instr->const_index[0],
- instr->num_components);
+ emit_gs_input_load(dest, instr->src[0], instr->const_index[0],
+ instr->src[1], instr->num_components);
break;
case nir_intrinsic_emit_vertex_with_counter:
@@ -2091,6 +2090,37 @@ fs_visitor::nir_emit_cs_intrinsic(const fs_builder &bld,
break;
}
+ case nir_intrinsic_shared_atomic_add:
+ nir_emit_shared_atomic(bld, BRW_AOP_ADD, instr);
+ break;
+ case nir_intrinsic_shared_atomic_imin:
+ nir_emit_shared_atomic(bld, BRW_AOP_IMIN, instr);
+ break;
+ case nir_intrinsic_shared_atomic_umin:
+ nir_emit_shared_atomic(bld, BRW_AOP_UMIN, instr);
+ break;
+ case nir_intrinsic_shared_atomic_imax:
+ nir_emit_shared_atomic(bld, BRW_AOP_IMAX, instr);
+ break;
+ case nir_intrinsic_shared_atomic_umax:
+ nir_emit_shared_atomic(bld, BRW_AOP_UMAX, instr);
+ break;
+ case nir_intrinsic_shared_atomic_and:
+ nir_emit_shared_atomic(bld, BRW_AOP_AND, instr);
+ break;
+ case nir_intrinsic_shared_atomic_or:
+ nir_emit_shared_atomic(bld, BRW_AOP_OR, instr);
+ break;
+ case nir_intrinsic_shared_atomic_xor:
+ nir_emit_shared_atomic(bld, BRW_AOP_XOR, instr);
+ break;
+ case nir_intrinsic_shared_atomic_exchange:
+ nir_emit_shared_atomic(bld, BRW_AOP_MOV, instr);
+ break;
+ case nir_intrinsic_shared_atomic_comp_swap:
+ nir_emit_shared_atomic(bld, BRW_AOP_CMPWR, instr);
+ break;
+
default:
nir_emit_intrinsic(bld, instr);
break;
@@ -2104,8 +2134,6 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
if (nir_intrinsic_infos[instr->intrinsic].has_dest)
dest = get_nir_dest(instr->dest);
- bool has_indirect = false;
-
switch (instr->intrinsic) {
case nir_intrinsic_atomic_counter_inc:
case nir_intrinsic_atomic_counter_dec:
@@ -2294,27 +2322,27 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
bld.MOV(retype(dest, BRW_REGISTER_TYPE_D), brw_imm_d(1));
break;
- case nir_intrinsic_load_uniform_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_load_uniform: {
- fs_reg uniform_reg(UNIFORM, instr->const_index[0]);
- uniform_reg.reg_offset = instr->const_index[1];
+ /* Offsets are in bytes but they should always be multiples of 4 */
+ assert(instr->const_index[0] % 4 == 0);
+
+ fs_reg src(UNIFORM, instr->const_index[0] / 4, dest.type);
+
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[0]);
+ if (const_offset) {
+ /* Offsets are in bytes but they should always be multiples of 4 */
+ assert(const_offset->u[0] % 4 == 0);
+ src.reg_offset = const_offset->u[0] / 4;
+ } else {
+ src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));
+ }
for (unsigned j = 0; j < instr->num_components; j++) {
- fs_reg src = offset(retype(uniform_reg, dest.type), bld, j);
- if (has_indirect)
- src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));
-
- bld.MOV(dest, src);
- dest = offset(dest, bld, 1);
+ bld.MOV(offset(dest, bld, j), offset(src, bld, j));
}
break;
}
- case nir_intrinsic_load_ubo_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_load_ubo: {
nir_const_value *const_index = nir_src_as_const_value(instr->src[0]);
fs_reg surf_index;
@@ -2342,27 +2370,24 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
nir->info.num_ubos - 1);
}
- if (has_indirect) {
- /* Turn the byte offset into a dword offset. */
- fs_reg base_offset = vgrf(glsl_type::int_type);
- bld.SHR(base_offset, retype(get_nir_src(instr->src[1]),
- BRW_REGISTER_TYPE_D),
- brw_imm_d(2));
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
+ if (const_offset == NULL) {
+ fs_reg base_offset = retype(get_nir_src(instr->src[1]),
+ BRW_REGISTER_TYPE_D);
- unsigned vec4_offset = instr->const_index[0] / 4;
for (int i = 0; i < instr->num_components; i++)
VARYING_PULL_CONSTANT_LOAD(bld, offset(dest, bld, i), surf_index,
- base_offset, vec4_offset + i);
+ base_offset, i * 4);
} else {
fs_reg packed_consts = vgrf(glsl_type::float_type);
packed_consts.type = dest.type;
- struct brw_reg const_offset_reg = brw_imm_ud(instr->const_index[0] & ~15);
+ struct brw_reg const_offset_reg = brw_imm_ud(const_offset->u[0] & ~15);
bld.emit(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, packed_consts,
surf_index, const_offset_reg);
for (unsigned i = 0; i < instr->num_components; i++) {
- packed_consts.set_smear(instr->const_index[0] % 16 / 4 + i);
+ packed_consts.set_smear(const_offset->u[0] % 16 / 4 + i);
/* The std140 packing rules don't allow vectors to cross 16-byte
* boundaries, and a reg is 32 bytes.
@@ -2376,9 +2401,6 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
break;
}
- case nir_intrinsic_load_ssbo_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_load_ssbo: {
assert(devinfo->gen >= 7);
@@ -2404,12 +2426,12 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
nir->info.num_ssbos - 1);
}
- /* Get the offset to read from */
fs_reg offset_reg;
- if (has_indirect) {
- offset_reg = get_nir_src(instr->src[1]);
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
+ if (const_offset) {
+ offset_reg = brw_imm_ud(const_offset->u[0]);
} else {
- offset_reg = brw_imm_ud(instr->const_index[0]);
+ offset_reg = get_nir_src(instr->src[1]);
}
/* Read the vector */
@@ -2424,32 +2446,101 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
break;
}
- case nir_intrinsic_load_input_indirect:
- has_indirect = true;
- /* fallthrough */
- case nir_intrinsic_load_input: {
- unsigned index = 0;
- for (unsigned j = 0; j < instr->num_components; j++) {
- fs_reg src;
- if (stage == MESA_SHADER_VERTEX) {
- src = offset(fs_reg(ATTR, instr->const_index[0], dest.type), bld, index);
- } else {
- src = offset(retype(nir_inputs, dest.type), bld,
- instr->const_index[0] + index);
- }
- if (has_indirect)
- src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));
- index++;
+ case nir_intrinsic_load_shared: {
+ assert(devinfo->gen >= 7);
- bld.MOV(dest, src);
- dest = offset(dest, bld, 1);
+ fs_reg surf_index = brw_imm_ud(GEN7_BTI_SLM);
+
+ /* Get the offset to read from */
+ fs_reg offset_reg;
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
+ if (const_offset) {
+ offset_reg = brw_imm_ud(instr->const_index[0] + const_offset->u[0]);
+ } else {
+ offset_reg = vgrf(glsl_type::uint_type);
+ bld.ADD(offset_reg,
+ retype(get_nir_src(instr->src[0]), BRW_REGISTER_TYPE_UD),
+ brw_imm_ud(instr->const_index[0]));
+ }
+
+ /* Read the vector */
+ fs_reg read_result = emit_untyped_read(bld, surf_index, offset_reg,
+ 1 /* dims */,
+ instr->num_components,
+ BRW_PREDICATE_NONE);
+ read_result.type = dest.type;
+ for (int i = 0; i < instr->num_components; i++)
+ bld.MOV(offset(dest, bld, i), offset(read_result, bld, i));
+
+ break;
+ }
+
+ case nir_intrinsic_store_shared: {
+ assert(devinfo->gen >= 7);
+
+ /* Block index */
+ fs_reg surf_index = brw_imm_ud(GEN7_BTI_SLM);
+
+ /* Value */
+ fs_reg val_reg = get_nir_src(instr->src[0]);
+
+ /* Writemask */
+ unsigned writemask = instr->const_index[1];
+
+ /* Combine groups of consecutive enabled channels in one write
+ * message. We use ffs to find the first enabled channel and then ffs on
+ * the bit-inverse, down-shifted writemask to determine the length of
+ * the block of enabled bits.
+ */
+ while (writemask) {
+ unsigned first_component = ffs(writemask) - 1;
+ unsigned length = ffs(~(writemask >> first_component)) - 1;
+ fs_reg offset_reg;
+
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
+ if (const_offset) {
+ offset_reg = brw_imm_ud(instr->const_index[0] + const_offset->u[0] +
+ 4 * first_component);
+ } else {
+ offset_reg = vgrf(glsl_type::uint_type);
+ bld.ADD(offset_reg,
+ retype(get_nir_src(instr->src[1]), BRW_REGISTER_TYPE_UD),
+ brw_imm_ud(instr->const_index[0] + 4 * first_component));
+ }
+
+ emit_untyped_write(bld, surf_index, offset_reg,
+ offset(val_reg, bld, first_component),
+ 1 /* dims */, length,
+ BRW_PREDICATE_NONE);
+
+ /* Clear the bits in the writemask that we just wrote, then try
+ * again to see if more channels are left.
+ */
+ writemask &= (15 << (first_component + length));
+ }
+
+ break;
+ }
+
+ case nir_intrinsic_load_input: {
+ fs_reg src;
+ if (stage == MESA_SHADER_VERTEX) {
+ src = fs_reg(ATTR, instr->const_index[0], dest.type);
+ } else {
+ src = offset(retype(nir_inputs, dest.type), bld,
+ instr->const_index[0]);
+ }
+
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[0]);
+ assert(const_offset && "Indirect input loads not allowed");
+ src = offset(src, bld, const_offset->u[0]);
+
+ for (unsigned j = 0; j < instr->num_components; j++) {
+ bld.MOV(offset(dest, bld, j), offset(src, bld, j));
}
break;
}
- case nir_intrinsic_store_ssbo_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_store_ssbo: {
assert(devinfo->gen >= 7);
@@ -2476,7 +2567,7 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
fs_reg val_reg = get_nir_src(instr->src[0]);
/* Writemask */
- unsigned writemask = instr->const_index[1];
+ unsigned writemask = instr->const_index[0];
/* Combine groups of consecutive enabled channels in one write
* message. We use ffs to find the first enabled channel and then ffs on
@@ -2486,10 +2577,11 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
while (writemask) {
unsigned first_component = ffs(writemask) - 1;
unsigned length = ffs(~(writemask >> first_component)) - 1;
- fs_reg offset_reg;
- if (!has_indirect) {
- offset_reg = brw_imm_ud(instr->const_index[0] + 4 * first_component);
+ fs_reg offset_reg;
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[2]);
+ if (const_offset) {
+ offset_reg = brw_imm_ud(const_offset->u[0] + 4 * first_component);
} else {
offset_reg = vgrf(glsl_type::uint_type);
bld.ADD(offset_reg,
@@ -2510,20 +2602,17 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
break;
}
- case nir_intrinsic_store_output_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_store_output: {
fs_reg src = get_nir_src(instr->src[0]);
- unsigned index = 0;
+ fs_reg new_dest = offset(retype(nir_outputs, src.type), bld,
+ instr->const_index[0]);
+
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
+ assert(const_offset && "Indirect output stores not allowed");
+ new_dest = offset(new_dest, bld, const_offset->u[0]);
+
for (unsigned j = 0; j < instr->num_components; j++) {
- fs_reg new_dest = offset(retype(nir_outputs, src.type), bld,
- instr->const_index[0] + index);
- if (has_indirect)
- src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[1]));
- index++;
- bld.MOV(new_dest, src);
- src = offset(src, bld, 1);
+ bld.MOV(offset(new_dest, bld, j), offset(src, bld, j));
}
break;
}
@@ -2646,6 +2735,33 @@ fs_visitor::nir_emit_ssbo_atomic(const fs_builder &bld,
bld.MOV(dest, atomic_result);
}
+void
+fs_visitor::nir_emit_shared_atomic(const fs_builder &bld,
+ int op, nir_intrinsic_instr *instr)
+{
+ fs_reg dest;
+ if (nir_intrinsic_infos[instr->intrinsic].has_dest)
+ dest = get_nir_dest(instr->dest);
+
+ fs_reg surface = brw_imm_ud(GEN7_BTI_SLM);
+ fs_reg offset = get_nir_src(instr->src[0]);
+ fs_reg data1 = get_nir_src(instr->src[1]);
+ fs_reg data2;
+ if (op == BRW_AOP_CMPWR)
+ data2 = get_nir_src(instr->src[2]);
+
+ /* Emit the actual atomic operation operation */
+
+ fs_reg atomic_result =
+ surface_access::emit_untyped_atomic(bld, surface, offset,
+ data1, data2,
+ 1 /* dims */, 1 /* rsize */,
+ op,
+ BRW_PREDICATE_NONE);
+ dest.type = atomic_result.type;
+ bld.MOV(dest, atomic_result);
+}
+
void
fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr)
{
diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
index 1b61f9fe01c..2347cd5d33f 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
@@ -25,10 +25,10 @@
*
*/
+#include "brw_eu.h"
#include "brw_fs.h"
#include "brw_cfg.h"
-#include "glsl/nir/glsl_types.h"
-#include "glsl/ir_optimization.h"
+#include "util/register_allocate.h"
using namespace brw;
@@ -597,6 +597,19 @@ fs_visitor::assign_regs(bool allow_spilling)
}
}
+ /* Certain instructions can't safely use the same register for their
+ * sources and destination. Add interference.
+ */
+ foreach_block_and_inst(block, fs_inst, inst, cfg) {
+ if (inst->dst.file == VGRF && inst->has_source_and_destination_hazard()) {
+ for (unsigned i = 0; i < 3; i++) {
+ if (inst->src[i].file == VGRF) {
+ ra_add_node_interference(g, inst->dst.nr, inst->src[i].nr);
+ }
+ }
+ }
+ }
+
setup_payload_interference(g, payload_node_count, first_payload_node);
if (devinfo->gen >= 7) {
int first_used_mrf = BRW_MAX_MRF(devinfo->gen);
@@ -723,8 +736,15 @@ fs_visitor::emit_unspill(bblock_t *block, fs_inst *inst, fs_reg dst,
.at(block, inst);
for (int i = 0; i < count / reg_size; i++) {
- /* The gen7 descriptor-based offset is 12 bits of HWORD units. */
- bool gen7_read = devinfo->gen >= 7 && spill_offset < (1 << 12) * REG_SIZE;
+ /* The Gen7 descriptor-based offset is 12 bits of HWORD units. Because
+ * the Gen7-style scratch block read is hardwired to BTI 255, on Gen9+
+ * it would cause the DC to do an IA-coherent read, what largely
+ * outweighs the slight advantage from not having to provide the address
+ * as part of the message header, so we're better off using plain old
+ * oword block reads.
+ */
+ bool gen7_read = (devinfo->gen >= 7 && devinfo->gen < 9 &&
+ spill_offset < (1 << 12) * REG_SIZE);
fs_inst *unspill_inst = ibld.emit(gen7_read ?
SHADER_OPCODE_GEN7_SCRATCH_READ :
SHADER_OPCODE_GEN4_SCRATCH_READ,
diff --git a/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp b/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp
index cab5af318a2..0c8ad76aa50 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp
@@ -37,10 +37,8 @@
* behavior we want for the results of texture lookups, but probably not for
*/
-#include "main/core.h"
-#include "brw_context.h"
+#include "main/imports.h"
#include "glsl/ir.h"
-#include "glsl/ir_visitor.h"
#include "glsl/ir_rvalue_visitor.h"
#include "glsl/nir/glsl_types.h"
#include "util/hash_table.h"
@@ -107,6 +105,7 @@ ir_vector_reference_visitor::get_variable_entry(ir_variable *var)
switch (var->data.mode) {
case ir_var_uniform:
case ir_var_shader_storage:
+ case ir_var_shader_shared:
case ir_var_shader_in:
case ir_var_shader_out:
case ir_var_system_value:
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index e82acd141f3..76f0185fdd7 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -27,26 +27,8 @@
* makes it easier to do backend-specific optimizations than doing so
* in the GLSL IR or in the native code.
*/
-#include
-
-#include "main/macros.h"
-#include "main/shaderobj.h"
-#include "program/prog_parameter.h"
-#include "program/prog_print.h"
-#include "program/prog_optimize.h"
-#include "util/register_allocate.h"
-#include "program/hash_table.h"
-#include "brw_context.h"
-#include "brw_eu.h"
-#include "brw_wm.h"
-#include "brw_cs.h"
-#include "brw_vec4.h"
-#include "brw_vec4_gs_visitor.h"
#include "brw_fs.h"
-#include "main/uniforms.h"
#include "glsl/nir/glsl_types.h"
-#include "glsl/ir_optimization.h"
-#include "program/sampler.h"
using namespace brw;
@@ -768,7 +750,6 @@ fs_visitor::emit_urb_writes(const fs_reg &gs_vertex_count)
const int output_vertex_size_owords =
gs_prog_data->output_vertex_size_hwords * 2;
- fs_reg offset;
if (gs_vertex_count.file == IMM) {
per_slot_offsets = brw_imm_ud(output_vertex_size_owords *
gs_vertex_count.ud);
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index 149b43ba055..edb52ac44b7 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -33,6 +33,46 @@
#include "brw_state.h"
#include "brw_ff_gs.h"
#include "brw_nir.h"
+#include "brw_program.h"
+#include "glsl/ir_uniform.h"
+
+static void
+brw_gs_debug_recompile(struct brw_context *brw,
+ struct gl_shader_program *shader_prog,
+ const struct brw_gs_prog_key *key)
+{
+ struct brw_cache_item *c = NULL;
+ const struct brw_gs_prog_key *old_key = NULL;
+ bool found = false;
+
+ perf_debug("Recompiling geometry shader for program %d\n",
+ shader_prog->Name);
+
+ for (unsigned int i = 0; i < brw->cache.size; i++) {
+ for (c = brw->cache.items[i]; c; c = c->next) {
+ if (c->cache_id == BRW_CACHE_GS_PROG) {
+ old_key = c->key;
+
+ if (old_key->program_string_id == key->program_string_id)
+ break;
+ }
+ }
+ if (c)
+ break;
+ }
+
+ if (!c) {
+ perf_debug(" Didn't find previous compile in the shader cache for "
+ "debug\n");
+ return;
+ }
+
+ found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
+
+ if (!found) {
+ perf_debug(" Something else\n");
+ }
+}
static void
assign_gs_binding_table_offsets(const struct brw_device_info *devinfo,
@@ -61,6 +101,9 @@ brw_codegen_gs_prog(struct brw_context *brw,
struct gl_shader *shader = prog->_LinkedShaders[MESA_SHADER_GEOMETRY];
struct brw_stage_state *stage_state = &brw->gs.base;
struct brw_gs_prog_data prog_data;
+ bool start_busy = false;
+ double start_time = 0;
+
memset(&prog_data, 0, sizeof(prog_data));
assign_gs_binding_table_offsets(brw->intelScreen->devinfo, prog,
@@ -75,6 +118,7 @@ brw_codegen_gs_prog(struct brw_context *brw,
* every uniform is a float which gets padded to the size of a vec4.
*/
struct gl_shader *gs = prog->_LinkedShaders[MESA_SHADER_GEOMETRY];
+ struct brw_shader *bgs = (struct brw_shader *) gs;
int param_count = gp->program.Base.nir->num_uniforms;
if (!compiler->scalar_stage[MESA_SHADER_GEOMETRY])
param_count *= 4;
@@ -105,6 +149,11 @@ brw_codegen_gs_prog(struct brw_context *brw,
if (INTEL_DEBUG & DEBUG_SHADER_TIME)
st_index = brw_get_shader_time_index(brw, prog, NULL, ST_GS);
+ if (unlikely(brw->perf_debug)) {
+ start_busy = brw->batch.last_bo && drm_intel_bo_busy(brw->batch.last_bo);
+ start_time = get_time();
+ }
+
void *mem_ctx = ralloc_context(NULL);
unsigned program_size;
char *error_str;
@@ -117,6 +166,17 @@ brw_codegen_gs_prog(struct brw_context *brw,
return false;
}
+ if (unlikely(brw->perf_debug)) {
+ if (bgs->compiled_once) {
+ brw_gs_debug_recompile(brw, prog, key);
+ }
+ if (start_busy && !drm_intel_bo_busy(brw->batch.last_bo)) {
+ perf_debug("GS compile took %.03f ms and stalled the GPU\n",
+ (get_time() - start_time) * 1000);
+ }
+ bgs->compiled_once = true;
+ }
+
/* Scratch space is used for register spilling */
if (prog_data.base.base.total_scratch) {
brw_get_scratch_bo(brw, &stage_state->scratch_bo,
diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h
index 9879f3d6464..13d6be8029b 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_gs.h
@@ -27,15 +27,12 @@
#include
#include "brw_context.h"
-#include "brw_program.h"
#ifdef __cplusplus
extern "C" {
#endif
-struct gl_context;
struct gl_shader_program;
-struct gl_program;
void
brw_upload_gs_prog(struct brw_context *brw);
diff --git a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c
index 76ed237d88a..aa9324164da 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c
@@ -48,11 +48,10 @@ brw_upload_gs_pull_constants(struct brw_context *brw)
/* BRW_NEW_GS_PROG_DATA */
const struct brw_vue_prog_data *prog_data = &brw->gs.prog_data->base;
- const bool dword_pitch = prog_data->dispatch_mode == DISPATCH_MODE_SIMD8;
/* _NEW_PROGRAM_CONSTANTS */
brw_upload_pull_constants(brw, BRW_NEW_GS_CONSTBUF, &gp->program.Base,
- stage_state, &prog_data->base, dword_pitch);
+ stage_state, &prog_data->base);
}
const struct brw_tracked_state brw_gs_pull_constants = {
@@ -79,10 +78,9 @@ brw_upload_gs_ubo_surfaces(struct brw_context *brw)
/* BRW_NEW_GS_PROG_DATA */
struct brw_vue_prog_data *prog_data = &brw->gs.prog_data->base;
- bool dword_pitch = prog_data->dispatch_mode == DISPATCH_MODE_SIMD8;
brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
- &brw->gs.base, &prog_data->base, dword_pitch);
+ &brw->gs.base, &prog_data->base);
}
const struct brw_tracked_state brw_gs_ubo_surfaces = {
diff --git a/src/mesa/drivers/dri/i965/brw_inst.h b/src/mesa/drivers/dri/i965/brw_inst.h
index cd9f6ef591d..0e5f61389df 100644
--- a/src/mesa/drivers/dri/i965/brw_inst.h
+++ b/src/mesa/drivers/dri/i965/brw_inst.h
@@ -39,15 +39,6 @@
extern "C" {
#endif
-/** Maximum SEND message length */
-#define BRW_MAX_MSG_LENGTH 15
-
-/** First MRF register used by pull loads */
-#define FIRST_SPILL_MRF(gen) ((gen) == 6 ? 21 : 13)
-
-/** First MRF register used by spills */
-#define FIRST_PULL_LOAD_MRF(gen) ((gen) == 6 ? 16 : 13)
-
/* brw_context.h has a forward declaration of brw_inst, so name the struct. */
typedef struct brw_inst {
uint64_t data[2];
diff --git a/src/mesa/drivers/dri/i965/brw_ir_fs.h b/src/mesa/drivers/dri/i965/brw_ir_fs.h
index 0410053ce27..c3eec2efb42 100644
--- a/src/mesa/drivers/dri/i965/brw_ir_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_ir_fs.h
@@ -36,7 +36,7 @@ public:
void init();
fs_reg();
- fs_reg(struct brw_reg reg);
+ fs_reg(struct ::brw_reg reg);
fs_reg(enum brw_reg_file file, int nr);
fs_reg(enum brw_reg_file file, int nr, enum brw_reg_type type);
@@ -205,6 +205,7 @@ public:
bool can_do_source_mods(const struct brw_device_info *devinfo);
bool can_change_types() const;
bool has_side_effects() const;
+ bool has_source_and_destination_hazard() const;
bool reads_flag() const;
bool writes_flag() const;
diff --git a/src/mesa/drivers/dri/i965/brw_ir_vec4.h b/src/mesa/drivers/dri/i965/brw_ir_vec4.h
index e2e66044d3a..660becaafa7 100644
--- a/src/mesa/drivers/dri/i965/brw_ir_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_ir_vec4.h
@@ -41,7 +41,7 @@ public:
src_reg(enum brw_reg_file file, int nr, const glsl_type *type);
src_reg();
- src_reg(struct brw_reg reg);
+ src_reg(struct ::brw_reg reg);
bool equals(const src_reg &r) const;
@@ -108,7 +108,7 @@ public:
unsigned writemask);
dst_reg(enum brw_reg_file file, int nr, brw_reg_type type,
unsigned writemask);
- dst_reg(struct brw_reg reg);
+ dst_reg(struct ::brw_reg reg);
dst_reg(class vec4_visitor *v, const struct glsl_type *type);
explicit dst_reg(const src_reg ®);
@@ -169,6 +169,7 @@ public:
void reswizzle(int dst_writemask, int swizzle);
bool can_do_source_mods(const struct brw_device_info *devinfo);
bool can_change_types() const;
+ bool has_source_and_destination_hazard() const;
bool reads_flag()
{
diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp b/src/mesa/drivers/dri/i965/brw_link.cpp
index 14421d421b6..31d29ec9045 100644
--- a/src/mesa/drivers/dri/i965/brw_link.cpp
+++ b/src/mesa/drivers/dri/i965/brw_link.cpp
@@ -21,16 +21,16 @@
* IN THE SOFTWARE.
*/
-#include "main/macros.h"
#include "brw_context.h"
-#include "brw_vs.h"
-#include "brw_gs.h"
+#include "brw_shader.h"
#include "brw_fs.h"
-#include "brw_cfg.h"
#include "brw_nir.h"
+#include "brw_program.h"
#include "glsl/ir_optimization.h"
#include "glsl/glsl_parser_extras.h"
+#include "program/program.h"
#include "main/shaderapi.h"
+#include "main/uniforms.h"
/**
* Performs a compile of the shader stages even when we don't know
@@ -198,7 +198,7 @@ process_glsl_ir(gl_shader_stage stage,
}
}
-GLboolean
+extern "C" GLboolean
brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
{
struct brw_context *brw = brw_context(ctx);
diff --git a/src/mesa/drivers/dri/i965/brw_meta_fast_clear.c b/src/mesa/drivers/dri/i965/brw_meta_fast_clear.c
index 1f8bfdfa492..cf0e56b5244 100644
--- a/src/mesa/drivers/dri/i965/brw_meta_fast_clear.c
+++ b/src/mesa/drivers/dri/i965/brw_meta_fast_clear.c
@@ -41,6 +41,8 @@
#include "main/api_validate.h"
#include "main/state.h"
+#include "util/format_srgb.h"
+
#include "vbo/vbo_context.h"
#include "drivers/common/meta.h"
@@ -48,14 +50,16 @@
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_draw.h"
+#include "brw_state.h"
#include "intel_fbo.h"
#include "intel_batchbuffer.h"
#include "brw_blorp.h"
struct brw_fast_clear_state {
+ struct gl_buffer_object *buf_obj;
+ struct gl_vertex_array_object *array_obj;
GLuint vao;
- GLuint vbo;
GLuint shader_prog;
GLint color_location;
};
@@ -64,11 +68,11 @@ static bool
brw_fast_clear_init(struct brw_context *brw)
{
struct brw_fast_clear_state *clear;
+ struct gl_context *ctx = &brw->ctx;
if (brw->fast_clear_state) {
clear = brw->fast_clear_state;
_mesa_BindVertexArray(clear->vao);
- _mesa_BindBuffer(GL_ARRAY_BUFFER, clear->vbo);
return true;
}
@@ -79,10 +83,21 @@ brw_fast_clear_init(struct brw_context *brw)
memset(clear, 0, sizeof *clear);
_mesa_GenVertexArrays(1, &clear->vao);
_mesa_BindVertexArray(clear->vao);
- _mesa_GenBuffers(1, &clear->vbo);
- _mesa_BindBuffer(GL_ARRAY_BUFFER, clear->vbo);
- _mesa_VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
- _mesa_EnableVertexAttribArray(0);
+
+ clear->buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
+ if (clear->buf_obj == NULL)
+ return false;
+
+ clear->array_obj = _mesa_lookup_vao(ctx, clear->vao);
+ assert(clear->array_obj != NULL);
+
+ _mesa_update_array_format(ctx, clear->array_obj, VERT_ATTRIB_GENERIC(0),
+ 2, GL_FLOAT, GL_RGBA, GL_FALSE, GL_FALSE, GL_FALSE,
+ 0, true);
+ _mesa_bind_vertex_buffer(ctx, clear->array_obj, VERT_ATTRIB_GENERIC(0),
+ clear->buf_obj, 0, sizeof(float) * 2);
+ _mesa_enable_vertex_array_attrib(ctx, clear->array_obj,
+ VERT_ATTRIB_GENERIC(0));
return true;
}
@@ -150,7 +165,7 @@ brw_meta_fast_clear_free(struct brw_context *brw)
_mesa_make_current(&brw->ctx, NULL, NULL);
_mesa_DeleteVertexArrays(1, &clear->vao);
- _mesa_DeleteBuffers(1, &clear->vbo);
+ _mesa_reference_buffer_object(&brw->ctx, &clear->buf_obj, NULL);
_mesa_DeleteProgram(clear->shader_prog);
free(clear);
@@ -165,8 +180,10 @@ struct rect {
};
static void
-brw_draw_rectlist(struct gl_context *ctx, struct rect *rect, int num_instances)
+brw_draw_rectlist(struct brw_context *brw, struct rect *rect, int num_instances)
{
+ struct gl_context *ctx = &brw->ctx;
+ struct brw_fast_clear_state *clear = brw->fast_clear_state;
int start = 0, count = 3;
struct _mesa_prim prim;
float verts[6];
@@ -179,8 +196,8 @@ brw_draw_rectlist(struct gl_context *ctx, struct rect *rect, int num_instances)
verts[5] = rect->y0;
/* upload new vertex data */
- _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
- GL_DYNAMIC_DRAW_ARB);
+ _mesa_buffer_data(ctx, clear->buf_obj, GL_NONE, sizeof(verts), verts,
+ GL_DYNAMIC_DRAW, __func__);
if (ctx->NewState)
_mesa_update_state(ctx);
@@ -410,6 +427,15 @@ set_fast_clear_color(struct brw_context *brw,
override_color.f[3] = 1.0f;
}
+ /* Handle linear→SRGB conversion */
+ if (brw->ctx.Color.sRGBEnabled &&
+ _mesa_get_srgb_format_linear(mt->format) != mt->format) {
+ for (int i = 0; i < 3; i++) {
+ override_color.f[i] =
+ util_format_linear_to_srgb_float(override_color.f[i]);
+ }
+ }
+
if (brw->gen >= 9) {
mt->gen9_fast_clear_color = override_color;
} else {
@@ -480,7 +506,6 @@ fast_clear_attachments(struct brw_context *brw,
struct rect fast_clear_rect)
{
assert(brw->gen >= 9);
- struct gl_context *ctx = &brw->ctx;
brw_bind_rep_write_shader(brw, (float *) fast_clear_color);
@@ -497,7 +522,7 @@ fast_clear_attachments(struct brw_context *brw,
_mesa_meta_drawbuffers_from_bitfield(1 << index);
- brw_draw_rectlist(ctx, &fast_clear_rect, MAX2(1, fb->MaxNumLayers));
+ brw_draw_rectlist(brw, &fast_clear_rect, MAX2(1, fb->MaxNumLayers));
/* Now set the mcs we cleared to INTEL_FAST_CLEAR_STATE_CLEAR so we'll
* resolve them eventually.
@@ -549,11 +574,17 @@ brw_meta_fast_clear(struct brw_context *brw, struct gl_framebuffer *fb,
if (brw->gen < 7)
clear_type = REP_CLEAR;
- /* Certain formats have unresolved issues with sampling from the MCS
- * buffer on Gen9. This disables fast clears altogether for MSRTs until
- * we can figure out what's going on.
+ /* If we're mapping the render format to a different format than the
+ * format we use for texturing then it is a bit questionable whether it
+ * should be possible to use a fast clear. Although we only actually
+ * render using a renderable format, without the override workaround it
+ * wouldn't be possible to have a non-renderable surface in a fast clear
+ * state so the hardware probably legitimately doesn't need to support
+ * this case. At least on Gen9 this really does seem to cause problems.
*/
- if (brw->gen >= 9 && irb->mt->num_samples > 1)
+ if (brw->gen >= 9 &&
+ brw_format_for_mesa_format(irb->mt->format) !=
+ brw->render_target_format[irb->mt->format])
clear_type = REP_CLEAR;
if (irb->mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_NO_MCS)
@@ -694,7 +725,7 @@ brw_meta_fast_clear(struct brw_context *brw, struct gl_framebuffer *fb,
_mesa_meta_drawbuffers_from_bitfield(fast_clear_buffers);
brw_bind_rep_write_shader(brw, (float *) fast_clear_color);
set_fast_clear_op(brw, GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE);
- brw_draw_rectlist(ctx, &fast_clear_rect, layers);
+ brw_draw_rectlist(brw, &fast_clear_rect, layers);
set_fast_clear_op(brw, 0);
/* Now set the mcs we cleared to INTEL_FAST_CLEAR_STATE_CLEAR so we'll
@@ -713,7 +744,7 @@ brw_meta_fast_clear(struct brw_context *brw, struct gl_framebuffer *fb,
if (rep_clear_buffers) {
_mesa_meta_drawbuffers_from_bitfield(rep_clear_buffers);
brw_bind_rep_write_shader(brw, ctx->Color.ClearColor.f);
- brw_draw_rectlist(ctx, &clear_rect, layers);
+ brw_draw_rectlist(brw, &clear_rect, layers);
}
bail_to_meta:
@@ -818,7 +849,7 @@ brw_meta_resolve_color(struct brw_context *brw,
mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
get_resolve_rect(brw, mt, &rect);
- brw_draw_rectlist(ctx, &rect, 1);
+ brw_draw_rectlist(brw, &rect, 1);
set_fast_clear_op(brw, 0);
use_rectlist(brw, false);
diff --git a/src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c b/src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c
index 4e9aa949506..ed471723fcf 100644
--- a/src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c
+++ b/src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c
@@ -286,7 +286,8 @@ setup_program(struct brw_context *brw, bool msaa_tex)
char *fs_source;
const struct sampler_and_fetch *sampler = &samplers[msaa_tex];
- _mesa_meta_setup_vertex_objects(&blit->VAO, &blit->VBO, true, 2, 2, 0);
+ _mesa_meta_setup_vertex_objects(&brw->ctx, &blit->VAO, &blit->buf_obj, true,
+ 2, 2, 0);
GLuint *prog_id = &brw->meta_stencil_blit_programs[msaa_tex];
@@ -294,7 +295,7 @@ setup_program(struct brw_context *brw, bool msaa_tex)
_mesa_UseProgram(*prog_id);
return *prog_id;
}
-
+
fs_source = ralloc_asprintf(NULL, fs_tmpl, sampler->sampler,
sampler->fetch);
_mesa_meta_compile_and_link_program(ctx, vs_source, fs_source,
@@ -306,7 +307,7 @@ setup_program(struct brw_context *brw, bool msaa_tex)
}
/**
- * Samples in stencil buffer are interleaved, and unfortunately the data port
+ * Samples in stencil buffer are interleaved, and unfortunately the data port
* does not support it as render target. Therefore the surface is set up as
* single sampled and the program handles the interleaving.
* In case of single sampled stencil, the render buffer is adjusted with
@@ -372,7 +373,7 @@ adjust_mip_level(const struct intel_mipmap_tree *mt,
}
static void
-prepare_vertex_data(void)
+prepare_vertex_data(struct gl_context *ctx, struct gl_buffer_object *buf_obj)
{
static const struct vertex verts[] = {
{ .x = -1.0f, .y = -1.0f },
@@ -380,7 +381,7 @@ prepare_vertex_data(void)
{ .x = 1.0f, .y = 1.0f },
{ .x = -1.0f, .y = 1.0f } };
- _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ _mesa_buffer_sub_data(ctx, buf_obj, 0, sizeof(verts), verts, __func__);
}
static bool
@@ -460,7 +461,7 @@ brw_meta_stencil_blit(struct brw_context *brw,
_mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_num_samples"),
dst_mt->num_samples);
- prepare_vertex_data();
+ prepare_vertex_data(ctx, ctx->Meta->Blit.buf_obj);
_mesa_set_viewport(ctx, 0, dims.dst_x0, dims.dst_y0,
dims.dst_x1 - dims.dst_x0, dims.dst_y1 - dims.dst_y0);
_mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c
index 10e92735210..fdfc4f661d1 100644
--- a/src/mesa/drivers/dri/i965/brw_nir.c
+++ b/src/mesa/drivers/dri/i965/brw_nir.c
@@ -23,33 +23,50 @@
#include "brw_nir.h"
#include "brw_shader.h"
-#include "glsl/glsl_parser_extras.h"
#include "glsl/nir/glsl_to_nir.h"
+#include "glsl/nir/nir_builder.h"
#include "program/prog_to_nir.h"
-static bool
-remap_vs_attrs(nir_block *block, void *closure)
-{
- GLbitfield64 inputs_read = *((GLbitfield64 *) closure);
+struct remap_vs_attrs_state {
+ nir_builder b;
+ uint64_t inputs_read;
+};
- nir_foreach_instr(block, instr) {
+static bool
+remap_vs_attrs(nir_block *block, void *void_state)
+{
+ struct remap_vs_attrs_state *state = void_state;
+
+ nir_foreach_instr_safe(block, instr) {
if (instr->type != nir_instr_type_intrinsic)
continue;
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
- /* We set EmitNoIndirect for VS inputs, so there are no indirects. */
- assert(intrin->intrinsic != nir_intrinsic_load_input_indirect);
-
if (intrin->intrinsic == nir_intrinsic_load_input) {
/* Attributes come in a contiguous block, ordered by their
* gl_vert_attrib value. That means we can compute the slot
* number for an attribute by masking out the enabled attributes
* before it and counting the bits.
*/
- int attr = intrin->const_index[0];
- int slot = _mesa_bitcount_64(inputs_read & BITFIELD64_MASK(attr));
+ nir_const_value *const_offset = nir_src_as_const_value(intrin->src[0]);
+
+ /* We set EmitNoIndirect for VS inputs, so there are no indirects. */
+ assert(const_offset);
+
+ int attr = intrin->const_index[0] + const_offset->u[0];
+ int slot = _mesa_bitcount_64(state->inputs_read &
+ BITFIELD64_MASK(attr));
+
+ /* The NIR -> FS pass will just add the base and offset together, so
+ * there's no reason to keep them separate. Just put it all in
+ * const_index[0] and set the offset src[0] to load_const(0).
+ */
intrin->const_index[0] = 4 * slot;
+
+ state->b.cursor = nir_before_instr(&intrin->instr);
+ nir_instr_rewrite_src(&intrin->instr, &intrin->src[0],
+ nir_src_for_ssa(nir_imm_int(&state->b, 0)));
}
}
return true;
@@ -62,13 +79,6 @@ brw_nir_lower_inputs(nir_shader *nir,
{
switch (nir->stage) {
case MESA_SHADER_VERTEX:
- /* For now, leave the vec4 backend doing the old method. */
- if (!is_scalar) {
- nir_assign_var_locations(&nir->inputs, &nir->num_inputs,
- type_size_vec4);
- break;
- }
-
/* Start with the location of the variable's base. */
foreach_list_typed(nir_variable, var, node, &nir->inputs) {
var->data.driver_location = var->data.location;
@@ -80,15 +90,25 @@ brw_nir_lower_inputs(nir_shader *nir,
*/
nir_lower_io(nir, nir_var_shader_in, type_size_vec4);
- /* Finally, translate VERT_ATTRIB_* values into the actual registers.
- *
- * Note that we can use nir->info.inputs_read instead of key->inputs_read
- * since the two are identical aside from Gen4-5 edge flag differences.
- */
- GLbitfield64 inputs_read = nir->info.inputs_read;
- nir_foreach_overload(nir, overload) {
- if (overload->impl) {
- nir_foreach_block(overload->impl, remap_vs_attrs, &inputs_read);
+ if (is_scalar) {
+ /* Finally, translate VERT_ATTRIB_* values into the actual registers.
+ *
+ * Note that we can use nir->info.inputs_read instead of
+ * key->inputs_read since the two are identical aside from Gen4-5
+ * edge flag differences.
+ */
+ struct remap_vs_attrs_state remap_state = {
+ .inputs_read = nir->info.inputs_read,
+ };
+
+ /* This pass needs actual constants */
+ nir_opt_constant_folding(nir);
+
+ nir_foreach_overload(nir, overload) {
+ if (overload->impl) {
+ nir_builder_init(&remap_state.b, overload->impl);
+ nir_foreach_block(overload->impl, remap_vs_attrs, &remap_state);
+ }
}
}
break;
@@ -171,12 +191,40 @@ brw_nir_lower_outputs(nir_shader *nir, bool is_scalar)
}
}
+static int
+type_size_scalar_bytes(const struct glsl_type *type)
+{
+ return type_size_scalar(type) * 4;
+}
+
+static int
+type_size_vec4_bytes(const struct glsl_type *type)
+{
+ return type_size_vec4(type) * 16;
+}
+
+static void
+brw_nir_lower_uniforms(nir_shader *nir, bool is_scalar)
+{
+ if (is_scalar) {
+ nir_assign_var_locations(&nir->uniforms, &nir->num_uniforms,
+ type_size_scalar_bytes);
+ nir_lower_io(nir, nir_var_uniform, type_size_scalar_bytes);
+ } else {
+ nir_assign_var_locations(&nir->uniforms, &nir->num_uniforms,
+ type_size_vec4_bytes);
+ nir_lower_io(nir, nir_var_uniform, type_size_vec4_bytes);
+ }
+}
+
+#include "util/debug.h"
+
static bool
should_clone_nir()
{
static int should_clone = -1;
if (should_clone < 1)
- should_clone = brw_env_var_as_boolean("NIR_TEST_CLONE", false);
+ should_clone = env_var_as_boolean("NIR_TEST_CLONE", false);
return should_clone;
}
@@ -298,9 +346,7 @@ brw_lower_nir(nir_shader *nir,
OPT_V(brw_nir_lower_inputs, devinfo, is_scalar);
OPT_V(brw_nir_lower_outputs, is_scalar);
- //nir_assign_var_locations(&nir->uniforms,
- // &nir->num_uniforms,
- // is_scalar ? type_size_scalar : type_size_vec4);
+ //OPT_V(brw_nir_lower_uniforms, is_scalar);
OPT_V(nir_lower_io, nir_var_all, is_scalar ? type_size_scalar : type_size_vec4);
if (shader_prog) {
diff --git a/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp b/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp
index 87b383919df..0849ca40046 100644
--- a/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp
+++ b/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp
@@ -23,19 +23,18 @@
#include "brw_shader.h"
#include "brw_nir.h"
-#include "glsl/ir.h"
#include "glsl/ir_uniform.h"
static void
brw_nir_setup_glsl_builtin_uniform(nir_variable *var,
const struct gl_program *prog,
struct brw_stage_prog_data *stage_prog_data,
- unsigned comps_per_unit)
+ bool is_scalar)
{
const nir_state_slot *const slots = var->state_slots;
assert(var->state_slots != NULL);
- unsigned uniform_index = var->data.driver_location * comps_per_unit;
+ unsigned uniform_index = var->data.driver_location / 4;
for (unsigned int i = 0; i < var->num_state_slots; i++) {
/* This state reference has already been setup by ir_to_mesa, but we'll
* get the same index back here.
@@ -56,7 +55,7 @@ brw_nir_setup_glsl_builtin_uniform(nir_variable *var,
* and move on to the next one. In vec4, we need to continue and pad
* it out to 4 components.
*/
- if (swiz == last_swiz && comps_per_unit == 1)
+ if (swiz == last_swiz && is_scalar)
break;
last_swiz = swiz;
@@ -71,7 +70,7 @@ static void
brw_nir_setup_glsl_uniform(gl_shader_stage stage, nir_variable *var,
struct gl_shader_program *shader_prog,
struct brw_stage_prog_data *stage_prog_data,
- unsigned comps_per_unit)
+ bool is_scalar)
{
int namelen = strlen(var->name);
@@ -81,7 +80,7 @@ brw_nir_setup_glsl_uniform(gl_shader_stage stage, nir_variable *var,
* order we'd walk the type, so walk the list of storage and find anything
* with our name, or the prefix of a component that starts with our name.
*/
- unsigned uniform_index = var->data.driver_location * comps_per_unit;
+ unsigned uniform_index = var->data.driver_location / 4;
for (unsigned u = 0; u < shader_prog->NumUniformStorage; u++) {
struct gl_uniform_storage *storage = &shader_prog->UniformStorage[u];
@@ -112,10 +111,12 @@ brw_nir_setup_glsl_uniform(gl_shader_stage stage, nir_variable *var,
stage_prog_data->param[uniform_index++] = components++;
}
- /* Pad out with zeros if needed (only needed for vec4) */
- for (; i < comps_per_unit; i++) {
- static const gl_constant_value zero = { 0.0 };
- stage_prog_data->param[uniform_index++] = &zero;
+ if (!is_scalar) {
+ /* Pad out with zeros if needed (only needed for vec4) */
+ for (; i < 4; i++) {
+ static const gl_constant_value zero = { 0.0 };
+ stage_prog_data->param[uniform_index++] = &zero;
+ }
}
}
}
@@ -129,8 +130,6 @@ brw_nir_setup_glsl_uniforms(nir_shader *shader,
struct brw_stage_prog_data *stage_prog_data,
bool is_scalar)
{
- unsigned comps_per_unit = is_scalar ? 1 : 4;
-
nir_foreach_variable(var, &shader->uniforms) {
/* UBO's, atomics and samplers don't take up space in the
uniform file */
@@ -139,10 +138,10 @@ brw_nir_setup_glsl_uniforms(nir_shader *shader,
if (strncmp(var->name, "gl_", 3) == 0) {
brw_nir_setup_glsl_builtin_uniform(var, prog, stage_prog_data,
- comps_per_unit);
+ is_scalar);
} else {
brw_nir_setup_glsl_uniform(shader->stage, var, shader_prog,
- stage_prog_data, comps_per_unit);
+ stage_prog_data, is_scalar);
}
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_pipe_control.c b/src/mesa/drivers/dri/i965/brw_pipe_control.c
index a2aef8ad2b6..ae3d8188325 100644
--- a/src/mesa/drivers/dri/i965/brw_pipe_control.c
+++ b/src/mesa/drivers/dri/i965/brw_pipe_control.c
@@ -36,6 +36,7 @@
* - Stall at Pixel Scoreboard
* - Post-Sync Operation
* - Depth Stall
+ * - DC Flush Enable
*
* I chose "Stall at Pixel Scoreboard" since we've used it effectively
* in the past, but the choice is fairly arbitrary.
@@ -49,7 +50,8 @@ gen8_add_cs_stall_workaround_bits(uint32_t *flags)
PIPE_CONTROL_WRITE_DEPTH_COUNT |
PIPE_CONTROL_WRITE_TIMESTAMP |
PIPE_CONTROL_STALL_AT_SCOREBOARD |
- PIPE_CONTROL_DEPTH_STALL;
+ PIPE_CONTROL_DEPTH_STALL |
+ PIPE_CONTROL_DATA_CACHE_INVALIDATE;
/* If we're doing a CS stall, and don't already have one of the
* workaround bits set, add "Stall at Pixel Scoreboard."
diff --git a/src/mesa/drivers/dri/i965/brw_primitive_restart.c b/src/mesa/drivers/dri/i965/brw_primitive_restart.c
index c8d90027ea0..0c3db6b0711 100644
--- a/src/mesa/drivers/dri/i965/brw_primitive_restart.c
+++ b/src/mesa/drivers/dri/i965/brw_primitive_restart.c
@@ -28,6 +28,7 @@
#include "main/imports.h"
#include "main/bufferobj.h"
#include "main/varray.h"
+#include "vbo/vbo.h"
#include "brw_context.h"
#include "brw_defines.h"
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index 3da8e9e8a97..94ceb526762 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -31,8 +31,6 @@
#include
#include "main/imports.h"
-#include "main/enums.h"
-#include "main/shaderobj.h"
#include "program/prog_parameter.h"
#include "program/prog_print.h"
#include "program/program.h"
@@ -41,10 +39,10 @@
#include "util/ralloc.h"
#include "glsl/ir.h"
+#include "brw_program.h"
#include "brw_context.h"
#include "brw_shader.h"
#include "brw_nir.h"
-#include "brw_wm.h"
#include "intel_batchbuffer.h"
static unsigned
@@ -97,6 +95,28 @@ static struct gl_program *brwNewProgram( struct gl_context *ctx,
}
}
+ case GL_TESS_CONTROL_PROGRAM_NV: {
+ struct brw_tess_ctrl_program *prog = CALLOC_STRUCT(brw_tess_ctrl_program);
+ if (prog) {
+ prog->id = get_new_program_id(brw->intelScreen);
+
+ return _mesa_init_gl_program(&prog->program.Base, target, id);
+ } else {
+ return NULL;
+ }
+ }
+
+ case GL_TESS_EVALUATION_PROGRAM_NV: {
+ struct brw_tess_eval_program *prog = CALLOC_STRUCT(brw_tess_eval_program);
+ if (prog) {
+ prog->id = get_new_program_id(brw->intelScreen);
+
+ return _mesa_init_gl_program(&prog->program.Base, target, id);
+ } else {
+ return NULL;
+ }
+ }
+
case GL_COMPUTE_PROGRAM_NV: {
struct brw_compute_program *prog = CALLOC_STRUCT(brw_compute_program);
if (prog) {
diff --git a/src/mesa/drivers/dri/i965/brw_program.h b/src/mesa/drivers/dri/i965/brw_program.h
index f8cf2b062c8..339b8e19ec5 100644
--- a/src/mesa/drivers/dri/i965/brw_program.h
+++ b/src/mesa/drivers/dri/i965/brw_program.h
@@ -30,6 +30,8 @@
extern "C" {
#endif
+struct brw_context;
+
void brw_setup_tex_for_precompile(struct brw_context *brw,
struct brw_sampler_prog_key_data *tex,
struct gl_program *prog);
diff --git a/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp b/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
index 776f75d3e58..60f7fd9cfcd 100644
--- a/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
+++ b/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
@@ -30,8 +30,6 @@
#include "brw_vec4.h"
#include "brw_cfg.h"
#include "brw_shader.h"
-#include "glsl/nir/glsl_types.h"
-#include "glsl/ir_optimization.h"
using namespace brw;
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c
index 872464c4255..5acbf189969 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.c
+++ b/src/mesa/drivers/dri/i965/brw_sf.c
@@ -30,7 +30,6 @@
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/mtypes.h"
#include "main/enums.h"
diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c
index b3ee5c11627..f03b74143f4 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c
@@ -30,7 +30,6 @@
*/
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/enums.h"
@@ -219,7 +218,7 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )
copy_flatshaded_attributes(c, c->vert[0], c->vert[2]);
copy_flatshaded_attributes(c, c->vert[1], c->vert[2]);
}
-
+
static void do_flatshade_line( struct brw_sf_compile *c )
{
@@ -245,7 +244,6 @@ static void do_flatshade_line( struct brw_sf_compile *c )
copy_flatshaded_attributes(c, c->vert[0], c->vert[1]);
}
-
/***********************************************************************
* Triangle setup.
@@ -467,7 +465,7 @@ void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate)
brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2);
brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0));
brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
-
+
/* calculate dA/dy
*/
brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0);
@@ -483,7 +481,7 @@ void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate)
/* Copy m0..m3 to URB. m0 is implicitly copied from r0 in
* the send instruction:
- */
+ */
brw_urb_WRITE(p,
brw_null_reg(),
0,
@@ -544,7 +542,7 @@ void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate)
brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0);
brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
-
+
brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0);
brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
}
@@ -689,7 +687,7 @@ void brw_emit_point_setup(struct brw_sf_compile *c, bool allocate)
bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
if (pc_persp)
- {
+ {
/* This seems odd as the values are all constant, but the
* fragment shader will be expecting it:
*/
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 2f0e8b680ab..d051e124584 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -21,16 +21,14 @@
* IN THE SOFTWARE.
*/
-#include "main/macros.h"
#include "brw_context.h"
-#include "brw_vs.h"
-#include "brw_gs.h"
-#include "brw_fs.h"
#include "brw_cfg.h"
+#include "brw_eu.h"
#include "brw_nir.h"
-#include "glsl/ir_optimization.h"
#include "glsl/glsl_parser_extras.h"
-#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "main/uniforms.h"
+#include "util/debug.h"
static void
shader_debug_log_mesa(void *data, const char *fmt, ...)
@@ -87,7 +85,7 @@ brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo)
compiler->scalar_stage[MESA_SHADER_VERTEX] =
devinfo->gen >= 8 && !(INTEL_DEBUG & DEBUG_VEC4VS);
compiler->scalar_stage[MESA_SHADER_GEOMETRY] =
- devinfo->gen >= 8 && brw_env_var_as_boolean("INTEL_SCALAR_GS", false);
+ devinfo->gen >= 8 && env_var_as_boolean("INTEL_SCALAR_GS", false);
compiler->scalar_stage[MESA_SHADER_FRAGMENT] = true;
compiler->scalar_stage[MESA_SHADER_COMPUTE] = true;
@@ -142,10 +140,13 @@ brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo)
if (compiler->scalar_stage[MESA_SHADER_GEOMETRY])
compiler->glsl_compiler_options[MESA_SHADER_GEOMETRY].EmitNoIndirectInput = false;
+ compiler->glsl_compiler_options[MESA_SHADER_COMPUTE]
+ .LowerShaderSharedVariables = true;
+
return compiler;
}
-struct gl_shader *
+extern "C" struct gl_shader *
brw_new_shader(struct gl_context *ctx, GLuint name, GLuint type)
{
struct brw_shader *shader;
@@ -161,7 +162,7 @@ brw_new_shader(struct gl_context *ctx, GLuint name, GLuint type)
return &shader->base;
}
-void
+extern "C" void
brw_mark_surface_used(struct brw_stage_prog_data *prog_data,
unsigned surf_index)
{
@@ -685,6 +686,13 @@ backend_shader::backend_shader(const struct brw_compiler *compiler,
stage_abbrev = _mesa_shader_stage_to_abbrev(stage);
}
+bool
+backend_reg::equals(const backend_reg &r) const
+{
+ return memcmp((brw_reg *)this, (brw_reg *)&r, sizeof(brw_reg)) == 0 &&
+ reg_offset == r.reg_offset;
+}
+
bool
backend_reg::is_zero() const
{
diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h
index 9555406c777..0b77dc24539 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.h
+++ b/src/mesa/drivers/dri/i965/brw_shader.h
@@ -21,28 +21,41 @@
* IN THE SOFTWARE.
*/
+#pragma once
+
#include
#include "brw_reg.h"
#include "brw_defines.h"
#include "brw_context.h"
-#include "main/compiler.h"
-#include "glsl/ir.h"
-#include "program/prog_parameter.h"
#ifdef __cplusplus
#include "brw_ir_allocator.h"
#endif
-#pragma once
-
#define MAX_SAMPLER_MESSAGE_SIZE 11
#define MAX_VGRF_SIZE 16
#ifdef __cplusplus
-struct backend_reg : public brw_reg
+struct backend_reg : private brw_reg
{
backend_reg() {}
- backend_reg(struct brw_reg reg) : brw_reg(reg) {}
+ backend_reg(const struct brw_reg ®) : brw_reg(reg) {}
+
+ const brw_reg &as_brw_reg() const
+ {
+ assert(file == ARF || file == FIXED_GRF || file == MRF || file == IMM);
+ assert(reg_offset == 0);
+ return static_cast(*this);
+ }
+
+ brw_reg &as_brw_reg()
+ {
+ assert(file == ARF || file == FIXED_GRF || file == MRF || file == IMM);
+ assert(reg_offset == 0);
+ return static_cast(*this);
+ }
+
+ bool equals(const backend_reg &r) const;
bool is_zero() const;
bool is_one() const;
@@ -61,6 +74,25 @@ struct backend_reg : public brw_reg
* For uniforms, this is in units of 1 float.
*/
uint16_t reg_offset;
+
+ using brw_reg::type;
+ using brw_reg::file;
+ using brw_reg::negate;
+ using brw_reg::abs;
+ using brw_reg::address_mode;
+ using brw_reg::subnr;
+ using brw_reg::nr;
+
+ using brw_reg::swizzle;
+ using brw_reg::writemask;
+ using brw_reg::indirect_offset;
+ using brw_reg::vstride;
+ using brw_reg::width;
+ using brw_reg::hstride;
+
+ using brw_reg::f;
+ using brw_reg::d;
+ using brw_reg::ud;
};
#endif
@@ -248,6 +280,9 @@ bool brw_cs_precompile(struct gl_context *ctx,
struct gl_shader_program *shader_prog,
struct gl_program *prog);
+GLboolean brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
+struct gl_shader *brw_new_shader(struct gl_context *ctx, GLuint name, GLuint type);
+
int type_size_scalar(const struct glsl_type *type);
int type_size_vec4(const struct glsl_type *type);
int type_size_vec4_times_4(const struct glsl_type *type);
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 94734bae621..59acec990be 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -127,14 +127,17 @@ extern const struct brw_tracked_state gen6_wm_push_constants;
extern const struct brw_tracked_state gen6_wm_state;
extern const struct brw_tracked_state gen7_depthbuffer;
extern const struct brw_tracked_state gen7_clip_state;
-extern const struct brw_tracked_state gen7_disable_stages;
+extern const struct brw_tracked_state gen7_ds_state;
extern const struct brw_tracked_state gen7_gs_state;
+extern const struct brw_tracked_state gen7_hs_state;
+extern const struct brw_tracked_state gen7_l3_state;
extern const struct brw_tracked_state gen7_ps_state;
extern const struct brw_tracked_state gen7_push_constant_space;
extern const struct brw_tracked_state gen7_sbe_state;
extern const struct brw_tracked_state gen7_sf_clip_viewport;
extern const struct brw_tracked_state gen7_sf_state;
extern const struct brw_tracked_state gen7_sol_state;
+extern const struct brw_tracked_state gen7_te_state;
extern const struct brw_tracked_state gen7_urb;
extern const struct brw_tracked_state gen7_vs_state;
extern const struct brw_tracked_state gen7_wm_state;
@@ -142,7 +145,9 @@ extern const struct brw_tracked_state gen7_hw_binding_tables;
extern const struct brw_tracked_state haswell_cut_index;
extern const struct brw_tracked_state gen8_blend_state;
extern const struct brw_tracked_state gen8_disable_stages;
+extern const struct brw_tracked_state gen8_ds_state;
extern const struct brw_tracked_state gen8_gs_state;
+extern const struct brw_tracked_state gen8_hs_state;
extern const struct brw_tracked_state gen8_index_buffer;
extern const struct brw_tracked_state gen8_multisample_state;
extern const struct brw_tracked_state gen8_pma_fix;
@@ -357,8 +362,7 @@ brw_upload_pull_constants(struct brw_context *brw,
GLbitfield64 brw_new_constbuf,
const struct gl_program *prog,
struct brw_stage_state *stage_state,
- const struct brw_stage_prog_data *prog_data,
- bool dword_pitch);
+ const struct brw_stage_prog_data *prog_data);
/* gen7_vs_state.c */
void
@@ -379,6 +383,10 @@ void gen7_update_binding_table_from_array(struct brw_context *brw,
void gen7_disable_hw_binding_tables(struct brw_context *brw);
void gen7_reset_hw_bt_pool_offsets(struct brw_context *brw);
+/* gen7_l3_state.c */
+void
+gen7_restore_default_l3_config(struct brw_context *brw);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index f7c0a2037d9..cac06fa8918 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -51,6 +51,7 @@
#include "brw_wm.h"
#include "brw_gs.h"
#include "brw_cs.h"
+#include "brw_program.h"
#define FILE_DEBUG_FLAG DEBUG_STATE
diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c
index 0c974c4c807..3d3a6cf943a 100644
--- a/src/mesa/drivers/dri/i965/brw_state_dump.c
+++ b/src/mesa/drivers/dri/i965/brw_state_dump.c
@@ -729,6 +729,12 @@ dump_prog_cache(struct brw_context *brw)
case BRW_CACHE_VS_PROG:
name = "VS kernel";
break;
+ case BRW_CACHE_TCS_PROG:
+ name = "TCS kernel";
+ break;
+ case BRW_CACHE_TES_PROG:
+ name = "TES kernel";
+ break;
case BRW_CACHE_FF_GS_PROG:
name = "Fixed-function GS kernel";
break;
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 6f8daf6d4d2..76bf4024d41 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -186,6 +186,7 @@ static const struct brw_tracked_state *gen7_render_atoms[] =
&brw_cc_vp,
&gen7_sf_clip_viewport,
+ &gen7_l3_state,
&gen7_push_constant_space,
&gen7_urb,
&gen6_blend_state, /* must do before cc unit */
@@ -225,8 +226,10 @@ static const struct brw_tracked_state *gen7_render_atoms[] =
&brw_gs_samplers,
&gen6_multisample_state,
- &gen7_disable_stages,
&gen7_vs_state,
+ &gen7_hs_state,
+ &gen7_te_state,
+ &gen7_ds_state,
&gen7_gs_state,
&gen7_sol_state,
&gen7_clip_state,
@@ -257,6 +260,7 @@ static const struct brw_tracked_state *gen7_render_atoms[] =
static const struct brw_tracked_state *gen7_compute_atoms[] =
{
&brw_state_base_address,
+ &gen7_l3_state,
&brw_cs_image_surfaces,
&gen7_cs_push_constants,
&brw_cs_pull_constants,
@@ -275,6 +279,7 @@ static const struct brw_tracked_state *gen8_render_atoms[] =
&brw_cc_vp,
&gen8_sf_clip_viewport,
+ &gen7_l3_state,
&gen7_push_constant_space,
&gen7_urb,
&gen8_blend_state,
@@ -315,6 +320,9 @@ static const struct brw_tracked_state *gen8_render_atoms[] =
&gen8_disable_stages,
&gen8_vs_state,
+ &gen8_hs_state,
+ &gen7_te_state,
+ &gen8_ds_state,
&gen8_gs_state,
&gen8_sol_state,
&gen6_clip_state,
@@ -352,6 +360,7 @@ static const struct brw_tracked_state *gen8_render_atoms[] =
static const struct brw_tracked_state *gen8_compute_atoms[] =
{
&gen8_state_base_address,
+ &gen7_l3_state,
&brw_cs_image_surfaces,
&gen7_cs_push_constants,
&brw_cs_pull_constants,
@@ -382,7 +391,7 @@ brw_upload_initial_gpu_state(struct brw_context *brw)
BEGIN_BATCH(3);
OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2));
OUT_BATCH(GEN7_CACHE_MODE_1);
- OUT_BATCH((GEN9_PARTIAL_RESOLVE_DISABLE_IN_VC << 16) |
+ OUT_BATCH(REG_MASK(GEN9_PARTIAL_RESOLVE_DISABLE_IN_VC) |
GEN9_PARTIAL_RESOLVE_DISABLE_IN_VC);
ADVANCE_BATCH();
}
@@ -577,14 +586,19 @@ static struct dirty_bit_map brw_bits[] = {
DEFINE_BIT(BRW_NEW_VS_PROG_DATA),
DEFINE_BIT(BRW_NEW_FF_GS_PROG_DATA),
DEFINE_BIT(BRW_NEW_GS_PROG_DATA),
+ DEFINE_BIT(BRW_NEW_TCS_PROG_DATA),
+ DEFINE_BIT(BRW_NEW_TES_PROG_DATA),
DEFINE_BIT(BRW_NEW_CLIP_PROG_DATA),
DEFINE_BIT(BRW_NEW_CS_PROG_DATA),
DEFINE_BIT(BRW_NEW_URB_FENCE),
DEFINE_BIT(BRW_NEW_FRAGMENT_PROGRAM),
DEFINE_BIT(BRW_NEW_GEOMETRY_PROGRAM),
+ DEFINE_BIT(BRW_NEW_TESS_EVAL_PROGRAM),
+ DEFINE_BIT(BRW_NEW_TESS_CTRL_PROGRAM),
DEFINE_BIT(BRW_NEW_VERTEX_PROGRAM),
DEFINE_BIT(BRW_NEW_CURBE_OFFSETS),
DEFINE_BIT(BRW_NEW_REDUCED_PRIMITIVE),
+ DEFINE_BIT(BRW_NEW_PATCH_PRIMITIVE),
DEFINE_BIT(BRW_NEW_PRIMITIVE),
DEFINE_BIT(BRW_NEW_CONTEXT),
DEFINE_BIT(BRW_NEW_PSP),
@@ -618,6 +632,7 @@ static struct dirty_bit_map brw_bits[] = {
DEFINE_BIT(BRW_NEW_VS_ATTRIB_WORKAROUNDS),
DEFINE_BIT(BRW_NEW_COMPUTE_PROGRAM),
DEFINE_BIT(BRW_NEW_CS_WORK_GROUPS),
+ DEFINE_BIT(BRW_NEW_URB_SIZE),
{0, 0, 0}
};
@@ -717,6 +732,16 @@ brw_upload_pipeline_state(struct brw_context *brw,
brw->ctx.NewDriverState |= BRW_NEW_FRAGMENT_PROGRAM;
}
+ if (brw->tess_eval_program != ctx->TessEvalProgram._Current) {
+ brw->tess_eval_program = ctx->TessEvalProgram._Current;
+ brw->ctx.NewDriverState |= BRW_NEW_TESS_EVAL_PROGRAM;
+ }
+
+ if (brw->tess_ctrl_program != ctx->TessCtrlProgram._Current) {
+ brw->tess_ctrl_program = ctx->TessCtrlProgram._Current;
+ brw->ctx.NewDriverState |= BRW_NEW_TESS_CTRL_PROGRAM;
+ }
+
if (brw->geometry_program != ctx->GeometryProgram._Current) {
brw->geometry_program = ctx->GeometryProgram._Current;
brw->ctx.NewDriverState |= BRW_NEW_GEOMETRY_PROGRAM;
diff --git a/src/mesa/drivers/dri/i965/brw_surface_formats.c b/src/mesa/drivers/dri/i965/brw_surface_formats.c
index 69eed4bc629..b7d9078d87d 100644
--- a/src/mesa/drivers/dri/i965/brw_surface_formats.c
+++ b/src/mesa/drivers/dri/i965/brw_surface_formats.c
@@ -20,7 +20,6 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
-#include "main/context.h"
#include "main/mtypes.h"
#include "brw_context.h"
@@ -153,8 +152,8 @@ const struct brw_surface_format_info surface_formats[] = {
SF( Y, 50, Y, x, x, x, x, x, x, x, I32_FLOAT)
SF( Y, 50, Y, x, x, x, x, x, x, x, L32_FLOAT)
SF( Y, 50, Y, x, x, x, x, x, x, x, A32_FLOAT)
- SF( Y, Y, x, Y, x, x, x, x, 60, 90, B8G8R8X8_UNORM)
- SF( Y, Y, x, x, x, x, x, x, x, x, B8G8R8X8_UNORM_SRGB)
+ SF( Y, Y, x, Y, 80, 80, x, x, 60, 90, B8G8R8X8_UNORM)
+ SF( Y, Y, x, x, 80, 80, x, x, x, x, B8G8R8X8_UNORM_SRGB)
SF( Y, Y, x, x, x, x, x, x, x, x, R8G8B8X8_UNORM)
SF( Y, Y, x, x, x, x, x, x, x, x, R8G8B8X8_UNORM_SRGB)
SF( Y, Y, x, x, x, x, x, x, x, x, R9G9B9E5_SHAREDEXP)
@@ -656,9 +655,10 @@ brw_init_surface_formats(struct brw_context *brw)
* mask writes to alpha (ala glColorMask) and reconfigure the
* alpha blending hardware to use GL_ONE (or GL_ZERO) for
* cases where GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is
- * used.
+ * used. On Gen8+ BGRX is actually allowed (but not RGBX).
*/
- render = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+ if (gen < tinfo->render_target)
+ render = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
break;
case BRW_SURFACEFORMAT_R8G8B8X8_UNORM:
render = BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c
index 2cb9aa6503a..7aebac63445 100644
--- a/src/mesa/drivers/dri/i965/brw_tex.c
+++ b/src/mesa/drivers/dri/i965/brw_tex.c
@@ -30,7 +30,6 @@
*/
-#include "main/glheader.h"
#include "main/mtypes.h"
#include "main/teximage.h"
diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c
index 6078c3810d4..a4b8d724cde 100644
--- a/src/mesa/drivers/dri/i965/brw_urb.c
+++ b/src/mesa/drivers/dri/i965/brw_urb.c
@@ -139,11 +139,11 @@ static void recalculate_urb_fence( struct brw_context *brw )
brw->urb.sfsize = sfsize;
brw->urb.vsize = vsize;
- brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
- brw->urb.nr_gs_entries = limits[GS].preferred_nr_entries;
+ brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
+ brw->urb.nr_gs_entries = limits[GS].preferred_nr_entries;
brw->urb.nr_clip_entries = limits[CLP].preferred_nr_entries;
- brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;
- brw->urb.nr_cs_entries = limits[CS].preferred_nr_entries;
+ brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;
+ brw->urb.nr_cs_entries = limits[CS].preferred_nr_entries;
brw->urb.constrained = 0;
@@ -168,18 +168,18 @@ static void recalculate_urb_fence( struct brw_context *brw )
}
if (!check_urb_layout(brw)) {
- brw->urb.nr_vs_entries = limits[VS].min_nr_entries;
- brw->urb.nr_gs_entries = limits[GS].min_nr_entries;
+ brw->urb.nr_vs_entries = limits[VS].min_nr_entries;
+ brw->urb.nr_gs_entries = limits[GS].min_nr_entries;
brw->urb.nr_clip_entries = limits[CLP].min_nr_entries;
- brw->urb.nr_sf_entries = limits[SF].min_nr_entries;
- brw->urb.nr_cs_entries = limits[CS].min_nr_entries;
+ brw->urb.nr_sf_entries = limits[SF].min_nr_entries;
+ brw->urb.nr_cs_entries = limits[CS].min_nr_entries;
/* Mark us as operating with constrained nr_entries, so that next
* time we recalculate we'll resize the fences in the hope of
* escaping constrained mode and getting back to normal performance.
*/
brw->urb.constrained = 1;
-
+
if (!check_urb_layout(brw)) {
/* This is impossible, given the maximal sizes of urb
* entries and the values for minimum nr of entries
@@ -188,7 +188,7 @@ static void recalculate_urb_fence( struct brw_context *brw )
fprintf(stderr, "couldn't calculate URB layout!\n");
exit(1);
}
-
+
if (unlikely(INTEL_DEBUG & (DEBUG_URB|DEBUG_PERF)))
fprintf(stderr, "URB CONSTRAINED\n");
}
diff --git a/src/mesa/drivers/dri/i965/brw_util.c b/src/mesa/drivers/dri/i965/brw_util.c
index e4533f34f1f..934b6b8d627 100644
--- a/src/mesa/drivers/dri/i965/brw_util.c
+++ b/src/mesa/drivers/dri/i965/brw_util.c
@@ -30,10 +30,6 @@
*/
-#include
-
-#include "main/mtypes.h"
-#include "program/prog_parameter.h"
#include "brw_util.h"
#include "brw_defines.h"
diff --git a/src/mesa/drivers/dri/i965/brw_util.h b/src/mesa/drivers/dri/i965/brw_util.h
index 68f4318d371..1f27e9862a7 100644
--- a/src/mesa/drivers/dri/i965/brw_util.h
+++ b/src/mesa/drivers/dri/i965/brw_util.h
@@ -33,8 +33,6 @@
#ifndef BRW_UTIL_H
#define BRW_UTIL_H
-#include "main/mtypes.h"
-#include "main/imports.h"
#include "brw_context.h"
extern GLuint brw_translate_blend_factor( GLenum factor );
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index ae3cf728443..a697bdf84a0 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -28,14 +28,7 @@
#include "brw_nir.h"
#include "brw_vec4_live_variables.h"
#include "brw_dead_control_flow.h"
-
-extern "C" {
-#include "main/macros.h"
-#include "main/shaderobj.h"
-#include "program/prog_print.h"
#include "program/prog_parameter.h"
-}
-#include "main/context.h"
#define MAX_INSTRUCTION (1 << 30)
@@ -71,7 +64,7 @@ src_reg::src_reg()
init();
}
-src_reg::src_reg(struct brw_reg reg) :
+src_reg::src_reg(struct ::brw_reg reg) :
backend_reg(reg)
{
this->reg_offset = 0;
@@ -79,9 +72,8 @@ src_reg::src_reg(struct brw_reg reg) :
}
src_reg::src_reg(const dst_reg ®) :
- backend_reg(static_cast(reg))
+ backend_reg(reg)
{
- this->reg_offset = reg.reg_offset;
this->reladdr = reg.reladdr;
this->swizzle = brw_swizzle_for_mask(reg.writemask);
}
@@ -129,7 +121,7 @@ dst_reg::dst_reg(enum brw_reg_file file, int nr, brw_reg_type type,
this->writemask = writemask;
}
-dst_reg::dst_reg(struct brw_reg reg) :
+dst_reg::dst_reg(struct ::brw_reg reg) :
backend_reg(reg)
{
this->reg_offset = 0;
@@ -137,9 +129,8 @@ dst_reg::dst_reg(struct brw_reg reg) :
}
dst_reg::dst_reg(const src_reg ®) :
- backend_reg(static_cast(reg))
+ backend_reg(reg)
{
- this->reg_offset = reg.reg_offset;
this->writemask = brw_mask_for_swizzle(reg.swizzle);
this->reladdr = reg.reladdr;
}
@@ -147,8 +138,7 @@ dst_reg::dst_reg(const src_reg ®) :
bool
dst_reg::equals(const dst_reg &r) const
{
- return (memcmp((brw_reg *)this, (brw_reg *)&r, sizeof(brw_reg)) == 0 &&
- reg_offset == r.reg_offset &&
+ return (this->backend_reg::equals(r) &&
(reladdr == r.reladdr ||
(reladdr && r.reladdr && reladdr->equals(*r.reladdr))));
}
@@ -171,6 +161,35 @@ vec4_instruction::is_send_from_grf()
}
}
+/**
+ * Returns true if this instruction's sources and destinations cannot
+ * safely be the same register.
+ *
+ * In most cases, a register can be written over safely by the same
+ * instruction that is its last use. For a single instruction, the
+ * sources are dereferenced before writing of the destination starts
+ * (naturally).
+ *
+ * However, there are a few cases where this can be problematic:
+ *
+ * - Virtual opcodes that translate to multiple instructions in the
+ * code generator: if src == dst and one instruction writes the
+ * destination before a later instruction reads the source, then
+ * src will have been clobbered.
+ *
+ * The register allocator uses this information to set up conflicts between
+ * GRF sources and the destination.
+ */
+bool
+vec4_instruction::has_source_and_destination_hazard() const
+{
+ switch (opcode) {
+ /* Most opcodes in the vec4 world use MRFs. */
+ default:
+ return false;
+ }
+}
+
unsigned
vec4_instruction::regs_read(unsigned arg) const
{
@@ -285,8 +304,7 @@ vec4_visitor::implied_mrf_writes(vec4_instruction *inst)
bool
src_reg::equals(const src_reg &r) const
{
- return (memcmp((brw_reg *)this, (brw_reg *)&r, sizeof(brw_reg)) == 0 &&
- reg_offset == r.reg_offset &&
+ return (this->backend_reg::equals(r) &&
!reladdr && !r.reladdr);
}
@@ -587,7 +605,8 @@ vec4_visitor::opt_algebraic()
if (inst->dst.type != inst->src[0].type)
assert(!"unimplemented: saturate mixed types");
- if (brw_saturate_immediate(inst->dst.type, &inst->src[0])) {
+ if (brw_saturate_immediate(inst->dst.type,
+ &inst->src[0].as_brw_reg())) {
inst->saturate = false;
progress = true;
}
@@ -1769,7 +1788,7 @@ vec4_visitor::convert_to_hw_regs()
case ARF:
case FIXED_GRF:
- reg = dst;
+ reg = dst.as_brw_reg();
break;
case BAD_FILE:
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index f94f7128a07..27c72766f2d 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -24,24 +24,11 @@
#ifndef BRW_VEC4_H
#define BRW_VEC4_H
-#include
#include "brw_shader.h"
-#include "main/compiler.h"
-#include "program/hash_table.h"
#include "brw_program.h"
#ifdef __cplusplus
#include "brw_ir_vec4.h"
-
-extern "C" {
-#endif
-
-#include "brw_context.h"
-#include "brw_eu.h"
-#include "intel_asm_annotation.h"
-
-#ifdef __cplusplus
-}; /* extern "C" */
#endif
#include "glsl/ir.h"
@@ -328,7 +315,6 @@ public:
bool is_high_sampler(src_reg sampler);
virtual void emit_nir_code();
- virtual void nir_setup_inputs();
virtual void nir_setup_uniforms();
virtual void nir_setup_system_value_intrinsic(nir_intrinsic_instr *instr);
virtual void nir_setup_system_values();
@@ -361,7 +347,6 @@ public:
dst_reg *nir_locals;
dst_reg *nir_ssa_values;
- src_reg *nir_inputs;
dst_reg *nir_system_values;
protected:
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_cmod_propagation.cpp b/src/mesa/drivers/dri/i965/brw_vec4_cmod_propagation.cpp
index 7aa8f5d9b8f..0c8224f5f83 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_cmod_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_cmod_propagation.cpp
@@ -31,6 +31,7 @@
#include "brw_vec4.h"
#include "brw_cfg.h"
+#include "brw_eu.h"
namespace brw {
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
index 3b76e36a803..c6f0b0d8a2a 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
@@ -31,9 +31,7 @@
#include "brw_vec4.h"
#include "brw_cfg.h"
-extern "C" {
-#include "main/macros.h"
-}
+#include "brw_eu.h"
namespace brw {
@@ -134,14 +132,14 @@ try_constant_propagate(const struct brw_device_info *devinfo,
if (inst->src[arg].abs) {
if ((devinfo->gen >= 8 && is_logic_op(inst->opcode)) ||
- !brw_abs_immediate(value.type, &value)) {
+ !brw_abs_immediate(value.type, &value.as_brw_reg())) {
return false;
}
}
if (inst->src[arg].negate) {
if ((devinfo->gen >= 8 && is_logic_op(inst->opcode)) ||
- !brw_negate_immediate(value.type, &value)) {
+ !brw_negate_immediate(value.type, &value.as_brw_reg())) {
return false;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp b/src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp
index 58aed810fcd..2d0722aa1eb 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp
@@ -71,13 +71,13 @@ vec4_visitor::dead_code_eliminate()
BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
BITSET_WORD *flag_live = ralloc_array(NULL, BITSET_WORD, 1);
- foreach_block(block, cfg) {
+ foreach_block_reverse_safe(block, cfg) {
memcpy(live, live_intervals->block_data[block->num].liveout,
sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout,
sizeof(BITSET_WORD));
- foreach_inst_in_block_reverse(vec4_instruction, inst, block) {
+ foreach_inst_in_block_reverse_safe(vec4_instruction, inst, block) {
if ((inst->dst.file == VGRF && !inst->has_side_effects()) ||
(inst->dst.is_null() && inst->writes_flag())){
bool result_live[4] = { false };
@@ -115,7 +115,7 @@ vec4_visitor::dead_code_eliminate()
inst->dst = dst_reg(retype(brw_null_reg(), inst->dst.type));
} else {
inst->opcode = BRW_OPCODE_NOP;
- continue;
+ break;
}
}
}
@@ -130,7 +130,6 @@ vec4_visitor::dead_code_eliminate()
if (!combined_live) {
inst->opcode = BRW_OPCODE_NOP;
progress = true;
- continue;
}
}
@@ -150,6 +149,11 @@ vec4_visitor::dead_code_eliminate()
BITSET_CLEAR(flag_live, c);
}
+ if (inst->opcode == BRW_OPCODE_NOP) {
+ inst->remove(block);
+ continue;
+ }
+
for (int i = 0; i < 3; i++) {
if (inst->src[i].file == VGRF) {
for (unsigned j = 0; j < inst->regs_read(i); j++) {
@@ -172,15 +176,8 @@ vec4_visitor::dead_code_eliminate()
ralloc_free(live);
ralloc_free(flag_live);
- if (progress) {
- foreach_block_and_inst_safe(block, backend_instruction, inst, cfg) {
- if (inst->opcode == BRW_OPCODE_NOP) {
- inst->remove(block);
- }
- }
-
+ if (progress)
invalidate_live_intervals();
- }
return progress;
}
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
index 432ccb77cc3..205a86d597a 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
@@ -23,6 +23,8 @@
#include "glsl/glsl_parser_extras.h"
#include "brw_vec4.h"
#include "brw_cfg.h"
+#include "brw_eu.h"
+#include "brw_program.h"
using namespace brw;
@@ -364,7 +366,7 @@ generate_gs_urb_write_allocate(struct brw_codegen *p, vec4_instruction *inst)
/* We pass the temporary passed in src0 as the writeback register */
brw_urb_WRITE(p,
- inst->src[0], /* dest */
+ inst->src[0].as_brw_reg(), /* dest */
inst->base_mrf, /* starting mrf reg nr */
src,
BRW_URB_WRITE_ALLOCATE_COMPLETE,
@@ -377,8 +379,8 @@ generate_gs_urb_write_allocate(struct brw_codegen *p, vec4_instruction *inst)
brw_push_insn_state(p);
brw_set_default_access_mode(p, BRW_ALIGN_1);
brw_set_default_mask_control(p, BRW_MASK_DISABLE);
- brw_MOV(p, get_element_ud(inst->dst, 0),
- get_element_ud(inst->src[0], 0));
+ brw_MOV(p, get_element_ud(inst->dst.as_brw_reg(), 0),
+ get_element_ud(inst->src[0].as_brw_reg(), 0));
brw_pop_insn_state(p);
}
@@ -808,7 +810,7 @@ generate_scratch_read(struct brw_codegen *p,
if (devinfo->gen < 6)
brw_inst_set_cond_modifier(devinfo, send, inst->base_mrf);
brw_set_dp_read_message(p, send,
- 255, /* binding table index: stateless access */
+ brw_scratch_surface_idx(p),
BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD,
msg_type,
BRW_DATAPORT_READ_TARGET_RENDER_CACHE,
@@ -881,7 +883,7 @@ generate_scratch_write(struct brw_codegen *p,
if (devinfo->gen < 6)
brw_inst_set_cond_modifier(p->devinfo, send, inst->base_mrf);
brw_set_dp_write_message(p, send,
- 255, /* binding table index: stateless access */
+ brw_scratch_surface_idx(p),
BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD,
msg_type,
3, /* mlen */
@@ -909,8 +911,21 @@ generate_pull_constant_load(struct brw_codegen *p,
gen6_resolve_implied_move(p, &header, inst->base_mrf);
- brw_MOV(p, retype(brw_message_reg(inst->base_mrf + 1), BRW_REGISTER_TYPE_D),
- offset);
+ if (devinfo->gen >= 6) {
+ if (offset.file == BRW_IMMEDIATE_VALUE) {
+ brw_MOV(p, retype(brw_message_reg(inst->base_mrf + 1),
+ BRW_REGISTER_TYPE_D),
+ brw_imm_d(offset.ud >> 4));
+ } else {
+ brw_SHR(p, retype(brw_message_reg(inst->base_mrf + 1),
+ BRW_REGISTER_TYPE_D),
+ offset, brw_imm_d(4));
+ }
+ } else {
+ brw_MOV(p, retype(brw_message_reg(inst->base_mrf + 1),
+ BRW_REGISTER_TYPE_D),
+ offset);
+ }
uint32_t msg_type;
@@ -1067,9 +1082,9 @@ generate_code(struct brw_codegen *p,
annotate(p->devinfo, &annotation, cfg, inst, p->next_insn_offset);
for (unsigned int i = 0; i < 3; i++) {
- src[i] = inst->src[i];
+ src[i] = inst->src[i].as_brw_reg();
}
- dst = inst->dst;
+ dst = inst->dst.as_brw_reg();
brw_set_default_predicate_control(p, inst->predicate);
brw_set_default_predicate_inverse(p, inst->predicate_inverse);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp
index 6bc39473137..6f66978f8e1 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp
@@ -21,7 +21,6 @@
* IN THE SOFTWARE.
*/
-#include "brw_nir.h"
#include "brw_vec4_gs_visitor.h"
namespace brw {
@@ -61,19 +60,19 @@ vec4_gs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
src_reg src;
switch (instr->intrinsic) {
- case nir_intrinsic_load_per_vertex_input_indirect:
- assert(!"EmitNoIndirectInput should prevent this.");
case nir_intrinsic_load_per_vertex_input: {
/* The EmitNoIndirectInput flag guarantees our vertex index will
* be constant. We should handle indirects someday.
*/
nir_const_value *vertex = nir_src_as_const_value(instr->src[0]);
+ nir_const_value *offset = nir_src_as_const_value(instr->src[1]);
/* Make up a type...we have no way of knowing... */
const glsl_type *const type = glsl_type::ivec(instr->num_components);
src = src_reg(ATTR, BRW_VARYING_SLOT_COUNT * vertex->u[0] +
- instr->const_index[0], type);
+ instr->const_index[0] + offset->u[0],
+ type);
dest = get_nir_dest(instr->dest, src.type);
dest.writemask = brw_writemask_for_size(instr->num_components);
emit(MOV(dest, src));
@@ -81,7 +80,6 @@ vec4_gs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
}
case nir_intrinsic_load_input:
- case nir_intrinsic_load_input_indirect:
unreachable("nir_lower_io should have produced per_vertex intrinsics");
case nir_intrinsic_emit_vertex_with_counter: {
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
index 260b515ad42..cf1f82f9d78 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
@@ -25,7 +25,7 @@
#include "brw_vec4.h"
#include "brw_vec4_builder.h"
#include "brw_vec4_surface_builder.h"
-#include "glsl/ir_uniform.h"
+#include "brw_program.h"
using namespace brw;
using namespace brw::surface_access;
@@ -35,9 +35,6 @@ namespace brw {
void
vec4_visitor::emit_nir_code()
{
- if (nir->num_inputs > 0)
- nir_setup_inputs();
-
if (nir->num_uniforms > 0)
nir_setup_uniforms();
@@ -117,28 +114,10 @@ vec4_visitor::nir_setup_system_values()
}
}
-void
-vec4_visitor::nir_setup_inputs()
-{
- nir_inputs = ralloc_array(mem_ctx, src_reg, nir->num_inputs);
- for (unsigned i = 0; i < nir->num_inputs; i++) {
- nir_inputs[i] = src_reg();
- }
-
- nir_foreach_variable(var, &nir->inputs) {
- int offset = var->data.driver_location;
- unsigned size = type_size_vec4(var->type);
- for (unsigned i = 0; i < size; i++) {
- src_reg src = src_reg(ATTR, var->data.location + i, var->type);
- nir_inputs[offset + i] = src;
- }
- }
-}
-
void
vec4_visitor::nir_setup_uniforms()
{
- uniforms = nir->num_uniforms;
+ uniforms = nir->num_uniforms / 16;
nir_foreach_variable(var, &nir->uniforms) {
/* UBO's and atomics don't take up space in the uniform file */
@@ -146,7 +125,7 @@ vec4_visitor::nir_setup_uniforms()
continue;
if (type_size_vec4(var->type) > 0)
- uniform_size[var->data.driver_location] = type_size_vec4(var->type);
+ uniform_size[var->data.driver_location / 16] = type_size_vec4(var->type);
}
}
@@ -390,22 +369,17 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
dst_reg dest;
src_reg src;
- bool has_indirect = false;
-
switch (instr->intrinsic) {
- case nir_intrinsic_load_input_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_load_input: {
- int offset = instr->const_index[0];
- src = nir_inputs[offset];
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[0]);
+
+ /* We set EmitNoIndirectInput for VS */
+ assert(const_offset);
+
+ src = src_reg(ATTR, instr->const_index[0] + const_offset->u[0],
+ glsl_type::uvec4_type);
- if (has_indirect) {
- dest.reladdr = new(mem_ctx) src_reg(get_nir_src(instr->src[0],
- BRW_REGISTER_TYPE_D,
- 1));
- }
dest = get_nir_dest(instr->dest, src.type);
dest.writemask = brw_writemask_for_size(instr->num_components);
@@ -413,22 +387,16 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
break;
}
- case nir_intrinsic_store_output_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_store_output: {
- int varying = instr->const_index[0];
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
+ assert(const_offset);
+
+ int varying = instr->const_index[0] + const_offset->u[0];
src = get_nir_src(instr->src[0], BRW_REGISTER_TYPE_F,
instr->num_components);
- dest = dst_reg(src);
- if (has_indirect) {
- dest.reladdr = new(mem_ctx) src_reg(get_nir_src(instr->src[1],
- BRW_REGISTER_TYPE_D,
- 1));
- }
- output_reg[varying] = dest;
+ output_reg[varying] = dst_reg(src);
break;
}
@@ -458,9 +426,6 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
break;
}
- case nir_intrinsic_store_ssbo_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_store_ssbo: {
assert(devinfo->gen >= 7);
@@ -485,20 +450,19 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
}
/* Offset */
- src_reg offset_reg = src_reg(this, glsl_type::uint_type);
- unsigned const_offset_bytes = 0;
- if (has_indirect) {
- emit(MOV(dst_reg(offset_reg), get_nir_src(instr->src[2], 1)));
+ src_reg offset_reg;
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[2]);
+ if (const_offset) {
+ offset_reg = brw_imm_ud(const_offset->u[0]);
} else {
- const_offset_bytes = instr->const_index[0];
- emit(MOV(dst_reg(offset_reg), brw_imm_ud(const_offset_bytes)));
+ offset_reg = get_nir_src(instr->src[2], 1);
}
/* Value */
src_reg val_reg = get_nir_src(instr->src[0], 4);
/* Writemask */
- unsigned write_mask = instr->const_index[1];
+ unsigned write_mask = instr->const_index[0];
/* IvyBridge does not have a native SIMD4x2 untyped write message so untyped
* writes will use SIMD8 mode. In order to hide this and keep symmetry across
@@ -564,9 +528,8 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
* write at to skip the channels we skipped, if any.
*/
if (skipped_channels > 0) {
- if (!has_indirect) {
- const_offset_bytes += 4 * skipped_channels;
- offset_reg = brw_imm_ud(const_offset_bytes);
+ if (offset_reg.file == IMM) {
+ offset_reg.ud += 4 * skipped_channels;
} else {
emit(ADD(dst_reg(offset_reg), offset_reg,
brw_imm_ud(4 * skipped_channels)));
@@ -601,9 +564,6 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
break;
}
- case nir_intrinsic_load_ssbo_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_load_ssbo: {
assert(devinfo->gen >= 7);
@@ -631,13 +591,12 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
nir->info.num_ssbos - 1);
}
- src_reg offset_reg = src_reg(this, glsl_type::uint_type);
- unsigned const_offset_bytes = 0;
- if (has_indirect) {
- emit(MOV(dst_reg(offset_reg), get_nir_src(instr->src[1], 1)));
+ src_reg offset_reg;
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
+ if (const_offset) {
+ offset_reg = brw_imm_ud(const_offset->u[0]);
} else {
- const_offset_bytes = instr->const_index[0];
- emit(MOV(dst_reg(offset_reg), brw_imm_ud((const_offset_bytes))));
+ offset_reg = get_nir_src(instr->src[1], 1);
}
/* Read the vector */
@@ -700,16 +659,21 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
break;
}
- case nir_intrinsic_load_uniform_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_load_uniform: {
+ /* Offsets are in bytes but they should always be multiples of 16 */
+ assert(instr->const_index[0] % 16 == 0);
+
dest = get_nir_dest(instr->dest);
- src = src_reg(dst_reg(UNIFORM, instr->const_index[0]));
- src.reg_offset = instr->const_index[1];
+ src = src_reg(dst_reg(UNIFORM, instr->const_index[0] / 16));
+ src.type = dest.type;
- if (has_indirect) {
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[0]);
+ if (const_offset) {
+ /* Offsets are in bytes but they should always be multiples of 16 */
+ assert(const_offset->u[0] % 16 == 0);
+ src.reg_offset = const_offset->u[0] / 16;
+ } else {
src_reg tmp = get_nir_src(instr->src[0], BRW_REGISTER_TYPE_D, 1);
src.reladdr = new(mem_ctx) src_reg(tmp);
}
@@ -747,9 +711,6 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
break;
}
- case nir_intrinsic_load_ubo_indirect:
- has_indirect = true;
- /* fallthrough */
case nir_intrinsic_load_ubo: {
nir_const_value *const_block_index = nir_src_as_const_value(instr->src[0]);
src_reg surf_index;
@@ -783,15 +744,12 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
nir->info.num_ubos - 1);
}
- unsigned const_offset = instr->const_index[0];
src_reg offset;
-
- if (!has_indirect) {
- offset = brw_imm_ud(const_offset / 16);
+ nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
+ if (const_offset) {
+ offset = brw_imm_ud(const_offset->u[0] & ~15);
} else {
- offset = src_reg(this, glsl_type::uint_type);
- emit(SHR(dst_reg(offset), get_nir_src(instr->src[1], nir_type_int, 1),
- brw_imm_ud(4u)));
+ offset = get_nir_src(instr->src[1], nir_type_int, 1);
}
src_reg packed_consts = src_reg(this, glsl_type::vec4_type);
@@ -803,10 +761,12 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
NULL, NULL /* before_block/inst */);
packed_consts.swizzle = brw_swizzle_for_size(instr->num_components);
- packed_consts.swizzle += BRW_SWIZZLE4(const_offset % 16 / 4,
- const_offset % 16 / 4,
- const_offset % 16 / 4,
- const_offset % 16 / 4);
+ if (const_offset) {
+ packed_consts.swizzle += BRW_SWIZZLE4(const_offset->u[0] % 16 / 4,
+ const_offset->u[0] % 16 / 4,
+ const_offset->u[0] % 16 / 4,
+ const_offset->u[0] % 16 / 4);
+ }
emit(MOV(dest, packed_consts));
break;
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
index 6d27a4694d3..afc326612a2 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
@@ -21,10 +21,8 @@
* IN THE SOFTWARE.
*/
-#include "main/macros.h"
#include "util/register_allocate.h"
#include "brw_vec4.h"
-#include "brw_vs.h"
#include "brw_cfg.h"
using namespace brw;
@@ -223,6 +221,19 @@ vec4_visitor::reg_allocate()
}
}
+ /* Certain instructions can't safely use the same register for their
+ * sources and destination. Add interference.
+ */
+ foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
+ if (inst->dst.file == VGRF && inst->has_source_and_destination_hazard()) {
+ for (unsigned i = 0; i < 3; i++) {
+ if (inst->src[i].file == VGRF) {
+ ra_add_node_interference(g, inst->dst.nr, inst->src[i].nr);
+ }
+ }
+ }
+ }
+
setup_payload_interference(g, first_payload_node, node_count);
if (!ra_allocate(g)) {
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index caf1ee02bf0..529498be77a 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -23,8 +23,8 @@
#include "brw_vec4.h"
#include "brw_cfg.h"
-#include "glsl/ir_uniform.h"
-#include "program/sampler.h"
+#include "brw_eu.h"
+#include "brw_program.h"
namespace brw {
@@ -1476,24 +1476,16 @@ vec4_visitor::get_pull_constant_offset(bblock_t * block, vec4_instruction *inst,
src_reg index = src_reg(this, glsl_type::int_type);
emit_before(block, inst, ADD(dst_reg(index), *reladdr,
- brw_imm_d(reg_offset)));
-
- /* Pre-gen6, the message header uses byte offsets instead of vec4
- * (16-byte) offset units.
- */
- if (devinfo->gen < 6) {
- emit_before(block, inst, MUL(dst_reg(index), index, brw_imm_d(16)));
- }
+ brw_imm_d(reg_offset * 16)));
return index;
} else if (devinfo->gen >= 8) {
/* Store the offset in a GRF so we can send-from-GRF. */
src_reg offset = src_reg(this, glsl_type::int_type);
- emit_before(block, inst, MOV(dst_reg(offset), brw_imm_d(reg_offset)));
+ emit_before(block, inst, MOV(dst_reg(offset), brw_imm_d(reg_offset * 16)));
return offset;
} else {
- int message_header_scale = devinfo->gen < 6 ? 16 : 1;
- return brw_imm_d(reg_offset * message_header_scale);
+ return brw_imm_d(reg_offset * 16);
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 7c783f66864..59b748f2055 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -39,6 +39,7 @@
#include "program/prog_print.h"
#include "program/prog_parameter.h"
#include "brw_nir.h"
+#include "brw_program.h"
#include "util/ralloc.h"
@@ -219,16 +220,6 @@ brw_codegen_vs_prog(struct brw_context *brw,
return true;
}
-static bool
-key_debug(struct brw_context *brw, const char *name, int a, int b)
-{
- if (a != b) {
- perf_debug(" %s %d->%d\n", name, a, b);
- return true;
- }
- return false;
-}
-
void
brw_vs_debug_recompile(struct brw_context *brw,
struct gl_shader_program *prog,
diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index bcb5e7b0b2a..31ab1ce5766 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -34,10 +34,7 @@
#define BRW_VS_H
-#include "brw_context.h"
-#include "brw_eu.h"
#include "brw_vec4.h"
-#include "program/program.h"
/**
* The VF can't natively handle certain types of attributes, such as GL_FIXED
diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
index d7473845c72..7e8b989ad72 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -53,8 +53,7 @@ brw_upload_pull_constants(struct brw_context *brw,
GLbitfield64 brw_new_constbuf,
const struct gl_program *prog,
struct brw_stage_state *stage_state,
- const struct brw_stage_prog_data *prog_data,
- bool dword_pitch)
+ const struct brw_stage_prog_data *prog_data)
{
unsigned i;
uint32_t surf_index = prog_data->binding_table.pull_constants_start;
@@ -94,8 +93,7 @@ brw_upload_pull_constants(struct brw_context *brw,
}
brw_create_constant_surface(brw, const_bo, const_offset, size,
- &stage_state->surf_offset[surf_index],
- dword_pitch);
+ &stage_state->surf_offset[surf_index]);
drm_intel_bo_unreference(const_bo);
brw->ctx.NewDriverState |= brw_new_constbuf;
@@ -112,7 +110,6 @@ static void
brw_upload_vs_pull_constants(struct brw_context *brw)
{
struct brw_stage_state *stage_state = &brw->vs.base;
- bool dword_pitch;
/* BRW_NEW_VERTEX_PROGRAM */
struct brw_vertex_program *vp =
@@ -121,11 +118,9 @@ brw_upload_vs_pull_constants(struct brw_context *brw)
/* BRW_NEW_VS_PROG_DATA */
const struct brw_stage_prog_data *prog_data = &brw->vs.prog_data->base.base;
- dword_pitch = brw->vs.prog_data->base.dispatch_mode == DISPATCH_MODE_SIMD8;
-
/* _NEW_PROGRAM_CONSTANTS */
brw_upload_pull_constants(brw, BRW_NEW_VS_CONSTBUF, &vp->program.Base,
- stage_state, prog_data, dword_pitch);
+ stage_state, prog_data);
}
const struct brw_tracked_state brw_vs_pull_constants = {
@@ -145,16 +140,13 @@ brw_upload_vs_ubo_surfaces(struct brw_context *brw)
/* _NEW_PROGRAM */
struct gl_shader_program *prog =
ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
- bool dword_pitch;
if (!prog)
return;
/* BRW_NEW_VS_PROG_DATA */
- dword_pitch = brw->vs.prog_data->base.dispatch_mode == DISPATCH_MODE_SIMD8;
brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_VERTEX],
- &brw->vs.base, &brw->vs.prog_data->base.base,
- dword_pitch);
+ &brw->vs.base, &brw->vs.prog_data->base.base);
}
const struct brw_tracked_state brw_vs_ubo_surfaces = {
diff --git a/src/mesa/drivers/dri/i965/brw_vue_map.c b/src/mesa/drivers/dri/i965/brw_vue_map.c
index edb16087410..6cb3da46995 100644
--- a/src/mesa/drivers/dri/i965/brw_vue_map.c
+++ b/src/mesa/drivers/dri/i965/brw_vue_map.c
@@ -40,7 +40,6 @@
*/
-#include "main/compiler.h"
#include "brw_context.h"
static inline void
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 8d9ed3a6c33..39d644ea63a 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -36,6 +36,7 @@
#include "program/program.h"
#include "intel_mipmap_tree.h"
#include "brw_nir.h"
+#include "brw_program.h"
#include "util/ralloc.h"
@@ -179,17 +180,6 @@ brw_codegen_wm_prog(struct brw_context *brw,
return true;
}
-static bool
-key_debug(struct brw_context *brw, const char *name, int a, int b)
-{
- if (a != b) {
- perf_debug(" %s %d->%d\n", name, a, b);
- return true;
- } else {
- return false;
- }
-}
-
bool
brw_debug_recompile_sampler_key(struct brw_context *brw,
const struct brw_sampler_prog_key_data *old_key,
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 53a642ee8bb..7130a61c4f5 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -35,10 +35,8 @@
#include
-#include "program/prog_instruction.h"
#include "brw_context.h"
#include "brw_eu.h"
-#include "brw_program.h"
/* A big lookup table is used to figure out which and how many
* additional regs will inserted before the main payload in the WM
@@ -61,9 +59,6 @@
extern "C" {
#endif
-GLboolean brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
-struct gl_shader *brw_new_shader(struct gl_context *ctx, GLuint name, GLuint type);
-
bool brw_color_buffer_write_enabled(struct brw_context *brw);
bool brw_codegen_wm_prog(struct brw_context *brw,
struct gl_shader_program *prog,
diff --git a/src/mesa/drivers/dri/i965/brw_wm_iz.cpp b/src/mesa/drivers/dri/i965/brw_wm_iz.cpp
index 6f22f294476..83e1855025d 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_iz.cpp
+++ b/src/mesa/drivers/dri/i965/brw_wm_iz.cpp
@@ -30,8 +30,8 @@
*/
-#include "main/mtypes.h"
#include "brw_fs.h"
+#include "brw_wm.h"
#undef P /* prompted depth */
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index f88f8d59196..909db324aec 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -36,6 +36,7 @@
#include "main/samplerobj.h"
#include "main/shaderimage.h"
#include "program/prog_parameter.h"
+#include "program/prog_instruction.h"
#include "main/framebuffer.h"
#include "intel_mipmap_tree.h"
@@ -400,15 +401,11 @@ brw_create_constant_surface(struct brw_context *brw,
drm_intel_bo *bo,
uint32_t offset,
uint32_t size,
- uint32_t *out_offset,
- bool dword_pitch)
+ uint32_t *out_offset)
{
- uint32_t stride = dword_pitch ? 4 : 16;
- uint32_t elements = ALIGN(size, stride) / stride;
-
brw->vtbl.emit_buffer_surface_state(brw, out_offset, bo, offset,
BRW_SURFACEFORMAT_R32G32B32A32_FLOAT,
- elements, stride, false);
+ size, 1, false);
}
/**
@@ -421,8 +418,7 @@ brw_create_buffer_surface(struct brw_context *brw,
drm_intel_bo *bo,
uint32_t offset,
uint32_t size,
- uint32_t *out_offset,
- bool dword_pitch)
+ uint32_t *out_offset)
{
/* Use a raw surface so we can reuse existing untyped read/write/atomic
* messages. We need these specifically for the fragment shader since they
@@ -537,7 +533,7 @@ brw_upload_wm_pull_constants(struct brw_context *brw)
/* _NEW_PROGRAM_CONSTANTS */
brw_upload_pull_constants(brw, BRW_NEW_SURFACES, &fp->program.Base,
- stage_state, prog_data, true);
+ stage_state, prog_data);
}
const struct brw_tracked_state brw_wm_pull_constants = {
@@ -773,7 +769,7 @@ brw_update_renderbuffer_surfaces(struct brw_context *brw,
const uint32_t surf_index = render_target_start + i;
if (intel_renderbuffer(fb->_ColorDrawBuffers[i])) {
- surf_offset[surf_index] =
+ surf_offset[surf_index] =
brw->vtbl.update_renderbuffer_surface(
brw, fb->_ColorDrawBuffers[i],
_mesa_geometric_layers(fb) > 0, i, surf_index);
@@ -918,8 +914,7 @@ void
brw_upload_ubo_surfaces(struct brw_context *brw,
struct gl_shader *shader,
struct brw_stage_state *stage_state,
- struct brw_stage_prog_data *prog_data,
- bool dword_pitch)
+ struct brw_stage_prog_data *prog_data)
{
struct gl_context *ctx = &brw->ctx;
@@ -944,8 +939,7 @@ brw_upload_ubo_surfaces(struct brw_context *brw,
binding->BufferObject->Size - binding->Offset);
brw_create_constant_surface(brw, bo, binding->Offset,
binding->BufferObject->Size - binding->Offset,
- &ubo_surf_offsets[i],
- dword_pitch);
+ &ubo_surf_offsets[i]);
}
}
@@ -967,8 +961,7 @@ brw_upload_ubo_surfaces(struct brw_context *brw,
binding->BufferObject->Size - binding->Offset);
brw_create_buffer_surface(brw, bo, binding->Offset,
binding->BufferObject->Size - binding->Offset,
- &ssbo_surf_offsets[i],
- dword_pitch);
+ &ssbo_surf_offsets[i]);
}
}
@@ -988,7 +981,7 @@ brw_upload_wm_ubo_surfaces(struct brw_context *brw)
/* BRW_NEW_FS_PROG_DATA */
brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
- &brw->wm.base, &brw->wm.prog_data->base, true);
+ &brw->wm.base, &brw->wm.prog_data->base);
}
const struct brw_tracked_state brw_wm_ubo_surfaces = {
@@ -1014,7 +1007,7 @@ brw_upload_cs_ubo_surfaces(struct brw_context *brw)
/* BRW_NEW_CS_PROG_DATA */
brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_COMPUTE],
- &brw->cs.base, &brw->cs.prog_data->base, true);
+ &brw->cs.base, &brw->cs.prog_data->base);
}
const struct brw_tracked_state brw_cs_ubo_surfaces = {
@@ -1060,7 +1053,7 @@ brw_upload_wm_abo_surfaces(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
/* _NEW_PROGRAM */
- struct gl_shader_program *prog = ctx->Shader._CurrentFragmentProgram;
+ struct gl_shader_program *prog = ctx->_Shader->_CurrentFragmentProgram;
if (prog) {
/* BRW_NEW_FS_PROG_DATA */
@@ -1336,7 +1329,7 @@ brw_upload_wm_image_surfaces(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
/* BRW_NEW_FRAGMENT_PROGRAM */
- struct gl_shader_program *prog = ctx->Shader._CurrentFragmentProgram;
+ struct gl_shader_program *prog = ctx->_Shader->_CurrentFragmentProgram;
if (prog) {
/* BRW_NEW_FS_PROG_DATA, BRW_NEW_IMAGE_UNITS, _NEW_TEXTURE */
diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
index 74f3a70a64e..079e1ba25f0 100644
--- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
@@ -24,15 +24,12 @@
#include
#include "intel_batchbuffer.h"
-#include "intel_fbo.h"
#include "intel_mipmap_tree.h"
#include "brw_context.h"
-#include "brw_defines.h"
#include "brw_state.h"
#include "brw_blorp.h"
-#include "gen6_blorp.h"
/**
* \name Constants for BLORP VBO
diff --git a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp
index 3840ce0fe57..9935557ae70 100644
--- a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp
@@ -30,6 +30,7 @@
*/
#include "gen6_gs_visitor.h"
+#include "brw_eu.h"
namespace brw {
diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
index f90e78e43c7..e87b9d1657f 100644
--- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
@@ -24,15 +24,12 @@
#include
#include "intel_batchbuffer.h"
-#include "intel_fbo.h"
#include "intel_mipmap_tree.h"
#include "brw_context.h"
-#include "brw_defines.h"
#include "brw_state.h"
#include "brw_blorp.h"
-#include "gen7_blorp.h"
/* 3DSTATE_URB_VS
diff --git a/src/mesa/drivers/dri/i965/gen7_cs_state.c b/src/mesa/drivers/dri/i965/gen7_cs_state.c
index 2d7c04f4ad2..1fde69cf78e 100644
--- a/src/mesa/drivers/dri/i965/gen7_cs_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_cs_state.c
@@ -30,6 +30,8 @@
#include "intel_mipmap_tree.h"
#include "intel_batchbuffer.h"
#include "brw_state.h"
+#include "program/prog_statevars.h"
+#include "glsl/ir_uniform.h"
static unsigned
get_cs_thread_count(const struct brw_cs_prog_data *cs_prog_data)
@@ -164,8 +166,20 @@ brw_upload_cs_state(struct brw_context *brw)
SET_FIELD(threads, GEN8_MEDIA_GPGPU_THREAD_COUNT) :
SET_FIELD(threads, MEDIA_GPGPU_THREAD_COUNT);
assert(threads <= brw->max_cs_threads);
+
+ assert(prog_data->total_shared <= 64 * 1024);
+ uint32_t slm_size = 0;
+ if (prog_data->total_shared > 0) {
+ /* slm_size is in 4k increments, but must be a power of 2. */
+ slm_size = 4 * 1024;
+ while (slm_size < prog_data->total_shared)
+ slm_size <<= 1;
+ slm_size /= 4 * 1024;
+ }
+
desc[dw++] =
SET_FIELD(cs_prog_data->uses_barrier, MEDIA_BARRIER_ENABLE) |
+ SET_FIELD(slm_size, MEDIA_SHARED_LOCAL_MEMORY_SIZE) |
media_threads;
BEGIN_BATCH(4);
@@ -304,7 +318,7 @@ brw_upload_cs_pull_constants(struct brw_context *brw)
/* _NEW_PROGRAM_CONSTANTS */
brw_upload_pull_constants(brw, BRW_NEW_SURFACES, &cp->program.Base,
- stage_state, prog_data, true);
+ stage_state, prog_data);
}
const struct brw_tracked_state brw_cs_pull_constants = {
diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.h b/src/mesa/drivers/dri/i965/gen7_ds_state.c
similarity index 53%
rename from src/mesa/drivers/dri/i965/gen7_blorp.h
rename to src/mesa/drivers/dri/i965/gen7_ds_state.c
index 64434309f82..79993b6d9f0 100644
--- a/src/mesa/drivers/dri/i965/gen7_blorp.h
+++ b/src/mesa/drivers/dri/i965/gen7_ds_state.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2011 Intel Corporation
+ * 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"),
@@ -17,25 +17,48 @@
* 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, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*/
-#pragma once
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "intel_batchbuffer.h"
-#include
+static void
+gen7_upload_ds_state(struct brw_context *brw)
+{
+ /* Disable the DS Unit */
+ BEGIN_BATCH(7);
+ OUT_BATCH(_3DSTATE_CONSTANT_DS << 16 | (7 - 2));
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
-#ifdef __cplusplus
-extern "C" {
-#endif
+ BEGIN_BATCH(6);
+ OUT_BATCH(_3DSTATE_DS << 16 | (6 - 2));
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
-struct intel_mipmap_tree;
-
-#ifdef __cplusplus
+ BEGIN_BATCH(2);
+ OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS_DS << 16 | (2 - 2));
+ OUT_BATCH(brw->hw_bt_pool.next_offset);
+ ADVANCE_BATCH();
}
-void
-gen7_blorp_exec(struct brw_context *brw,
- const brw_blorp_params *params);
-
-#endif
+const struct brw_tracked_state gen7_ds_state = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_CONTEXT,
+ },
+ .emit = gen7_upload_ds_state,
+};
diff --git a/src/mesa/drivers/dri/i965/gen7_disable.c b/src/mesa/drivers/dri/i965/gen7_hs_state.c
similarity index 67%
rename from src/mesa/drivers/dri/i965/gen7_disable.c
rename to src/mesa/drivers/dri/i965/gen7_hs_state.c
index bb509696d72..ae55f340f52 100644
--- a/src/mesa/drivers/dri/i965/gen7_disable.c
+++ b/src/mesa/drivers/dri/i965/gen7_hs_state.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2011 Intel Corporation
+ * 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"),
@@ -17,8 +17,8 @@
* 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, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*/
#include "brw_context.h"
@@ -27,7 +27,7 @@
#include "intel_batchbuffer.h"
static void
-disable_stages(struct brw_context *brw)
+gen7_upload_hs_state(struct brw_context *brw)
{
/* Disable the HS Unit */
BEGIN_BATCH(7);
@@ -54,45 +54,12 @@ disable_stages(struct brw_context *brw)
OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS_HS << 16 | (2 - 2));
OUT_BATCH(brw->hw_bt_pool.next_offset);
ADVANCE_BATCH();
-
- /* Disable the TE */
- BEGIN_BATCH(4);
- OUT_BATCH(_3DSTATE_TE << 16 | (4 - 2));
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
- /* Disable the DS Unit */
- BEGIN_BATCH(7);
- OUT_BATCH(_3DSTATE_CONSTANT_DS << 16 | (7 - 2));
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
- BEGIN_BATCH(6);
- OUT_BATCH(_3DSTATE_DS << 16 | (6 - 2));
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
- BEGIN_BATCH(2);
- OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS_DS << 16 | (2 - 2));
- OUT_BATCH(brw->hw_bt_pool.next_offset);
- ADVANCE_BATCH();
}
-const struct brw_tracked_state gen7_disable_stages = {
+const struct brw_tracked_state gen7_hs_state = {
.dirty = {
.mesa = 0,
.brw = BRW_NEW_CONTEXT,
},
- .emit = disable_stages,
+ .emit = gen7_upload_hs_state,
};
diff --git a/src/mesa/drivers/dri/i965/gen7_l3_state.c b/src/mesa/drivers/dri/i965/gen7_l3_state.c
new file mode 100644
index 00000000000..b63e61ca8f0
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/gen7_l3_state.c
@@ -0,0 +1,575 @@
+/*
+ * Copyright (c) 2015 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 "brw_context.h"
+#include "brw_defines.h"
+#include "brw_state.h"
+#include "intel_batchbuffer.h"
+
+/**
+ * Chunk of L3 cache reserved for some specific purpose.
+ */
+enum brw_l3_partition {
+ /** Shared local memory. */
+ L3P_SLM = 0,
+ /** Unified return buffer. */
+ L3P_URB,
+ /** Union of DC and RO. */
+ L3P_ALL,
+ /** Data cluster RW partition. */
+ L3P_DC,
+ /** Union of IS, C and T. */
+ L3P_RO,
+ /** Instruction and state cache. */
+ L3P_IS,
+ /** Constant cache. */
+ L3P_C,
+ /** Texture cache. */
+ L3P_T,
+ /** Number of supported L3 partitions. */
+ NUM_L3P
+};
+
+/**
+ * L3 configuration represented as the number of ways allocated for each
+ * partition. \sa get_l3_way_size().
+ */
+struct brw_l3_config {
+ unsigned n[NUM_L3P];
+};
+
+/**
+ * IVB/HSW validated L3 configurations. The first entry will be used as
+ * default by gen7_restore_default_l3_config(), otherwise the ordering is
+ * unimportant.
+ */
+static const struct brw_l3_config ivb_l3_configs[] = {
+ /* SLM URB ALL DC RO IS C T */
+ {{ 0, 32, 0, 0, 32, 0, 0, 0 }},
+ {{ 0, 32, 0, 16, 16, 0, 0, 0 }},
+ {{ 0, 32, 0, 4, 0, 8, 4, 16 }},
+ {{ 0, 28, 0, 8, 0, 8, 4, 16 }},
+ {{ 0, 28, 0, 16, 0, 8, 4, 8 }},
+ {{ 0, 28, 0, 8, 0, 16, 4, 8 }},
+ {{ 0, 28, 0, 0, 0, 16, 4, 16 }},
+ {{ 0, 32, 0, 0, 0, 16, 0, 16 }},
+ {{ 0, 28, 0, 4, 32, 0, 0, 0 }},
+ {{ 16, 16, 0, 16, 16, 0, 0, 0 }},
+ {{ 16, 16, 0, 8, 0, 8, 8, 8 }},
+ {{ 16, 16, 0, 4, 0, 8, 4, 16 }},
+ {{ 16, 16, 0, 4, 0, 16, 4, 8 }},
+ {{ 16, 16, 0, 0, 32, 0, 0, 0 }},
+ {{ 0 }}
+};
+
+/**
+ * VLV validated L3 configurations. \sa ivb_l3_configs.
+ */
+static const struct brw_l3_config vlv_l3_configs[] = {
+ /* SLM URB ALL DC RO IS C T */
+ {{ 0, 64, 0, 0, 32, 0, 0, 0 }},
+ {{ 0, 80, 0, 0, 16, 0, 0, 0 }},
+ {{ 0, 80, 0, 8, 8, 0, 0, 0 }},
+ {{ 0, 64, 0, 16, 16, 0, 0, 0 }},
+ {{ 0, 60, 0, 4, 32, 0, 0, 0 }},
+ {{ 32, 32, 0, 16, 16, 0, 0, 0 }},
+ {{ 32, 40, 0, 8, 16, 0, 0, 0 }},
+ {{ 32, 40, 0, 16, 8, 0, 0, 0 }},
+ {{ 0 }}
+};
+
+/**
+ * BDW validated L3 configurations. \sa ivb_l3_configs.
+ */
+static const struct brw_l3_config bdw_l3_configs[] = {
+ /* SLM URB ALL DC RO IS C T */
+ {{ 0, 48, 48, 0, 0, 0, 0, 0 }},
+ {{ 0, 48, 0, 16, 32, 0, 0, 0 }},
+ {{ 0, 32, 0, 16, 48, 0, 0, 0 }},
+ {{ 0, 32, 0, 0, 64, 0, 0, 0 }},
+ {{ 0, 32, 64, 0, 0, 0, 0, 0 }},
+ {{ 24, 16, 48, 0, 0, 0, 0, 0 }},
+ {{ 24, 16, 0, 16, 32, 0, 0, 0 }},
+ {{ 24, 16, 0, 32, 16, 0, 0, 0 }},
+ {{ 0 }}
+};
+
+/**
+ * CHV/SKL validated L3 configurations. \sa ivb_l3_configs.
+ */
+static const struct brw_l3_config chv_l3_configs[] = {
+ /* SLM URB ALL DC RO IS C T */
+ {{ 0, 48, 48, 0, 0, 0, 0, 0 }},
+ {{ 0, 48, 0, 16, 32, 0, 0, 0 }},
+ {{ 0, 32, 0, 16, 48, 0, 0, 0 }},
+ {{ 0, 32, 0, 0, 64, 0, 0, 0 }},
+ {{ 0, 32, 64, 0, 0, 0, 0, 0 }},
+ {{ 32, 16, 48, 0, 0, 0, 0, 0 }},
+ {{ 32, 16, 0, 16, 32, 0, 0, 0 }},
+ {{ 32, 16, 0, 32, 16, 0, 0, 0 }},
+ {{ 0 }}
+};
+
+/**
+ * Return a zero-terminated array of validated L3 configurations for the
+ * specified device.
+ */
+static const struct brw_l3_config *
+get_l3_configs(const struct brw_device_info *devinfo)
+{
+ switch (devinfo->gen) {
+ case 7:
+ return (devinfo->is_baytrail ? vlv_l3_configs : ivb_l3_configs);
+
+ case 8:
+ return (devinfo->is_cherryview ? chv_l3_configs : bdw_l3_configs);
+
+ case 9:
+ return chv_l3_configs;
+
+ default:
+ unreachable("Not implemented");
+ }
+}
+
+/**
+ * Return the size of an L3 way in KB.
+ */
+static unsigned
+get_l3_way_size(const struct brw_device_info *devinfo)
+{
+ if (devinfo->is_baytrail)
+ return 2;
+
+ else if (devinfo->is_cherryview || devinfo->gt == 1)
+ return 4;
+
+ else
+ return 8 * devinfo->num_slices;
+}
+
+/**
+ * L3 configuration represented as a vector of weights giving the desired
+ * relative size of each partition. The scale is arbitrary, only the ratios
+ * between weights will have an influence on the selection of the closest L3
+ * configuration.
+ */
+struct brw_l3_weights {
+ float w[NUM_L3P];
+};
+
+/**
+ * L1-normalize a vector of L3 partition weights.
+ */
+static struct brw_l3_weights
+norm_l3_weights(struct brw_l3_weights w)
+{
+ float sz = 0;
+
+ for (unsigned i = 0; i < NUM_L3P; i++)
+ sz += w.w[i];
+
+ for (unsigned i = 0; i < NUM_L3P; i++)
+ w.w[i] /= sz;
+
+ return w;
+}
+
+/**
+ * Get the relative partition weights of the specified L3 configuration.
+ */
+static struct brw_l3_weights
+get_config_l3_weights(const struct brw_l3_config *cfg)
+{
+ if (cfg) {
+ struct brw_l3_weights w;
+
+ for (unsigned i = 0; i < NUM_L3P; i++)
+ w.w[i] = cfg->n[i];
+
+ return norm_l3_weights(w);
+ } else {
+ const struct brw_l3_weights w = { { 0 } };
+ return w;
+ }
+}
+
+/**
+ * Distance between two L3 configurations represented as vectors of weights.
+ * Usually just the L1 metric except when the two configurations are
+ * considered incompatible in which case the distance will be infinite. Note
+ * that the compatibility condition is asymmetric -- They will be considered
+ * incompatible whenever the reference configuration \p w0 requires SLM, DC,
+ * or URB but \p w1 doesn't provide it.
+ */
+static float
+diff_l3_weights(struct brw_l3_weights w0, struct brw_l3_weights w1)
+{
+ if ((w0.w[L3P_SLM] && !w1.w[L3P_SLM]) ||
+ (w0.w[L3P_DC] && !w1.w[L3P_DC] && !w1.w[L3P_ALL]) ||
+ (w0.w[L3P_URB] && !w1.w[L3P_URB])) {
+ return HUGE_VALF;
+
+ } else {
+ float dw = 0;
+
+ for (unsigned i = 0; i < NUM_L3P; i++)
+ dw += fabs(w0.w[i] - w1.w[i]);
+
+ return dw;
+ }
+}
+
+/**
+ * Return the closest validated L3 configuration for the specified device and
+ * weight vector.
+ */
+static const struct brw_l3_config *
+get_l3_config(const struct brw_device_info *devinfo, struct brw_l3_weights w0)
+{
+ const struct brw_l3_config *const cfgs = get_l3_configs(devinfo);
+ const struct brw_l3_config *cfg_best = NULL;
+ float dw_best = HUGE_VALF;
+
+ for (const struct brw_l3_config *cfg = cfgs; cfg->n[L3P_URB]; cfg++) {
+ const float dw = diff_l3_weights(w0, get_config_l3_weights(cfg));
+
+ if (dw < dw_best) {
+ cfg_best = cfg;
+ dw_best = dw;
+ }
+ }
+
+ return cfg_best;
+}
+
+/**
+ * Return a reasonable default L3 configuration for the specified device based
+ * on whether SLM and DC are required. In the non-SLM non-DC case the result
+ * is intended to approximately resemble the hardware defaults.
+ */
+static struct brw_l3_weights
+get_default_l3_weights(const struct brw_device_info *devinfo,
+ bool needs_dc, bool needs_slm)
+{
+ struct brw_l3_weights w = {{ 0 }};
+
+ w.w[L3P_SLM] = needs_slm;
+ w.w[L3P_URB] = 1.0;
+
+ if (devinfo->gen >= 8) {
+ w.w[L3P_ALL] = 1.0;
+ } else {
+ w.w[L3P_DC] = needs_dc ? 0.1 : 0;
+ w.w[L3P_RO] = devinfo->is_baytrail ? 0.5 : 1.0;
+ }
+
+ return norm_l3_weights(w);
+}
+
+/**
+ * Calculate the desired L3 partitioning based on the current state of the
+ * pipeline. For now this simply returns the conservative defaults calculated
+ * by get_default_l3_weights(), but we could probably do better by gathering
+ * more statistics from the pipeline state (e.g. guess of expected URB usage
+ * and bound surfaces), or by using feed-back from performance counters.
+ */
+static struct brw_l3_weights
+get_pipeline_state_l3_weights(const struct brw_context *brw)
+{
+ const struct brw_stage_state *stage_states[] = {
+ &brw->vs.base, &brw->gs.base, &brw->wm.base, &brw->cs.base
+ };
+ bool needs_dc = false, needs_slm = false;
+
+ for (unsigned i = 0; i < ARRAY_SIZE(stage_states); i++) {
+ const struct gl_shader_program *prog =
+ brw->ctx._Shader->CurrentProgram[stage_states[i]->stage];
+ const struct brw_stage_prog_data *prog_data = stage_states[i]->prog_data;
+
+ needs_dc |= (prog && prog->NumAtomicBuffers) ||
+ (prog_data && (prog_data->total_scratch || prog_data->nr_image_params));
+ needs_slm |= prog_data && prog_data->total_shared;
+ }
+
+ return get_default_l3_weights(brw->intelScreen->devinfo,
+ needs_dc, needs_slm);
+}
+
+/**
+ * Program the hardware to use the specified L3 configuration.
+ */
+static void
+setup_l3_config(struct brw_context *brw, const struct brw_l3_config *cfg)
+{
+ const bool has_dc = cfg->n[L3P_DC] || cfg->n[L3P_ALL];
+ const bool has_is = cfg->n[L3P_IS] || cfg->n[L3P_RO] || cfg->n[L3P_ALL];
+ const bool has_c = cfg->n[L3P_C] || cfg->n[L3P_RO] || cfg->n[L3P_ALL];
+ const bool has_t = cfg->n[L3P_T] || cfg->n[L3P_RO] || cfg->n[L3P_ALL];
+ const bool has_slm = cfg->n[L3P_SLM];
+
+ /* According to the hardware docs, the L3 partitioning can only be changed
+ * while the pipeline is completely drained and the caches are flushed,
+ * which involves a first PIPE_CONTROL flush which stalls the pipeline and
+ * initiates invalidation of the relevant caches...
+ */
+ brw_emit_pipe_control_flush(brw,
+ PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
+ PIPE_CONTROL_CONST_CACHE_INVALIDATE |
+ PIPE_CONTROL_INSTRUCTION_INVALIDATE |
+ PIPE_CONTROL_DATA_CACHE_INVALIDATE |
+ PIPE_CONTROL_NO_WRITE |
+ PIPE_CONTROL_CS_STALL);
+
+ /* ...followed by a second stalling flush which guarantees that
+ * invalidation is complete when the L3 configuration registers are
+ * modified.
+ */
+ brw_emit_pipe_control_flush(brw,
+ PIPE_CONTROL_DATA_CACHE_INVALIDATE |
+ PIPE_CONTROL_NO_WRITE |
+ PIPE_CONTROL_CS_STALL);
+
+ if (brw->gen >= 8) {
+ assert(!cfg->n[L3P_IS] && !cfg->n[L3P_C] && !cfg->n[L3P_T]);
+
+ BEGIN_BATCH(3);
+ OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2));
+
+ /* Set up the L3 partitioning. */
+ OUT_BATCH(GEN8_L3CNTLREG);
+ OUT_BATCH((has_slm ? GEN8_L3CNTLREG_SLM_ENABLE : 0) |
+ SET_FIELD(cfg->n[L3P_URB], GEN8_L3CNTLREG_URB_ALLOC) |
+ SET_FIELD(cfg->n[L3P_RO], GEN8_L3CNTLREG_RO_ALLOC) |
+ SET_FIELD(cfg->n[L3P_DC], GEN8_L3CNTLREG_DC_ALLOC) |
+ SET_FIELD(cfg->n[L3P_ALL], GEN8_L3CNTLREG_ALL_ALLOC));
+
+ ADVANCE_BATCH();
+
+ } else {
+ assert(!cfg->n[L3P_ALL]);
+
+ /* When enabled SLM only uses a portion of the L3 on half of the banks,
+ * the matching space on the remaining banks has to be allocated to a
+ * client (URB for all validated configurations) set to the
+ * lower-bandwidth 2-bank address hashing mode.
+ */
+ const bool urb_low_bw = has_slm && !brw->is_baytrail;
+ assert(!urb_low_bw || cfg->n[L3P_URB] == cfg->n[L3P_SLM]);
+
+ /* Minimum number of ways that can be allocated to the URB. */
+ const unsigned n0_urb = (brw->is_baytrail ? 32 : 0);
+ assert(cfg->n[L3P_URB] >= n0_urb);
+
+ BEGIN_BATCH(7);
+ OUT_BATCH(MI_LOAD_REGISTER_IMM | (7 - 2));
+
+ /* Demote any clients with no ways assigned to LLC. */
+ OUT_BATCH(GEN7_L3SQCREG1);
+ OUT_BATCH((brw->is_haswell ? HSW_L3SQCREG1_SQGHPCI_DEFAULT :
+ brw->is_baytrail ? VLV_L3SQCREG1_SQGHPCI_DEFAULT :
+ IVB_L3SQCREG1_SQGHPCI_DEFAULT) |
+ (has_dc ? 0 : GEN7_L3SQCREG1_CONV_DC_UC) |
+ (has_is ? 0 : GEN7_L3SQCREG1_CONV_IS_UC) |
+ (has_c ? 0 : GEN7_L3SQCREG1_CONV_C_UC) |
+ (has_t ? 0 : GEN7_L3SQCREG1_CONV_T_UC));
+
+ /* Set up the L3 partitioning. */
+ OUT_BATCH(GEN7_L3CNTLREG2);
+ OUT_BATCH((has_slm ? GEN7_L3CNTLREG2_SLM_ENABLE : 0) |
+ SET_FIELD(cfg->n[L3P_URB] - n0_urb, GEN7_L3CNTLREG2_URB_ALLOC) |
+ (urb_low_bw ? GEN7_L3CNTLREG2_URB_LOW_BW : 0) |
+ SET_FIELD(cfg->n[L3P_ALL], GEN7_L3CNTLREG2_ALL_ALLOC) |
+ SET_FIELD(cfg->n[L3P_RO], GEN7_L3CNTLREG2_RO_ALLOC) |
+ SET_FIELD(cfg->n[L3P_DC], GEN7_L3CNTLREG2_DC_ALLOC));
+ OUT_BATCH(GEN7_L3CNTLREG3);
+ OUT_BATCH(SET_FIELD(cfg->n[L3P_IS], GEN7_L3CNTLREG3_IS_ALLOC) |
+ SET_FIELD(cfg->n[L3P_C], GEN7_L3CNTLREG3_C_ALLOC) |
+ SET_FIELD(cfg->n[L3P_T], GEN7_L3CNTLREG3_T_ALLOC));
+
+ ADVANCE_BATCH();
+
+ if (brw->is_haswell && brw->intelScreen->cmd_parser_version >= 4) {
+ /* Enable L3 atomics on HSW if we have a DC partition, otherwise keep
+ * them disabled to avoid crashing the system hard.
+ */
+ BEGIN_BATCH(5);
+ OUT_BATCH(MI_LOAD_REGISTER_IMM | (5 - 2));
+ OUT_BATCH(HSW_SCRATCH1);
+ OUT_BATCH(has_dc ? 0 : HSW_SCRATCH1_L3_ATOMIC_DISABLE);
+ OUT_BATCH(HSW_ROW_CHICKEN3);
+ OUT_BATCH(REG_MASK(HSW_ROW_CHICKEN3_L3_ATOMIC_DISABLE) |
+ (has_dc ? 0 : HSW_ROW_CHICKEN3_L3_ATOMIC_DISABLE));
+ ADVANCE_BATCH();
+ }
+ }
+}
+
+/**
+ * Return the unit brw_context::urb::size is expressed in, in KB. \sa
+ * brw_device_info::urb::size.
+ */
+static unsigned
+get_urb_size_scale(const struct brw_device_info *devinfo)
+{
+ return (devinfo->gen >= 8 ? devinfo->num_slices : 1);
+}
+
+/**
+ * Update the URB size in the context state for the specified L3
+ * configuration.
+ */
+static void
+update_urb_size(struct brw_context *brw, const struct brw_l3_config *cfg)
+{
+ const struct brw_device_info *devinfo = brw->intelScreen->devinfo;
+ /* From the SKL "L3 Allocation and Programming" documentation:
+ *
+ * "URB is limited to 1008KB due to programming restrictions. This is not
+ * a restriction of the L3 implementation, but of the FF and other clients.
+ * Therefore, in a GT4 implementation it is possible for the programmed
+ * allocation of the L3 data array to provide 3*384KB=1152KB for URB, but
+ * only 1008KB of this will be used."
+ */
+ const unsigned max = (devinfo->gen == 9 ? 1008 : ~0);
+ const unsigned sz =
+ MIN2(max, cfg->n[L3P_URB] * get_l3_way_size(devinfo)) /
+ get_urb_size_scale(devinfo);
+
+ if (brw->urb.size != sz) {
+ brw->urb.size = sz;
+ brw->ctx.NewDriverState |= BRW_NEW_URB_SIZE;
+ }
+}
+
+/**
+ * Print out the specified L3 configuration.
+ */
+static void
+dump_l3_config(const struct brw_l3_config *cfg)
+{
+ fprintf(stderr, "SLM=%d URB=%d ALL=%d DC=%d RO=%d IS=%d C=%d T=%d\n",
+ cfg->n[L3P_SLM], cfg->n[L3P_URB], cfg->n[L3P_ALL],
+ cfg->n[L3P_DC], cfg->n[L3P_RO],
+ cfg->n[L3P_IS], cfg->n[L3P_C], cfg->n[L3P_T]);
+}
+
+static void
+emit_l3_state(struct brw_context *brw)
+{
+ const struct brw_l3_weights w = get_pipeline_state_l3_weights(brw);
+ const float dw = diff_l3_weights(w, get_config_l3_weights(brw->l3.config));
+ /* The distance between any two compatible weight vectors cannot exceed two
+ * due to the triangle inequality.
+ */
+ const float large_dw_threshold = 2.0;
+ /* Somewhat arbitrary, simply makes sure that there will be no repeated
+ * transitions to the same L3 configuration, could probably do better here.
+ */
+ const float small_dw_threshold = 0.5;
+ /* If we're emitting a new batch the caches should already be clean and the
+ * transition should be relatively cheap, so it shouldn't hurt much to use
+ * the smaller threshold. Otherwise use the larger threshold so that we
+ * only reprogram the L3 mid-batch if the most recently programmed
+ * configuration is incompatible with the current pipeline state.
+ */
+ const float dw_threshold = (brw->ctx.NewDriverState & BRW_NEW_BATCH ?
+ small_dw_threshold : large_dw_threshold);
+
+ if (dw > dw_threshold && brw->can_do_pipelined_register_writes) {
+ const struct brw_l3_config *const cfg =
+ get_l3_config(brw->intelScreen->devinfo, w);
+
+ setup_l3_config(brw, cfg);
+ update_urb_size(brw, cfg);
+ brw->l3.config = cfg;
+
+ if (unlikely(INTEL_DEBUG & DEBUG_L3)) {
+ fprintf(stderr, "L3 config transition (%f > %f): ", dw, dw_threshold);
+ dump_l3_config(cfg);
+ }
+ }
+}
+
+const struct brw_tracked_state gen7_l3_state = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_BATCH |
+ BRW_NEW_CS_PROG_DATA |
+ BRW_NEW_FS_PROG_DATA |
+ BRW_NEW_GS_PROG_DATA |
+ BRW_NEW_VS_PROG_DATA,
+ },
+ .emit = emit_l3_state
+};
+
+/**
+ * Hack to restore the default L3 configuration.
+ *
+ * This will be called at the end of every batch in order to reset the L3
+ * configuration to the default values for the time being until the kernel is
+ * fixed. Until kernel commit 6702cf16e0ba8b0129f5aa1b6609d4e9c70bc13b
+ * (included in v4.1) we would set the MI_RESTORE_INHIBIT bit when submitting
+ * batch buffers for the default context used by the DDX, which meant that any
+ * context state changed by the GL would leak into the DDX, the assumption
+ * being that the DDX would initialize any state it cares about manually. The
+ * DDX is however not careful enough to program an L3 configuration
+ * explicitly, and it makes assumptions about it (URB size) which won't hold
+ * and cause it to misrender if we let our L3 set-up to leak into the DDX.
+ *
+ * Since v4.1 of the Linux kernel the default context is saved and restored
+ * normally, so it's far less likely for our L3 programming to interfere with
+ * other contexts -- In fact restoring the default L3 configuration at the end
+ * of the batch will be redundant most of the time. A kind of state leak is
+ * still possible though if the context making assumptions about L3 state is
+ * created immediately after our context was active (e.g. without the DDX
+ * default context being scheduled in between) because at present the DRM
+ * doesn't fully initialize the contents of newly created contexts and instead
+ * sets the MI_RESTORE_INHIBIT flag causing it to inherit the state from the
+ * last active context.
+ *
+ * It's possible to realize such a scenario if, say, an X server (or a GL
+ * application using an outdated non-L3-aware Mesa version) is started while
+ * another GL application is running and happens to have modified the L3
+ * configuration, or if no X server is running at all and a GL application
+ * using a non-L3-aware Mesa version is started after another GL application
+ * ran and modified the L3 configuration -- The latter situation can actually
+ * be reproduced easily on IVB in our CI system.
+ */
+void
+gen7_restore_default_l3_config(struct brw_context *brw)
+{
+ const struct brw_device_info *devinfo = brw->intelScreen->devinfo;
+ /* For efficiency assume that the first entry of the array matches the
+ * default configuration.
+ */
+ const struct brw_l3_config *const cfg = get_l3_configs(devinfo);
+ assert(cfg == get_l3_config(devinfo,
+ get_default_l3_weights(devinfo, false, false)));
+
+ if (cfg != brw->l3.config && brw->can_do_pipelined_register_writes) {
+ setup_l3_config(brw, cfg);
+ update_urb_size(brw, cfg);
+ brw->l3.config = cfg;
+ }
+}
diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.h b/src/mesa/drivers/dri/i965/gen7_te_state.c
similarity index 66%
rename from src/mesa/drivers/dri/i965/gen6_blorp.h
rename to src/mesa/drivers/dri/i965/gen7_te_state.c
index 1b273a49e3a..95a5e98133b 100644
--- a/src/mesa/drivers/dri/i965/gen6_blorp.h
+++ b/src/mesa/drivers/dri/i965/gen7_te_state.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2011 Intel Corporation
+ * 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"),
@@ -17,25 +17,31 @@
* 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, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*/
-#pragma once
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "intel_batchbuffer.h"
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct intel_mipmap_tree;
-
-#ifdef __cplusplus
+static void
+upload_te_state(struct brw_context *brw)
+{
+ /* Disable the TE */
+ BEGIN_BATCH(4);
+ OUT_BATCH(_3DSTATE_TE << 16 | (4 - 2));
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
}
-void
-gen6_blorp_exec(struct brw_context *brw,
- const brw_blorp_params *params);
-
-#endif
+const struct brw_tracked_state gen7_te_state = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_CONTEXT,
+ },
+ .emit = upload_te_state,
+};
diff --git a/src/mesa/drivers/dri/i965/gen7_urb.c b/src/mesa/drivers/dri/i965/gen7_urb.c
index 161de77e156..99a9d3c6500 100644
--- a/src/mesa/drivers/dri/i965/gen7_urb.c
+++ b/src/mesa/drivers/dri/i965/gen7_urb.c
@@ -153,6 +153,7 @@ gen7_upload_urb(struct brw_context *brw)
* skip the rest of the logic.
*/
if (!(brw->ctx.NewDriverState & BRW_NEW_CONTEXT) &&
+ !(brw->ctx.NewDriverState & BRW_NEW_URB_SIZE) &&
brw->urb.vsize == vs_size &&
brw->urb.gs_present == gs_present &&
brw->urb.gsize == gs_size) {
@@ -176,6 +177,7 @@ gen7_upload_urb(struct brw_context *brw)
unsigned chunk_size_bytes = 8192;
/* Determine the size of the URB in chunks.
+ * BRW_NEW_URB_SIZE
*/
unsigned urb_chunks = brw->urb.size * 1024 / chunk_size_bytes;
@@ -314,6 +316,7 @@ const struct brw_tracked_state gen7_urb = {
.dirty = {
.mesa = 0,
.brw = BRW_NEW_CONTEXT |
+ BRW_NEW_URB_SIZE |
BRW_NEW_GEOMETRY_PROGRAM |
BRW_NEW_GS_PROG_DATA |
BRW_NEW_VS_PROG_DATA,
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
index 438caefdd4a..79182560a3d 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
@@ -26,6 +26,7 @@
#include "main/texformat.h"
#include "main/teximage.h"
#include "program/prog_parameter.h"
+#include "program/prog_instruction.h"
#include "intel_mipmap_tree.h"
#include "intel_batchbuffer.h"
@@ -499,7 +500,7 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
/* fallthrough */
default:
surftype = translate_tex_target(gl_target);
- is_array = _mesa_tex_target_is_array(gl_target);
+ is_array = _mesa_is_array_texture(gl_target);
break;
}
diff --git a/src/mesa/drivers/dri/i965/gen8_disable.c b/src/mesa/drivers/dri/i965/gen8_disable.c
index 32508e377c9..6e0dc32bd1e 100644
--- a/src/mesa/drivers/dri/i965/gen8_disable.c
+++ b/src/mesa/drivers/dri/i965/gen8_disable.c
@@ -37,73 +37,6 @@ disable_stages(struct brw_context *brw)
OUT_BATCH(0);
ADVANCE_BATCH();
- /* Disable the HS Unit */
- BEGIN_BATCH(11);
- OUT_BATCH(_3DSTATE_CONSTANT_HS << 16 | (11 - 2));
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
- BEGIN_BATCH(9);
- OUT_BATCH(_3DSTATE_HS << 16 | (9 - 2));
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
- BEGIN_BATCH(2);
- OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS_HS << 16 | (2 - 2));
- OUT_BATCH(brw->hw_bt_pool.next_offset);
- ADVANCE_BATCH();
-
- /* Disable the TE */
- BEGIN_BATCH(4);
- OUT_BATCH(_3DSTATE_TE << 16 | (4 - 2));
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
- /* Disable the DS Unit */
- BEGIN_BATCH(11);
- OUT_BATCH(_3DSTATE_CONSTANT_DS << 16 | (11 - 2));
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
- int ds_pkt_len = brw->gen >= 9 ? 11 : 9;
- BEGIN_BATCH(ds_pkt_len);
- OUT_BATCH(_3DSTATE_DS << 16 | (ds_pkt_len - 2));
- for (int i = 0; i < ds_pkt_len - 1; i++)
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
- BEGIN_BATCH(2);
- OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS_DS << 16 | (2 - 2));
- OUT_BATCH(brw->hw_bt_pool.next_offset);
- ADVANCE_BATCH();
-
BEGIN_BATCH(2);
OUT_BATCH(_3DSTATE_WM_CHROMAKEY << 16 | (2 - 2));
OUT_BATCH(0);
diff --git a/src/mesa/drivers/dri/i965/gen8_draw_upload.c b/src/mesa/drivers/dri/i965/gen8_draw_upload.c
index 1b48643e577..198d612c514 100644
--- a/src/mesa/drivers/dri/i965/gen8_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/gen8_draw_upload.c
@@ -21,7 +21,6 @@
* IN THE SOFTWARE.
*/
-#include "main/glheader.h"
#include "main/bufferobj.h"
#include "main/context.h"
#include "main/enums.h"
diff --git a/src/mesa/drivers/dri/i965/gen8_ds_state.c b/src/mesa/drivers/dri/i965/gen8_ds_state.c
new file mode 100644
index 00000000000..2c0a04de140
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/gen8_ds_state.c
@@ -0,0 +1,66 @@
+/*
+ * 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 "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "intel_batchbuffer.h"
+
+static void
+gen8_upload_ds_state(struct brw_context *brw)
+{
+ /* Disable the DS Unit */
+ BEGIN_BATCH(11);
+ OUT_BATCH(_3DSTATE_CONSTANT_DS << 16 | (11 - 2));
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+
+ int ds_pkt_len = brw->gen >= 9 ? 11 : 9;
+ BEGIN_BATCH(ds_pkt_len);
+ OUT_BATCH(_3DSTATE_DS << 16 | (ds_pkt_len - 2));
+ for (int i = 0; i < ds_pkt_len - 1; i++)
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+
+ BEGIN_BATCH(2);
+ OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS_DS << 16 | (2 - 2));
+ OUT_BATCH(brw->hw_bt_pool.next_offset);
+ ADVANCE_BATCH();
+}
+
+const struct brw_tracked_state gen8_ds_state = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_CONTEXT,
+ },
+ .emit = gen8_upload_ds_state,
+};
diff --git a/src/mesa/drivers/dri/i965/gen8_hs_state.c b/src/mesa/drivers/dri/i965/gen8_hs_state.c
new file mode 100644
index 00000000000..13f70ef0a81
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/gen8_hs_state.c
@@ -0,0 +1,71 @@
+/*
+ * 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 "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "intel_batchbuffer.h"
+
+static void
+gen8_upload_hs_state(struct brw_context *brw)
+{
+ /* Disable the HS Unit */
+ BEGIN_BATCH(11);
+ OUT_BATCH(_3DSTATE_CONSTANT_HS << 16 | (11 - 2));
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+
+ BEGIN_BATCH(9);
+ OUT_BATCH(_3DSTATE_HS << 16 | (9 - 2));
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+
+ BEGIN_BATCH(2);
+ OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS_HS << 16 | (2 - 2));
+ OUT_BATCH(brw->hw_bt_pool.next_offset);
+ ADVANCE_BATCH();
+}
+
+const struct brw_tracked_state gen8_hs_state = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_CONTEXT,
+ },
+ .emit = gen8_upload_hs_state,
+};
diff --git a/src/mesa/drivers/dri/i965/gen8_ps_state.c b/src/mesa/drivers/dri/i965/gen8_ps_state.c
index 10e433b1d59..945f7106e3d 100644
--- a/src/mesa/drivers/dri/i965/gen8_ps_state.c
+++ b/src/mesa/drivers/dri/i965/gen8_ps_state.c
@@ -194,7 +194,7 @@ gen8_upload_ps_state(struct brw_context *brw,
const unsigned sampler_count =
DIV_ROUND_UP(CLAMP(stage_state->sampler_count, 0, 16), 4);
- dw3 |= SET_FIELD(sampler_count, GEN7_PS_SAMPLER_COUNT);
+ dw3 |= SET_FIELD(sampler_count, GEN7_PS_SAMPLER_COUNT);
/* BRW_NEW_FS_PROG_DATA */
dw3 |=
diff --git a/src/mesa/drivers/dri/i965/gen8_surface_state.c b/src/mesa/drivers/dri/i965/gen8_surface_state.c
index 9cdd1c71b4d..b062bf08aaf 100644
--- a/src/mesa/drivers/dri/i965/gen8_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen8_surface_state.c
@@ -27,6 +27,7 @@
#include "main/texformat.h"
#include "main/teximage.h"
#include "program/prog_parameter.h"
+#include "program/prog_instruction.h"
#include "intel_mipmap_tree.h"
#include "intel_batchbuffer.h"
@@ -272,7 +273,7 @@ gen8_emit_texture_surface_state(struct brw_context *brw,
format == BRW_SURFACEFORMAT_BC7_UNORM))
surf[0] |= GEN8_SURFACE_SAMPLER_L2_BYPASS_DISABLE;
- if (_mesa_is_array_texture(target) || target == GL_TEXTURE_CUBE_MAP)
+ if (_mesa_is_array_texture(mt->target) || mt->target == GL_TEXTURE_CUBE_MAP)
surf[0] |= GEN8_SURFACE_IS_ARRAY;
surf[1] = SET_FIELD(mocs_wb, GEN8_SURFACE_MOCS) | mt->qpitch >> 2;
@@ -451,7 +452,7 @@ gen8_update_renderbuffer_surface(struct brw_context *brw,
/* fallthrough */
default:
surf_type = translate_tex_target(gl_target);
- is_array = _mesa_tex_target_is_array(gl_target);
+ is_array = _mesa_is_array_texture(mt->target);
break;
}
diff --git a/src/mesa/drivers/dri/i965/intel_asm_annotation.c b/src/mesa/drivers/dri/i965/intel_asm_annotation.c
index fdd605a7db0..59cc863268f 100644
--- a/src/mesa/drivers/dri/i965/intel_asm_annotation.c
+++ b/src/mesa/drivers/dri/i965/intel_asm_annotation.c
@@ -121,24 +121,6 @@ void annotate(const struct brw_device_info *devinfo,
ann->block_start = cfg->blocks[annotation->cur_block];
}
- if (bblock_end(cfg->blocks[annotation->cur_block]) == inst) {
- ann->block_end = cfg->blocks[annotation->cur_block];
- annotation->cur_block++;
- }
-
- /* Merge this annotation with the previous if possible. */
- struct annotation *prev = annotation->ann_count > 1 ?
- &annotation->ann[annotation->ann_count - 2] : NULL;
- if (prev != NULL &&
- ann->ir == prev->ir &&
- ann->annotation == prev->annotation &&
- ann->block_start == NULL &&
- prev->block_end == NULL) {
- if (ann->block_end == NULL)
- annotation->ann_count--;
- return;
- }
-
/* There is no hardware DO instruction on Gen6+, so since DO always
* starts a basic block, we need to set the .block_start of the next
* instruction's annotation with a pointer to the bblock started by
@@ -150,6 +132,11 @@ void annotate(const struct brw_device_info *devinfo,
if (devinfo->gen >= 6 && inst->opcode == BRW_OPCODE_DO) {
annotation->ann_count--;
}
+
+ if (bblock_end(cfg->blocks[annotation->cur_block]) == inst) {
+ ann->block_end = cfg->blocks[annotation->cur_block];
+ annotation->cur_block++;
+ }
}
void
diff --git a/src/mesa/drivers/dri/i965/intel_asm_annotation.h b/src/mesa/drivers/dri/i965/intel_asm_annotation.h
index 662a4b4e0f7..5faf6c69d46 100644
--- a/src/mesa/drivers/dri/i965/intel_asm_annotation.h
+++ b/src/mesa/drivers/dri/i965/intel_asm_annotation.h
@@ -28,9 +28,6 @@
extern "C" {
#endif
-struct bblock_t;
-struct brw_context;
-struct gl_program;
struct backend_instruction;
struct cfg_t;
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index 0363bd3789a..f77807472fd 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -208,6 +208,13 @@ brw_finish_batch(struct brw_context *brw)
brw_emit_query_end(brw);
if (brw->batch.ring == RENDER_RING) {
+ /* Work around L3 state leaks into contexts set MI_RESTORE_INHIBIT which
+ * assume that the L3 cache is configured according to the hardware
+ * defaults.
+ */
+ if (brw->gen >= 7)
+ gen7_restore_default_l3_config(brw);
+
/* We may also need to snapshot and disable OA counters. */
brw_perf_monitor_finish_batch(brw);
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h
index 2b177d3a888..f47369029a0 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h
@@ -30,8 +30,12 @@ extern "C" {
* - 5 dwords for initial mi_flush
* - 2 dwords for CC state setup
* - 5 dwords for the required pipe control at the end
+ * - Restoring L3 configuration: (24 dwords = 96 bytes)
+ * - 2*6 dwords for two PIPE_CONTROL flushes.
+ * - 7 dwords for L3 configuration set-up.
+ * - 5 dwords for L3 atomic set-up (on HSW).
*/
-#define BATCH_RESERVED 152
+#define BATCH_RESERVED 248
struct intel_batchbuffer;
diff --git a/src/mesa/drivers/dri/i965/intel_debug.c b/src/mesa/drivers/dri/i965/intel_debug.c
index f53c4ab518a..e08c2969e06 100644
--- a/src/mesa/drivers/dri/i965/intel_debug.c
+++ b/src/mesa/drivers/dri/i965/intel_debug.c
@@ -31,7 +31,6 @@
#include "brw_context.h"
#include "intel_debug.h"
-#include "utils.h"
#include "util/u_atomic.h" /* for p_atomic_cmpxchg */
#include "util/debug.h"
@@ -79,6 +78,7 @@ static const struct debug_control debug_control[] = {
{ "tcs", DEBUG_TCS },
{ "ds", DEBUG_TES },
{ "tes", DEBUG_TES },
+ { "l3", DEBUG_L3 },
{ NULL, 0 }
};
@@ -103,28 +103,3 @@ brw_process_intel_debug_variable(void)
uint64_t intel_debug = parse_debug_string(getenv("INTEL_DEBUG"), debug_control);
(void) p_atomic_cmpxchg(&INTEL_DEBUG, 0, intel_debug);
}
-
-/**
- * Reads an environment variable and interprets its value as a boolean.
- *
- * Recognizes 0/false/no and 1/true/yes. Other values result in the default value.
- */
-bool
-brw_env_var_as_boolean(const char *var_name, bool default_value)
-{
- const char *str = getenv(var_name);
- if (str == NULL)
- return default_value;
-
- if (strcmp(str, "1") == 0 ||
- strcasecmp(str, "true") == 0 ||
- strcasecmp(str, "yes") == 0) {
- return true;
- } else if (strcmp(str, "0") == 0 ||
- strcasecmp(str, "false") == 0 ||
- strcasecmp(str, "no") == 0) {
- return false;
- } else {
- return default_value;
- }
-}
diff --git a/src/mesa/drivers/dri/i965/intel_debug.h b/src/mesa/drivers/dri/i965/intel_debug.h
index 9c6030a6d7d..b7b51112d92 100644
--- a/src/mesa/drivers/dri/i965/intel_debug.h
+++ b/src/mesa/drivers/dri/i965/intel_debug.h
@@ -71,6 +71,7 @@ extern uint64_t INTEL_DEBUG;
#define DEBUG_NO_COMPACTION (1ull << 35)
#define DEBUG_TCS (1ull << 36)
#define DEBUG_TES (1ull << 37)
+#define DEBUG_L3 (1ull << 38)
#ifdef HAVE_ANDROID_PLATFORM
#define LOG_TAG "INTEL-MESA"
@@ -120,5 +121,3 @@ extern uint64_t INTEL_DEBUG;
extern uint64_t intel_debug_flag_for_shader_stage(gl_shader_stage stage);
extern void brw_process_intel_debug_variable(void);
-
-extern bool brw_env_var_as_boolean(const char *var_name, bool default_value);
diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c b/src/mesa/drivers/dri/i965/intel_extensions.c
index 2e2459c125b..24761a70638 100644
--- a/src/mesa/drivers/dri/i965/intel_extensions.c
+++ b/src/mesa/drivers/dri/i965/intel_extensions.c
@@ -27,8 +27,6 @@
#include "brw_context.h"
#include "intel_batchbuffer.h"
-#include "intel_reg.h"
-#include "utils.h"
/**
* Test if we can use MI_LOAD_REGISTER_MEM from an untrusted batchbuffer.
@@ -40,8 +38,11 @@
static bool
can_do_pipelined_register_writes(struct brw_context *brw)
{
- /* Supposedly, Broadwell just works. */
- if (brw->gen >= 8)
+ /**
+ * gen >= 8 specifically allows these writes. gen <= 6 also
+ * doesn't block them.
+ */
+ if (brw->gen != 7)
return true;
static int result = -1;
@@ -319,6 +320,8 @@ intelInitExtensions(struct gl_context *ctx)
}
brw->predicate.supported = false;
+ brw->can_do_pipelined_register_writes =
+ can_do_pipelined_register_writes(brw);
if (brw->gen >= 7) {
ctx->Extensions.ARB_conservative_depth = true;
@@ -335,7 +338,7 @@ intelInitExtensions(struct gl_context *ctx)
ctx->Extensions.ARB_shader_storage_buffer_object = true;
ctx->Extensions.EXT_shader_samples_identical = true;
- if (can_do_pipelined_register_writes(brw)) {
+ if (brw->can_do_pipelined_register_writes) {
ctx->Extensions.ARB_draw_indirect = true;
ctx->Extensions.ARB_transform_feedback2 = true;
ctx->Extensions.ARB_transform_feedback3 = true;
@@ -352,6 +355,8 @@ intelInitExtensions(struct gl_context *ctx)
ctx->Extensions.ARB_viewport_array = true;
ctx->Extensions.AMD_vertex_shader_viewport_index = true;
ctx->Extensions.ARB_shader_subroutine = true;
+ if (ctx->Const.MaxComputeWorkGroupSize[0] >= 1024)
+ ctx->Extensions.ARB_compute_shader = true;
}
}
diff --git a/src/mesa/drivers/dri/i965/intel_fbo.h b/src/mesa/drivers/dri/i965/intel_fbo.h
index 5ba4c8f416c..89894cd3e86 100644
--- a/src/mesa/drivers/dri/i965/intel_fbo.h
+++ b/src/mesa/drivers/dri/i965/intel_fbo.h
@@ -39,7 +39,6 @@ extern "C" {
#endif
struct intel_mipmap_tree;
-struct intel_texture_image;
/**
* Intel renderbuffer, derived from gl_renderbuffer.
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
index 3326ac4d779..699e48a297c 100644
--- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
+++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
@@ -24,7 +24,6 @@
*/
#include "main/blend.h"
-#include "main/glheader.h"
#include "main/enums.h"
#include "main/image.h"
#include "main/colormac.h"
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_copy.c b/src/mesa/drivers/dri/i965/intel_pixel_copy.c
index 066b6a278b9..3b5bdb8f928 100644
--- a/src/mesa/drivers/dri/i965/intel_pixel_copy.c
+++ b/src/mesa/drivers/dri/i965/intel_pixel_copy.c
@@ -23,7 +23,6 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "main/glheader.h"
#include "main/image.h"
#include "main/state.h"
#include "main/mtypes.h"
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_draw.c b/src/mesa/drivers/dri/i965/intel_pixel_draw.c
index 0c8a9180d47..17f6592e303 100644
--- a/src/mesa/drivers/dri/i965/intel_pixel_draw.c
+++ b/src/mesa/drivers/dri/i965/intel_pixel_draw.c
@@ -23,7 +23,6 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "main/glheader.h"
#include "main/enums.h"
#include "main/image.h"
#include "main/glformats.h"
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_read.c b/src/mesa/drivers/dri/i965/intel_pixel_read.c
index 9bcbbd118ca..10d14623fe1 100644
--- a/src/mesa/drivers/dri/i965/intel_pixel_read.c
+++ b/src/mesa/drivers/dri/i965/intel_pixel_read.c
@@ -23,7 +23,6 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "main/glheader.h"
#include "main/enums.h"
#include "main/mtypes.h"
#include "main/macros.h"
@@ -135,10 +134,11 @@ intel_readpixels_tiled_memcpy(struct gl_context * ctx,
return false;
/* We can't handle copying from RGBX or BGRX because the tiled_memcpy
- * function doesn't set the last channel to 1.
+ * function doesn't set the last channel to 1. Note this checks BaseFormat
+ * rather than TexFormat in case the RGBX format is being simulated with an
+ * RGBA format.
*/
- if (rb->Format == MESA_FORMAT_B8G8R8X8_UNORM ||
- rb->Format == MESA_FORMAT_R8G8B8X8_UNORM)
+ if (rb->_BaseFormat == GL_RGB)
return false;
if (!intel_get_memcpy(rb->Format, format, type, &mem_copy, &cpp,
diff --git a/src/mesa/drivers/dri/i965/intel_reg.h b/src/mesa/drivers/dri/i965/intel_reg.h
index a261c2bbb8a..8888d6f776c 100644
--- a/src/mesa/drivers/dri/i965/intel_reg.h
+++ b/src/mesa/drivers/dri/i965/intel_reg.h
@@ -183,7 +183,7 @@
# define GEN8_HIZ_NP_EARLY_Z_FAILS_DISABLE (1 << 13)
# define GEN9_PARTIAL_RESOLVE_DISABLE_IN_VC (1 << 1)
# define GEN8_HIZ_PMA_MASK_BITS \
- ((GEN8_HIZ_NP_PMA_FIX_ENABLE | GEN8_HIZ_NP_EARLY_Z_FAILS_DISABLE) << 16)
+ REG_MASK(GEN8_HIZ_NP_PMA_FIX_ENABLE | GEN8_HIZ_NP_EARLY_Z_FAILS_DISABLE)
/* Predicate registers */
#define MI_PREDICATE_SRC0 0x2400
@@ -192,3 +192,56 @@
#define MI_PREDICATE_RESULT 0x2418
#define MI_PREDICATE_RESULT_1 0x241C
#define MI_PREDICATE_RESULT_2 0x2214
+
+/* L3 cache control registers. */
+#define GEN7_L3SQCREG1 0xb010
+/* L3SQ general and high priority credit initialization. */
+# define IVB_L3SQCREG1_SQGHPCI_DEFAULT 0x00730000
+# define VLV_L3SQCREG1_SQGHPCI_DEFAULT 0x00d30000
+# define HSW_L3SQCREG1_SQGHPCI_DEFAULT 0x00610000
+# define GEN7_L3SQCREG1_CONV_DC_UC (1 << 24)
+# define GEN7_L3SQCREG1_CONV_IS_UC (1 << 25)
+# define GEN7_L3SQCREG1_CONV_C_UC (1 << 26)
+# define GEN7_L3SQCREG1_CONV_T_UC (1 << 27)
+
+#define GEN7_L3CNTLREG2 0xb020
+# define GEN7_L3CNTLREG2_SLM_ENABLE (1 << 0)
+# define GEN7_L3CNTLREG2_URB_ALLOC_SHIFT 1
+# define GEN7_L3CNTLREG2_URB_ALLOC_MASK INTEL_MASK(6, 1)
+# define GEN7_L3CNTLREG2_URB_LOW_BW (1 << 7)
+# define GEN7_L3CNTLREG2_ALL_ALLOC_SHIFT 8
+# define GEN7_L3CNTLREG2_ALL_ALLOC_MASK INTEL_MASK(13, 8)
+# define GEN7_L3CNTLREG2_RO_ALLOC_SHIFT 14
+# define GEN7_L3CNTLREG2_RO_ALLOC_MASK INTEL_MASK(19, 14)
+# define GEN7_L3CNTLREG2_RO_LOW_BW (1 << 20)
+# define GEN7_L3CNTLREG2_DC_ALLOC_SHIFT 21
+# define GEN7_L3CNTLREG2_DC_ALLOC_MASK INTEL_MASK(26, 21)
+# define GEN7_L3CNTLREG2_DC_LOW_BW (1 << 27)
+
+#define GEN7_L3CNTLREG3 0xb024
+# define GEN7_L3CNTLREG3_IS_ALLOC_SHIFT 1
+# define GEN7_L3CNTLREG3_IS_ALLOC_MASK INTEL_MASK(6, 1)
+# define GEN7_L3CNTLREG3_IS_LOW_BW (1 << 7)
+# define GEN7_L3CNTLREG3_C_ALLOC_SHIFT 8
+# define GEN7_L3CNTLREG3_C_ALLOC_MASK INTEL_MASK(13, 8)
+# define GEN7_L3CNTLREG3_C_LOW_BW (1 << 14)
+# define GEN7_L3CNTLREG3_T_ALLOC_SHIFT 15
+# define GEN7_L3CNTLREG3_T_ALLOC_MASK INTEL_MASK(20, 15)
+# define GEN7_L3CNTLREG3_T_LOW_BW (1 << 21)
+
+#define HSW_SCRATCH1 0xb038
+#define HSW_SCRATCH1_L3_ATOMIC_DISABLE (1 << 27)
+
+#define HSW_ROW_CHICKEN3 0xe49c
+#define HSW_ROW_CHICKEN3_L3_ATOMIC_DISABLE (1 << 6)
+
+#define GEN8_L3CNTLREG 0x7034
+# define GEN8_L3CNTLREG_SLM_ENABLE (1 << 0)
+# define GEN8_L3CNTLREG_URB_ALLOC_SHIFT 1
+# define GEN8_L3CNTLREG_URB_ALLOC_MASK INTEL_MASK(7, 1)
+# define GEN8_L3CNTLREG_RO_ALLOC_SHIFT 11
+# define GEN8_L3CNTLREG_RO_ALLOC_MASK INTEL_MASK(17, 11)
+# define GEN8_L3CNTLREG_DC_ALLOC_SHIFT 18
+# define GEN8_L3CNTLREG_DC_ALLOC_MASK INTEL_MASK(24, 18)
+# define GEN8_L3CNTLREG_ALL_ALLOC_SHIFT 25
+# define GEN8_L3CNTLREG_ALL_ALLOC_MASK INTEL_MASK(31, 25)
diff --git a/src/mesa/drivers/dri/i965/intel_resolve_map.c b/src/mesa/drivers/dri/i965/intel_resolve_map.c
index bf6bcf257a9..3df4b882b05 100644
--- a/src/mesa/drivers/dri/i965/intel_resolve_map.c
+++ b/src/mesa/drivers/dri/i965/intel_resolve_map.c
@@ -23,7 +23,6 @@
#include "intel_resolve_map.h"
-#include
#include
/**
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index d64ebade769..cc90efe4886 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -26,7 +26,6 @@
#include
#include
#include
-#include "main/glheader.h"
#include "main/context.h"
#include "main/framebuffer.h"
#include "main/renderbuffer.h"
@@ -395,7 +394,7 @@ intel_create_image_from_name(__DRIscreen *screen,
return NULL;
}
- return image;
+ return image;
}
static __DRIimage *
@@ -530,7 +529,6 @@ intel_create_image(__DRIscreen *screen,
if (image == NULL)
return NULL;
-
cpp = _mesa_get_format_bytes(image->format);
image->bo = drm_intel_bo_alloc_tiled(intelScreen->bufmgr, "image",
width, height, cpp, &tiling,
diff --git a/src/mesa/drivers/dri/i965/intel_state.c b/src/mesa/drivers/dri/i965/intel_state.c
index 2f5c901fdf8..5001a49faff 100644
--- a/src/mesa/drivers/dri/i965/intel_state.c
+++ b/src/mesa/drivers/dri/i965/intel_state.c
@@ -23,7 +23,6 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "main/glheader.h"
#include "main/context.h"
#include "main/macros.h"
#include "main/enums.h"
diff --git a/src/mesa/drivers/dri/i965/intel_tex.h b/src/mesa/drivers/dri/i965/intel_tex.h
index dc83d0891ea..35d0a644bda 100644
--- a/src/mesa/drivers/dri/i965/intel_tex.h
+++ b/src/mesa/drivers/dri/i965/intel_tex.h
@@ -30,8 +30,6 @@
#include "main/formats.h"
#include "brw_context.h"
-struct intel_renderbuffer;
-
void intelInitTextureFuncs(struct dd_function_table *functions);
void intelInitTextureImageFuncs(struct dd_function_table *functions);
diff --git a/src/mesa/drivers/dri/i965/intel_tex_image.c b/src/mesa/drivers/dri/i965/intel_tex_image.c
index 34b91e823e0..5d32a4ce650 100644
--- a/src/mesa/drivers/dri/i965/intel_tex_image.c
+++ b/src/mesa/drivers/dri/i965/intel_tex_image.c
@@ -1,5 +1,4 @@
-#include "main/glheader.h"
#include "main/macros.h"
#include "main/mtypes.h"
#include "main/enums.h"
@@ -399,10 +398,11 @@ intel_gettexsubimage_tiled_memcpy(struct gl_context *ctx,
return false;
/* We can't handle copying from RGBX or BGRX because the tiled_memcpy
- * function doesn't set the last channel to 1.
+ * function doesn't set the last channel to 1. Note this checks BaseFormat
+ * rather than TexFormat in case the RGBX format is being simulated with an
+ * RGBA format.
*/
- if (texImage->TexFormat == MESA_FORMAT_B8G8R8X8_UNORM ||
- texImage->TexFormat == MESA_FORMAT_R8G8B8X8_UNORM)
+ if (texImage->_BaseFormat == GL_RGB)
return false;
if (!intel_get_memcpy(texImage->TexFormat, format, type, &mem_copy, &cpp,
diff --git a/src/mesa/drivers/dri/i965/test_vec4_copy_propagation.cpp b/src/mesa/drivers/dri/i965/test_vec4_copy_propagation.cpp
index ede409b6919..12667ffd23c 100644
--- a/src/mesa/drivers/dri/i965/test_vec4_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/test_vec4_copy_propagation.cpp
@@ -24,6 +24,7 @@
#include
#include "brw_vec4.h"
#include "brw_vs.h"
+#include "program/program.h"
using namespace brw;
diff --git a/src/mesa/drivers/dri/i965/test_vec4_register_coalesce.cpp b/src/mesa/drivers/dri/i965/test_vec4_register_coalesce.cpp
index 90a6bc3618f..34dcf95dc48 100644
--- a/src/mesa/drivers/dri/i965/test_vec4_register_coalesce.cpp
+++ b/src/mesa/drivers/dri/i965/test_vec4_register_coalesce.cpp
@@ -24,6 +24,7 @@
#include
#include "brw_vec4.h"
#include "brw_vs.h"
+#include "program/program.h"
using namespace brw;
diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
index 1e19cf7c7c0..adc146852ea 100644
--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
@@ -414,12 +414,12 @@ static GLboolean radeon_run_render( struct gl_context *ctx,
r100ContextPtr rmesa = R100_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- tnl_render_func *tab = TAG(render_tab_verts);
+ const tnl_render_func *tab = TAG(render_tab_verts);
GLuint i;
- if (rmesa->radeon.swtcl.RenderIndex != 0 ||
+ if (rmesa->radeon.swtcl.RenderIndex != 0 ||
!radeon_dma_validate_render( ctx, VB ))
- return GL_TRUE;
+ return GL_TRUE;
radeon_prepare_render(&rmesa->radeon);
if (rmesa->radeon.NewGLState)
diff --git a/src/mesa/drivers/x11/SConscript b/src/mesa/drivers/x11/SConscript
index cd5cccda0d1..d29f9874f44 100644
--- a/src/mesa/drivers/x11/SConscript
+++ b/src/mesa/drivers/x11/SConscript
@@ -4,8 +4,6 @@ env = env.Clone()
env.Append(CPPPATH = [
'#/src',
- '#/src/glsl',
- '#/src/glsl/nir',
'#/src/mapi',
'#/src/mesa',
'#/src/mesa/main',
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index a49018953ae..d693ec64ce4 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -170,7 +170,7 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
return GL_FALSE;
}
- /* From the ARB_geometry_shader4 spec:
+ /* 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:
@@ -710,6 +710,20 @@ valid_draw_indirect(struct gl_context *ctx,
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;
diff --git a/src/mesa/main/blit.c b/src/mesa/main/blit.c
index a32f1a42aea..abc553966e9 100644
--- a/src/mesa/main/blit.c
+++ b/src/mesa/main/blit.c
@@ -129,20 +129,22 @@ compatible_resolve_formats(const struct gl_renderbuffer *readRb,
{
GLenum readFormat, drawFormat;
- /* The simple case where we know the backing Mesa formats are the same.
- */
- if (_mesa_get_srgb_format_linear(readRb->Format) ==
- _mesa_get_srgb_format_linear(drawRb->Format)) {
- return GL_TRUE;
- }
-
- /* The Mesa formats are different, so we must check whether the internal
- * formats are compatible.
+ /* This checks whether the internal formats are compatible rather than the
+ * Mesa format for two reasons:
*
- * Under some circumstances, the user may request e.g. two GL_RGBA8
- * textures and get two entirely different Mesa formats like RGBA8888 and
- * ARGB8888. Drivers behaving like that should be able to cope with
- * non-matching formats by themselves, because it's not the user's fault.
+ * • Under some circumstances, the user may request e.g. two GL_RGBA8
+ * textures and get two entirely different Mesa formats like RGBA8888 and
+ * ARGB8888. Drivers behaving like that should be able to cope with
+ * non-matching formats by themselves, because it's not the user's fault.
+ *
+ * • Picking two different internal formats can end up with the same Mesa
+ * format. For example the driver might be simulating GL_RGB textures
+ * with GL_RGBA internally and in that case both internal formats would
+ * end up with RGBA8888.
+ *
+ * This function is used to generate a GL error according to the spec so in
+ * both cases we want to be looking at the application-level format, which
+ * is InternalFormat.
*
* Blits between linear and sRGB formats are also allowed.
*/
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index f985982c801..e0639c87ef4 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -50,6 +50,40 @@
/*#define BOUNDS_CHECK*/
+/**
+ * We count the number of buffer modification calls to check for
+ * inefficient buffer use. This is the number of such calls before we
+ * issue a warning.
+ */
+#define BUFFER_WARNING_CALL_COUNT 4
+
+
+/**
+ * Helper to warn of possible performance issues, such as frequently
+ * updating a buffer created with GL_STATIC_DRAW. Called via the macro
+ * below.
+ */
+static void
+buffer_usage_warning(struct gl_context *ctx, GLuint *id, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ _mesa_gl_vdebug(ctx, id,
+ MESA_DEBUG_SOURCE_API,
+ MESA_DEBUG_TYPE_PERFORMANCE,
+ MESA_DEBUG_SEVERITY_MEDIUM,
+ fmt, args);
+ va_end(args);
+}
+
+#define BUFFER_USAGE_WARNING(CTX, FMT, ...) \
+ do { \
+ static GLuint id = 0; \
+ buffer_usage_warning(CTX, &id, FMT, ##__VA_ARGS__); \
+ } while (0)
+
+
/**
* Used as a placeholder for buffer objects between glGenBuffers() and
* glBindBuffer() so that glIsBuffer() can work correctly.
@@ -1677,6 +1711,21 @@ _mesa_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
if (size == 0)
return;
+ bufObj->NumSubDataCalls++;
+
+ if ((bufObj->Usage == GL_STATIC_DRAW ||
+ bufObj->Usage == GL_STATIC_COPY) &&
+ bufObj->NumSubDataCalls >= BUFFER_WARNING_CALL_COUNT) {
+ /* If the application declared the buffer as static draw/copy or stream
+ * draw, it should not be frequently modified with glBufferSubData.
+ */
+ BUFFER_USAGE_WARNING(ctx,
+ "using %s(buffer %u, offset %u, size %u) to "
+ "update a %s buffer",
+ func, bufObj->Name, offset, size,
+ _mesa_enum_to_string(bufObj->Usage));
+ }
+
bufObj->Written = GL_TRUE;
assert(ctx->Driver.BufferSubData);
@@ -2384,6 +2433,18 @@ _mesa_map_buffer_range(struct gl_context *ctx,
return NULL;
}
+ if (access & GL_MAP_WRITE_BIT) {
+ bufObj->NumMapBufferWriteCalls++;
+ if ((bufObj->Usage == GL_STATIC_DRAW ||
+ bufObj->Usage == GL_STATIC_COPY) &&
+ bufObj->NumMapBufferWriteCalls >= BUFFER_WARNING_CALL_COUNT) {
+ BUFFER_USAGE_WARNING(ctx,
+ "using %s(buffer %u, offset %u, length %u) to "
+ "update a %s buffer",
+ func, bufObj->Name, offset, length,
+ _mesa_enum_to_string(bufObj->Usage));
+ }
+ }
assert(ctx->Driver.MapBufferRange);
map = ctx->Driver.MapBufferRange(ctx, offset, length, access, bufObj,
diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
index 93b4e6f12dd..c5ee7412b62 100644
--- a/src/mesa/main/compiler.h
+++ b/src/mesa/main/compiler.h
@@ -46,20 +46,6 @@ extern "C" {
#endif
-/**
- * Sun compilers define __i386 instead of the gcc-style __i386__
- */
-#ifdef __SUNPRO_C
-# if !defined(__i386__) && defined(__i386)
-# define __i386__
-# elif !defined(__amd64__) && defined(__amd64)
-# define __amd64__
-# elif !defined(__sparc__) && defined(__sparc)
-# define __sparc__
-# endif
-#endif
-
-
/**
* Either define MESA_BIG_ENDIAN or MESA_LITTLE_ENDIAN, and CPU_TO_LE32.
* Do not use these unless absolutely necessary!
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index f29de5f91fd..2d53e2fa72f 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -246,7 +246,7 @@
#define MAX_FEEDBACK_BUFFERS 4
#define MAX_FEEDBACK_ATTRIBS 32
-/** For GL_ARB_geometry_shader4 */
+/** For geometry shader */
/*@{*/
#define MAX_GEOMETRY_UNIFORM_COMPONENTS 512
#define MAX_GEOMETRY_OUTPUT_VERTICES 256
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index be542dd6797..be983d4c86a 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -654,6 +654,9 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api)
/* GL_EXT_provoking_vertex */
consts->QuadsFollowProvokingVertexConvention = GL_TRUE;
+ /** GL_ARB_viewport_array */
+ consts->LayerAndVPIndexProvokingVertex = GL_UNDEFINED_VERTEX;
+
/* GL_EXT_transform_feedback */
consts->MaxTransformFeedbackBuffers = MAX_FEEDBACK_BUFFERS;
consts->MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS;
@@ -2031,9 +2034,10 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
/* A pipeline object is bound */
if (ctx->_Shader->Name && !ctx->_Shader->Validated) {
- /* Error message will be printed inside _mesa_validate_program_pipeline.
- */
- if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader, GL_TRUE)) {
+ if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glValidateProgramPipeline failed to validate the "
+ "pipeline");
return GL_FALSE;
}
}
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
index 4798b1f9b43..8b64f452572 100644
--- a/src/mesa/main/context.h
+++ b/src/mesa/main/context.h
@@ -330,8 +330,7 @@ _mesa_is_gles31(const struct gl_context *ctx)
static inline bool
_mesa_has_geometry_shaders(const struct gl_context *ctx)
{
- return _mesa_is_desktop_gl(ctx) &&
- (ctx->Version >= 32 || ctx->Extensions.ARB_geometry_shader4);
+ return _mesa_is_desktop_gl(ctx) && ctx->Version >= 32;
}
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 496a14f8dad..e5281ce9744 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -727,6 +727,7 @@ struct dd_function_table {
* \name Performance monitors
*/
/*@{*/
+ void (*InitPerfMonitorGroups)(struct gl_context *ctx);
struct gl_perf_monitor_object * (*NewPerfMonitor)(struct gl_context *ctx);
void (*DeletePerfMonitor)(struct gl_context *ctx,
struct gl_perf_monitor_object *m);
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 2b65b2ea949..ba2e670eb9a 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -457,11 +457,6 @@ typedef enum
OPCODE_SAMPLER_PARAMETERIIV,
OPCODE_SAMPLER_PARAMETERUIV,
- /* GL_ARB_geometry_shader4 */
- OPCODE_PROGRAM_PARAMETERI,
- OPCODE_FRAMEBUFFER_TEXTURE,
- OPCODE_FRAMEBUFFER_TEXTURE_FACE,
-
/* GL_ARB_sync */
OPCODE_WAIT_SYNC,
@@ -7554,44 +7549,6 @@ save_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
}
}
-/* GL_ARB_geometry_shader4 */
-static void GLAPIENTRY
-save_ProgramParameteri(GLuint program, GLenum pname, GLint value)
-{
- Node *n;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_PROGRAM_PARAMETERI, 3);
- if (n) {
- n[1].ui = program;
- n[2].e = pname;
- n[3].i = value;
- }
- if (ctx->ExecuteFlag) {
- CALL_ProgramParameteri(ctx->Exec, (program, pname, value));
- }
-}
-
-static void GLAPIENTRY
-save_FramebufferTexture(GLenum target, GLenum attachment,
- GLuint texture, GLint level)
-{
- Node *n;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_FRAMEBUFFER_TEXTURE, 4);
- if (n) {
- n[1].e = target;
- n[2].e = attachment;
- n[3].ui = texture;
- n[4].i = level;
- }
- if (ctx->ExecuteFlag) {
- CALL_FramebufferTexture(ctx->Exec, (target, attachment, texture, level));
- }
-}
-
-
static void GLAPIENTRY
save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
@@ -8841,14 +8798,6 @@ execute_list(struct gl_context *ctx, GLuint list)
}
break;
- /* GL_ARB_geometry_shader4 */
- case OPCODE_PROGRAM_PARAMETERI:
- CALL_ProgramParameteri(ctx->Exec, (n[1].ui, n[2].e, n[3].i));
- break;
- case OPCODE_FRAMEBUFFER_TEXTURE:
- CALL_FramebufferTexture(ctx->Exec, (n[1].e, n[2].e,
- n[3].ui, n[4].i));
- break;
/* GL_ARB_sync */
case OPCODE_WAIT_SYNC:
{
@@ -9614,10 +9563,6 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
SET_BlendEquationiARB(table, save_BlendEquationi);
SET_BlendEquationSeparateiARB(table, save_BlendEquationSeparatei);
- /* OpenGL 3.2 */
- SET_ProgramParameteri(table, save_ProgramParameteri);
- SET_FramebufferTexture(table, save_FramebufferTexture);
-
/* GL_NV_conditional_render */
SET_BeginConditionalRender(table, save_BeginConditionalRender);
SET_EndConditionalRender(table, save_EndConditionalRender);
diff --git a/src/mesa/main/errors.c b/src/mesa/main/errors.c
index 366b119aba3..9e6610918c4 100644
--- a/src/mesa/main/errors.c
+++ b/src/mesa/main/errors.c
@@ -76,6 +76,8 @@ struct gl_debug_message
enum mesa_debug_type type;
GLuint id;
enum mesa_debug_severity severity;
+ /* length as given by the user - if message was explicitly null terminated,
+ * length can be negative */
GLsizei length;
GLcharARB *message;
};
@@ -98,7 +100,7 @@ struct gl_debug_state
struct gl_debug_group *Groups[MAX_DEBUG_GROUP_STACK_DEPTH];
struct gl_debug_message GroupMessages[MAX_DEBUG_GROUP_STACK_DEPTH];
- GLint GroupStackDepth;
+ GLint CurrentGroup; // GroupStackDepth - 1
struct gl_debug_log Log;
};
@@ -211,14 +213,19 @@ debug_message_store(struct gl_debug_message *msg,
enum mesa_debug_severity severity,
GLsizei len, const char *buf)
{
+ GLsizei length = len;
+
assert(!msg->message && !msg->length);
- msg->message = malloc(len+1);
- if (msg->message) {
- (void) strncpy(msg->message, buf, (size_t)len);
- msg->message[len] = '\0';
+ if (length < 0)
+ length = strlen(buf);
- msg->length = len+1;
+ msg->message = malloc(length+1);
+ if (msg->message) {
+ (void) strncpy(msg->message, buf, (size_t)length);
+ msg->message[length] = '\0';
+
+ msg->length = len;
msg->source = source;
msg->type = type;
msg->id = id;
@@ -229,7 +236,7 @@ debug_message_store(struct gl_debug_message *msg,
/* malloc failed! */
msg->message = out_of_memory;
- msg->length = strlen(out_of_memory)+1;
+ msg->length = -1;
msg->source = MESA_DEBUG_SOURCE_OTHER;
msg->type = MESA_DEBUG_TYPE_ERROR;
msg->id = oom_msg_id;
@@ -243,8 +250,9 @@ debug_namespace_init(struct gl_debug_namespace *ns)
make_empty_list(&ns->Elements);
/* Enable all the messages with severity HIGH or MEDIUM by default */
- ns->DefaultState = (1 << MESA_DEBUG_SEVERITY_HIGH) |
- (1 << MESA_DEBUG_SEVERITY_MEDIUM);
+ ns->DefaultState = (1 << MESA_DEBUG_SEVERITY_MEDIUM ) |
+ (1 << MESA_DEBUG_SEVERITY_HIGH) |
+ (1 << MESA_DEBUG_SEVERITY_NOTIFICATION);
}
static void
@@ -422,7 +430,7 @@ debug_create(void)
static bool
debug_is_group_read_only(const struct gl_debug_state *debug)
{
- const GLint gstack = debug->GroupStackDepth;
+ const GLint gstack = debug->CurrentGroup;
return (gstack > 0 && debug->Groups[gstack] == debug->Groups[gstack - 1]);
}
@@ -432,7 +440,7 @@ debug_is_group_read_only(const struct gl_debug_state *debug)
static bool
debug_make_group_writable(struct gl_debug_state *debug)
{
- const GLint gstack = debug->GroupStackDepth;
+ const GLint gstack = debug->CurrentGroup;
const struct gl_debug_group *src = debug->Groups[gstack];
struct gl_debug_group *dst;
int s, t;
@@ -472,7 +480,7 @@ debug_make_group_writable(struct gl_debug_state *debug)
static void
debug_clear_group(struct gl_debug_state *debug)
{
- const GLint gstack = debug->GroupStackDepth;
+ const GLint gstack = debug->CurrentGroup;
if (!debug_is_group_read_only(debug)) {
struct gl_debug_group *grp = debug->Groups[gstack];
@@ -496,9 +504,9 @@ debug_clear_group(struct gl_debug_state *debug)
static void
debug_destroy(struct gl_debug_state *debug)
{
- while (debug->GroupStackDepth > 0) {
+ while (debug->CurrentGroup > 0) {
debug_clear_group(debug);
- debug->GroupStackDepth--;
+ debug->CurrentGroup--;
}
debug_clear_group(debug);
@@ -514,7 +522,7 @@ debug_set_message_enable(struct gl_debug_state *debug,
enum mesa_debug_type type,
GLuint id, GLboolean enabled)
{
- const GLint gstack = debug->GroupStackDepth;
+ const GLint gstack = debug->CurrentGroup;
struct gl_debug_namespace *ns;
debug_make_group_writable(debug);
@@ -541,7 +549,7 @@ debug_set_message_enable_all(struct gl_debug_state *debug,
enum mesa_debug_severity severity,
GLboolean enabled)
{
- const GLint gstack = debug->GroupStackDepth;
+ const GLint gstack = debug->CurrentGroup;
int s, t, smax, tmax;
if (source == MESA_DEBUG_SOURCE_COUNT) {
@@ -579,7 +587,7 @@ debug_is_message_enabled(const struct gl_debug_state *debug,
GLuint id,
enum mesa_debug_severity severity)
{
- const GLint gstack = debug->GroupStackDepth;
+ const GLint gstack = debug->CurrentGroup;
struct gl_debug_group *grp = debug->Groups[gstack];
struct gl_debug_namespace *nspace = &grp->Namespaces[source][type];
@@ -606,7 +614,7 @@ debug_log_message(struct gl_debug_state *debug,
GLint nextEmpty;
struct gl_debug_message *emptySlot;
- assert(len >= 0 && len < MAX_DEBUG_MESSAGE_LENGTH);
+ assert(len < MAX_DEBUG_MESSAGE_LENGTH);
if (log->NumMessages == MAX_DEBUG_LOGGED_MESSAGES)
return;
@@ -657,24 +665,24 @@ debug_delete_messages(struct gl_debug_state *debug, int count)
static struct gl_debug_message *
debug_get_group_message(struct gl_debug_state *debug)
{
- return &debug->GroupMessages[debug->GroupStackDepth];
+ return &debug->GroupMessages[debug->CurrentGroup];
}
static void
debug_push_group(struct gl_debug_state *debug)
{
- const GLint gstack = debug->GroupStackDepth;
+ const GLint gstack = debug->CurrentGroup;
/* just point to the previous stack */
debug->Groups[gstack + 1] = debug->Groups[gstack];
- debug->GroupStackDepth++;
+ debug->CurrentGroup++;
}
static void
debug_pop_group(struct gl_debug_state *debug)
{
debug_clear_group(debug);
- debug->GroupStackDepth--;
+ debug->CurrentGroup--;
}
@@ -775,7 +783,7 @@ _mesa_get_debug_state_int(struct gl_context *ctx, GLenum pname)
debug->Log.Messages[debug->Log.NextMessage].length : 0;
break;
case GL_DEBUG_GROUP_STACK_DEPTH:
- val = debug->GroupStackDepth;
+ val = debug->CurrentGroup + 1;
break;
default:
assert(!"unknown debug output param");
@@ -921,9 +929,9 @@ validate_params(struct gl_context *ctx, unsigned caller,
case GL_DEBUG_TYPE_PORTABILITY_ARB:
case GL_DEBUG_TYPE_OTHER_ARB:
case GL_DEBUG_TYPE_MARKER:
- break;
case GL_DEBUG_TYPE_PUSH_GROUP:
case GL_DEBUG_TYPE_POP_GROUP:
+ break;
case GL_DONT_CARE:
if (caller == CONTROL)
break;
@@ -959,8 +967,22 @@ error:
static GLboolean
-validate_length(struct gl_context *ctx, const char *callerstr, GLsizei length)
+validate_length(struct gl_context *ctx, const char *callerstr, GLsizei length,
+ const GLchar *buf)
{
+
+ if (length < 0) {
+ GLsizei len = strlen(buf);
+
+ if (len >= MAX_DEBUG_MESSAGE_LENGTH) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(null terminated string length=%d, is not less than "
+ "GL_MAX_DEBUG_MESSAGE_LENGTH=%d)", callerstr, len,
+ MAX_DEBUG_MESSAGE_LENGTH);
+ return GL_FALSE;
+ }
+ }
+
if (length >= MAX_DEBUG_MESSAGE_LENGTH) {
_mesa_error(ctx, GL_INVALID_VALUE,
"%s(length=%d, which is not less than "
@@ -989,9 +1011,7 @@ _mesa_DebugMessageInsert(GLenum source, GLenum type, GLuint id,
if (!validate_params(ctx, INSERT, callerstr, source, type, severity))
return; /* GL_INVALID_ENUM */
- if (length < 0)
- length = strlen(buf);
- if (!validate_length(ctx, callerstr, length))
+ if (!validate_length(ctx, callerstr, length, buf))
return; /* GL_INVALID_VALUE */
log_msg(ctx, gl_enum_to_debug_source(source),
@@ -1032,23 +1052,28 @@ _mesa_GetDebugMessageLog(GLuint count, GLsizei logSize, GLenum *sources,
for (ret = 0; ret < count; ret++) {
const struct gl_debug_message *msg = debug_fetch_message(debug);
+ GLsizei len;
if (!msg)
break;
- if (logSize < msg->length && messageLog != NULL)
+ len = msg->length;
+ if (len < 0)
+ len = strlen(msg->message);
+
+ if (logSize < len+1 && messageLog != NULL)
break;
if (messageLog) {
- assert(msg->message[msg->length-1] == '\0');
- (void) strncpy(messageLog, msg->message, (size_t)msg->length);
+ assert(msg->message[len] == '\0');
+ (void) strncpy(messageLog, msg->message, (size_t)len+1);
- messageLog += msg->length;
- logSize -= msg->length;
+ messageLog += len+1;
+ logSize -= len+1;
}
if (lengths)
- *lengths++ = msg->length;
+ *lengths++ = len+1;
if (severities)
*severities++ = debug_severity_enums[msg->severity];
if (sources)
@@ -1158,16 +1183,14 @@ _mesa_PushDebugGroup(GLenum source, GLuint id, GLsizei length,
return;
}
- if (length < 0)
- length = strlen(message);
- if (!validate_length(ctx, callerstr, length))
+ if (!validate_length(ctx, callerstr, length, message))
return; /* GL_INVALID_VALUE */
debug = _mesa_lock_debug_state(ctx);
if (!debug)
return;
- if (debug->GroupStackDepth >= MAX_DEBUG_GROUP_STACK_DEPTH-1) {
+ if (debug->CurrentGroup >= MAX_DEBUG_GROUP_STACK_DEPTH-1) {
_mesa_unlock_debug_state(ctx);
_mesa_error(ctx, GL_STACK_OVERFLOW, "%s", callerstr);
return;
@@ -1209,7 +1232,7 @@ _mesa_PopDebugGroup(void)
if (!debug)
return;
- if (debug->GroupStackDepth <= 0) {
+ if (debug->CurrentGroup <= 0) {
_mesa_unlock_debug_state(ctx);
_mesa_error(ctx, GL_STACK_UNDERFLOW, "%s", callerstr);
return;
@@ -1599,20 +1622,19 @@ _mesa_log(const char *fmtString, ...)
* \param ctx GL context.
* \param type The namespace to which this message belongs.
* \param id The message ID within the given namespace.
- * \param msg The message to output. Need not be null-terminated.
- * \param len The length of 'msg'. If negative, 'msg' must be null-terminated.
+ * \param msg The message to output. Must be null-terminated.
*/
void
-_mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint *id,
- const char *msg, int len )
+_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id,
+ const char *msg)
{
enum mesa_debug_source source = MESA_DEBUG_SOURCE_SHADER_COMPILER;
enum mesa_debug_severity severity = MESA_DEBUG_SEVERITY_HIGH;
+ int len;
debug_get_id(id);
- if (len < 0)
- len = strlen(msg);
+ len = strlen(msg);
/* Truncate the message if necessary. */
if (len >= MAX_DEBUG_MESSAGE_LENGTH)
diff --git a/src/mesa/main/errors.h b/src/mesa/main/errors.h
index 81e47a8b8c1..f2919765488 100644
--- a/src/mesa/main/errors.h
+++ b/src/mesa/main/errors.h
@@ -115,7 +115,7 @@ _mesa_get_debug_state_ptr(struct gl_context *ctx, GLenum pname);
extern void
_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id,
- const char *msg, int len);
+ const char *msg);
void GLAPIENTRY
_mesa_DebugMessageInsert(GLenum source, GLenum type, GLuint id,
diff --git a/src/mesa/main/extensions.h b/src/mesa/main/extensions.h
index 1615e1cc0a4..b5e03507231 100644
--- a/src/mesa/main/extensions.h
+++ b/src/mesa/main/extensions.h
@@ -88,7 +88,7 @@ enum {
};
-/** Checks if the context suports a user-facing extension */
+/** Checks if the context supports a user-facing extension */
#define EXT(name_str, driver_cap, ...) \
static inline bool \
_mesa_has_##name_str(const struct gl_context *ctx) \
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index 051d69a3613..52a4ed63c0d 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -258,7 +258,7 @@ EXT(INGR_blend_func_separate , EXT_blend_func_separate
EXT(INTEL_performance_query , INTEL_performance_query , GLL, GLC, x , ES2, 2013)
EXT(KHR_context_flush_control , dummy_true , GLL, GLC, x , ES2, 2014)
-EXT(KHR_debug , dummy_true , GLL, GLC, ES1, ES2, 2012)
+EXT(KHR_debug , dummy_true , GLL, GLC, 11, ES2, 2012)
EXT(KHR_texture_compression_astc_hdr , KHR_texture_compression_astc_hdr , GLL, GLC, x , ES2, 2012)
EXT(KHR_texture_compression_astc_ldr , KHR_texture_compression_astc_ldr , GLL, GLC, x , ES2, 2012)
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 539c41148dd..c6a2e5b912c 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -398,7 +398,6 @@ EXTRA_EXT(EXT_pixel_buffer_object);
EXTRA_EXT(ARB_vertex_program);
EXTRA_EXT2(NV_point_sprite, ARB_point_sprite);
EXTRA_EXT2(ARB_vertex_program, ARB_fragment_program);
-EXTRA_EXT(ARB_geometry_shader4);
EXTRA_EXT(ARB_color_buffer_float);
EXTRA_EXT(EXT_framebuffer_sRGB);
EXTRA_EXT(OES_EGL_image_external);
@@ -455,12 +454,6 @@ static const int extra_gl32_es3[] = {
EXTRA_END,
};
-static const int extra_gl32_ARB_geometry_shader4[] = {
- EXTRA_VERSION_32,
- EXT(ARB_geometry_shader4),
- EXTRA_END
-};
-
static const int extra_gl40_ARB_sample_shading[] = {
EXTRA_VERSION_40,
EXT(ARB_sample_shading),
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 9b22b91ac1b..7a48ed2f414 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -765,14 +765,6 @@ descriptor=[
[ "MAX_TRANSFORM_FEEDBACK_BUFFERS", "CONTEXT_INT(Const.MaxTransformFeedbackBuffers), extra_ARB_transform_feedback3" ],
[ "MAX_VERTEX_STREAMS", "CONTEXT_INT(Const.MaxVertexStreams), extra_ARB_transform_feedback3_ARB_gpu_shader5" ],
-# GL_ARB_geometry_shader4
- [ "MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits), extra_gl32_ARB_geometry_shader4" ],
- [ "MAX_GEOMETRY_OUTPUT_VERTICES_ARB", "CONTEXT_INT(Const.MaxGeometryOutputVertices), extra_gl32_ARB_geometry_shader4" ],
- [ "MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB", "CONTEXT_INT(Const.MaxGeometryTotalOutputComponents), extra_gl32_ARB_geometry_shader4" ],
- [ "MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents), extra_gl32_ARB_geometry_shader4" ],
- [ "MAX_GEOMETRY_VARYING_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents), extra_ARB_geometry_shader4" ],
- [ "MAX_VERTEX_VARYING_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents), extra_ARB_geometry_shader4" ],
-
# GL_ARB_color_buffer_float
[ "RGBA_FLOAT_MODE_ARB", "BUFFER_FIELD(Visual.floatMode, TYPE_BOOLEAN), extra_core_ARB_color_buffer_float_and_new_buffers" ],
@@ -800,6 +792,10 @@ descriptor=[
[ "CONTEXT_PROFILE_MASK", "CONTEXT_INT(Const.ProfileMask), extra_version_32" ],
[ "MAX_GEOMETRY_INPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents), extra_version_32" ],
[ "MAX_GEOMETRY_OUTPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents), extra_version_32" ],
+ [ "MAX_GEOMETRY_TEXTURE_IMAGE_UNITS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits), extra_version_32" ],
+ [ "MAX_GEOMETRY_OUTPUT_VERTICES", "CONTEXT_INT(Const.MaxGeometryOutputVertices), extra_version_32" ],
+ [ "MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS", "CONTEXT_INT(Const.MaxGeometryTotalOutputComponents), extra_version_32" ],
+ [ "MAX_GEOMETRY_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents), extra_version_32" ],
# GL_ARB_robustness
[ "RESET_NOTIFICATION_STRATEGY_ARB", "CONTEXT_ENUM(Const.ResetStrategy), NO_EXTRA" ],
@@ -851,8 +847,8 @@ descriptor=[
[ "MAX_VIEWPORTS", "CONTEXT_INT(Const.MaxViewports), extra_ARB_viewport_array" ],
[ "VIEWPORT_SUBPIXEL_BITS", "CONTEXT_INT(Const.ViewportSubpixelBits), extra_ARB_viewport_array" ],
[ "VIEWPORT_BOUNDS_RANGE", "CONTEXT_FLOAT2(Const.ViewportBounds), extra_ARB_viewport_array" ],
- [ "LAYER_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ],
- [ "VIEWPORT_INDEX_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ],
+ [ "LAYER_PROVOKING_VERTEX", "CONTEXT_ENUM(Const.LayerAndVPIndexProvokingVertex), extra_ARB_viewport_array" ],
+ [ "VIEWPORT_INDEX_PROVOKING_VERTEX", "CONTEXT_ENUM(Const.LayerAndVPIndexProvokingVertex), extra_ARB_viewport_array" ],
# GL_ARB_gpu_shader5
[ "MAX_GEOMETRY_SHADER_INVOCATIONS", "CONST(MAX_GEOMETRY_SHADER_INVOCATIONS), extra_ARB_gpu_shader5" ],
diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c
index 2ed42eaffdd..f5284447b6e 100644
--- a/src/mesa/main/glformats.c
+++ b/src/mesa/main/glformats.c
@@ -2077,12 +2077,18 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
* \return error code, or GL_NO_ERROR.
*/
GLenum
-_mesa_es_error_check_format_and_type(GLenum format, GLenum type,
+_mesa_es_error_check_format_and_type(const struct gl_context *ctx,
+ GLenum format, GLenum type,
unsigned dimensions)
{
GLboolean type_valid = GL_TRUE;
switch (format) {
+ case GL_RED:
+ case GL_RG:
+ if (ctx->API == API_OPENGLES || !ctx->Extensions.ARB_texture_rg)
+ return GL_INVALID_VALUE;
+ /* fallthrough */
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h
index 92f4bc6864e..b3668556da2 100644
--- a/src/mesa/main/glformats.h
+++ b/src/mesa/main/glformats.h
@@ -127,7 +127,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
GLenum format, GLenum type);
extern GLenum
-_mesa_es_error_check_format_and_type(GLenum format, GLenum type,
+_mesa_es_error_check_format_and_type(const struct gl_context *ctx,
+ GLenum format, GLenum type,
unsigned dimensions);
extern GLenum
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 4a849fb090d..fabe9913c11 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1275,6 +1275,10 @@ struct gl_buffer_object
GLboolean Immutable; /**< GL_ARB_buffer_storage */
gl_buffer_usage UsageHistory; /**< How has this buffer been used so far? */
+ /** Counters used for buffer usage warnings */
+ GLuint NumSubDataCalls;
+ GLuint NumMapBufferWriteCalls;
+
struct gl_buffer_mapping Mappings[MAP_COUNT];
};
@@ -1419,6 +1423,9 @@ struct gl_vertex_array_object
/** Vertex buffer bindings */
struct gl_vertex_buffer_binding VertexBinding[VERT_ATTRIB_MAX];
+ /** Mask indicating which vertex arrays have vertex buffer associated. */
+ GLbitfield64 VertexAttribBufferMask;
+
/** Mask of VERT_BIT_* values indicating which arrays are enabled */
GLbitfield64 _Enabled;
@@ -2672,6 +2679,10 @@ struct gl_shader_program
* local_size_{x,y,z}. Otherwise undefined.
*/
unsigned LocalSize[3];
+ /**
+ * Size of shared variables accessed by the compute shader.
+ */
+ unsigned SharedSize;
} Comp;
/* post-link info: */
@@ -2883,6 +2894,9 @@ struct gl_shader_compiler_options
GLboolean LowerBufferInterfaceBlocks; /**< Lower UBO and SSBO access to intrinsics. */
+ GLboolean LowerShaderSharedVariables; /**< Lower compute shader shared
+ * variable access to intrinsics. */
+
const struct nir_shader_compiler_options *NirOptions;
};
@@ -3402,7 +3416,7 @@ struct gl_constants
*/
GLuint MaxUserAssignableUniformLocations;
- /** GL_ARB_geometry_shader4 */
+ /** geometry shader */
GLuint MaxGeometryOutputVertices;
GLuint MaxGeometryTotalOutputComponents;
@@ -3454,6 +3468,9 @@ struct gl_constants
/** GL_EXT_provoking_vertex */
GLboolean QuadsFollowProvokingVertexConvention;
+ /** GL_ARB_viewport_array */
+ GLenum LayerAndVPIndexProvokingVertex;
+
/** OpenGL version 3.0 */
GLbitfield ContextFlags; /**< Ex: GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT */
@@ -3687,7 +3704,6 @@ struct gl_extensions
GLboolean ARB_enhanced_layouts;
GLboolean ARB_explicit_attrib_location;
GLboolean ARB_explicit_uniform_location;
- GLboolean ARB_geometry_shader4;
GLboolean ARB_gpu_shader5;
GLboolean ARB_gpu_shader_fp64;
GLboolean ARB_half_float_vertex;
diff --git a/src/mesa/main/performance_monitor.c b/src/mesa/main/performance_monitor.c
index 2d740daf019..98dfbea083c 100644
--- a/src/mesa/main/performance_monitor.c
+++ b/src/mesa/main/performance_monitor.c
@@ -53,6 +53,13 @@ _mesa_init_performance_monitors(struct gl_context *ctx)
ctx->PerfMonitor.Groups = NULL;
}
+static inline void
+init_groups(struct gl_context *ctx)
+{
+ if (unlikely(!ctx->PerfMonitor.Groups))
+ ctx->Driver.InitPerfMonitorGroups(ctx);
+}
+
static struct gl_perf_monitor_object *
new_performance_monitor(struct gl_context *ctx, GLuint index)
{
@@ -171,6 +178,7 @@ _mesa_GetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize,
GLuint *groups)
{
GET_CURRENT_CONTEXT(ctx);
+ init_groups(ctx);
if (numGroups != NULL)
*numGroups = ctx->PerfMonitor.NumGroups;
@@ -191,7 +199,11 @@ _mesa_GetPerfMonitorCountersAMD(GLuint group, GLint *numCounters,
GLsizei countersSize, GLuint *counters)
{
GET_CURRENT_CONTEXT(ctx);
- const struct gl_perf_monitor_group *group_obj = get_group(ctx, group);
+ const struct gl_perf_monitor_group *group_obj;
+
+ init_groups(ctx);
+
+ group_obj = get_group(ctx, group);
if (group_obj == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetPerfMonitorCountersAMD(invalid group)");
@@ -219,9 +231,11 @@ _mesa_GetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize,
GLsizei *length, GLchar *groupString)
{
GET_CURRENT_CONTEXT(ctx);
+ const struct gl_perf_monitor_group *group_obj;
- const struct gl_perf_monitor_group *group_obj = get_group(ctx, group);
+ init_groups(ctx);
+ group_obj = get_group(ctx, group);
if (group_obj == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetPerfMonitorGroupStringAMD");
return;
@@ -251,6 +265,8 @@ _mesa_GetPerfMonitorCounterStringAMD(GLuint group, GLuint counter,
const struct gl_perf_monitor_group *group_obj;
const struct gl_perf_monitor_counter *counter_obj;
+ init_groups(ctx);
+
group_obj = get_group(ctx, group);
if (group_obj == NULL) {
@@ -290,6 +306,8 @@ _mesa_GetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum pname,
const struct gl_perf_monitor_group *group_obj;
const struct gl_perf_monitor_counter *counter_obj;
+ init_groups(ctx);
+
group_obj = get_group(ctx, group);
if (group_obj == NULL) {
@@ -353,6 +371,8 @@ _mesa_GenPerfMonitorsAMD(GLsizei n, GLuint *monitors)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glGenPerfMonitorsAMD(%d)\n", n);
+ init_groups(ctx);
+
if (n < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGenPerfMonitorsAMD(n < 0)");
return;
@@ -673,6 +693,8 @@ _mesa_GetFirstPerfQueryIdINTEL(GLuint *queryId)
GET_CURRENT_CONTEXT(ctx);
unsigned numGroups;
+ init_groups(ctx);
+
/* The GL_INTEL_performance_query spec says:
*
* "If queryId pointer is equal to 0, INVALID_VALUE error is generated."
@@ -705,6 +727,7 @@ extern void GLAPIENTRY
_mesa_GetNextPerfQueryIdINTEL(GLuint queryId, GLuint *nextQueryId)
{
GET_CURRENT_CONTEXT(ctx);
+ init_groups(ctx);
/* The GL_INTEL_performance_query spec says:
*
@@ -744,6 +767,8 @@ _mesa_GetPerfQueryIdByNameINTEL(char *queryName, GLuint *queryId)
GET_CURRENT_CONTEXT(ctx);
unsigned i;
+ init_groups(ctx);
+
/* The GL_INTEL_performance_query spec says:
*
* "If queryName does not reference a valid query name, an INVALID_VALUE
@@ -783,9 +808,11 @@ _mesa_GetPerfQueryInfoINTEL(GLuint queryId,
GET_CURRENT_CONTEXT(ctx);
unsigned i;
- const struct gl_perf_monitor_group *group_obj =
- get_group(ctx, queryid_to_index(queryId));
+ const struct gl_perf_monitor_group *group_obj;
+ init_groups(ctx);
+
+ group_obj = get_group(ctx, queryid_to_index(queryId));
if (group_obj == NULL) {
/* The GL_INTEL_performance_query spec says:
*
@@ -860,6 +887,8 @@ _mesa_GetPerfCounterInfoINTEL(GLuint queryId, GLuint counterId,
unsigned counterIndex;
unsigned i;
+ init_groups(ctx);
+
group_obj = get_group(ctx, queryid_to_index(queryId));
/* The GL_INTEL_performance_query spec says:
@@ -979,6 +1008,8 @@ _mesa_CreatePerfQueryINTEL(GLuint queryId, GLuint *queryHandle)
struct gl_perf_monitor_object *m;
unsigned i;
+ init_groups(ctx);
+
/* This is not specified in the extension, but is the only sane thing to
* do.
*/
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 90dff13485b..f2a872dc83a 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -341,6 +341,8 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
if ((stages & GL_COMPUTE_SHADER_BIT) != 0)
_mesa_use_shader_program(ctx, GL_COMPUTE_SHADER, shProg, pipe);
+
+ pipe->Validated = false;
}
/**
@@ -645,8 +647,7 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
*params = pipe->InfoLog ? strlen(pipe->InfoLog) + 1 : 0;
return;
case GL_VALIDATE_STATUS:
- /* If pipeline is not bound, return initial value 0. */
- *params = (ctx->_Shader->Name != pipe->Name) ? 0 : pipe->Validated;
+ *params = pipe->Validated;
return;
case GL_VERTEX_SHADER:
*params = pipe->CurrentProgram[MESA_SHADER_VERTEX]
@@ -758,10 +759,10 @@ program_stages_interleaved_illegally(const struct gl_pipeline_object *pipe)
extern GLboolean
_mesa_validate_program_pipeline(struct gl_context* ctx,
- struct gl_pipeline_object *pipe,
- GLboolean IsBound)
+ struct gl_pipeline_object *pipe)
{
unsigned i;
+ bool program_empty = true;
pipe->Validated = GL_FALSE;
@@ -789,7 +790,7 @@ _mesa_validate_program_pipeline(struct gl_context* ctx,
*/
for (i = 0; i < MESA_SHADER_STAGES; i++) {
if (!program_stages_all_active(pipe, pipe->CurrentProgram[i])) {
- goto err;
+ return GL_FALSE;
}
}
@@ -810,7 +811,7 @@ _mesa_validate_program_pipeline(struct gl_context* ctx,
ralloc_strdup(pipe,
"Program is active for multiple shader stages with an "
"intervening stage provided by another program");
- goto err;
+ return GL_FALSE;
}
/* Section 2.11.11 (Shader Execution), subheading "Validation," of the
@@ -831,7 +832,7 @@ _mesa_validate_program_pipeline(struct gl_context* ctx,
pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] ||
pipe->CurrentProgram[MESA_SHADER_TESS_EVAL])) {
pipe->InfoLog = ralloc_strdup(pipe, "Program lacks a vertex shader");
- goto err;
+ return GL_FALSE;
}
/* Section 2.11.11 (Shader Execution), subheading "Validation," of the
@@ -854,10 +855,33 @@ _mesa_validate_program_pipeline(struct gl_context* ctx,
"Program %d was relinked without "
"PROGRAM_SEPARABLE state",
pipe->CurrentProgram[i]->Name);
- goto err;
+ return GL_FALSE;
}
}
+ /* Section 11.1.3.11 (Validation) of the OpenGL 4.5 spec says:
+ *
+ * "An INVALID_OPERATION error is generated by any command that trans-
+ * fers vertices to the GL or launches compute work if the current set
+ * of active program objects cannot be executed, for reasons including:
+ *
+ * ...
+ *
+ * - There is no current program object specified by UseProgram,
+ * there is a current program pipeline object, and that object is
+ * empty (no executable code is installed for any stage).
+ */
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (pipe->CurrentProgram[i]) {
+ program_empty = false;
+ break;
+ }
+ }
+
+ if (program_empty) {
+ return GL_FALSE;
+ }
+
/* Section 2.11.11 (Shader Execution), subheading "Validation," of the
* OpenGL 4.1 spec says:
*
@@ -873,17 +897,25 @@ _mesa_validate_program_pipeline(struct gl_context* ctx,
* maximum number of texture image units allowed."
*/
if (!_mesa_sampler_uniforms_pipeline_are_valid(pipe))
- goto err;
+ return GL_FALSE;
+
+ /* Validate inputs against outputs, this cannot be done during linking
+ * since programs have been linked separately from each other.
+ *
+ * From OpenGL 4.5 Core spec:
+ * "Separable program objects may have validation failures that cannot be
+ * detected without the complete program pipeline. Mismatched interfaces,
+ * improper usage of program objects together, and the same
+ * state-dependent failures can result in validation errors for such
+ * program objects."
+ *
+ * OpenGL ES 3.1 specification has the same text.
+ */
+ if (!_mesa_validate_pipeline_io(pipe))
+ return GL_FALSE;
pipe->Validated = GL_TRUE;
return GL_TRUE;
-
-err:
- if (IsBound)
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glValidateProgramPipeline failed to validate the pipeline");
-
- return GL_FALSE;
}
/**
@@ -905,23 +937,7 @@ _mesa_ValidateProgramPipeline(GLuint pipeline)
return;
}
- _mesa_validate_program_pipeline(ctx, pipe,
- (ctx->_Shader->Name == pipe->Name));
-
- /* Validate inputs against outputs, this cannot be done during linking
- * since programs have been linked separately from each other.
- *
- * From OpenGL 4.5 Core spec:
- * "Separable program objects may have validation failures that cannot be
- * detected without the complete program pipeline. Mismatched interfaces,
- * improper usage of program objects together, and the same
- * state-dependent failures can result in validation errors for such
- * program objects."
- *
- * OpenGL ES 3.1 specification has the same text.
- */
- if (!_mesa_validate_pipeline_io(pipe))
- pipe->Validated = GL_FALSE;
+ _mesa_validate_program_pipeline(ctx, pipe);
}
void GLAPIENTRY
diff --git a/src/mesa/main/pipelineobj.h b/src/mesa/main/pipelineobj.h
index 6dee775ab5e..fbcb7659249 100644
--- a/src/mesa/main/pipelineobj.h
+++ b/src/mesa/main/pipelineobj.h
@@ -67,7 +67,8 @@ _mesa_bind_pipeline(struct gl_context *ctx,
struct gl_pipeline_object *pipe);
extern GLboolean
-_mesa_validate_program_pipeline(struct gl_context * ctx, struct gl_pipeline_object *pipe, GLboolean IsBound);
+_mesa_validate_program_pipeline(struct gl_context * ctx,
+ struct gl_pipeline_object *pipe);
extern void GLAPIENTRY
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 81bb912beb6..8cdc9fe1cb2 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -1043,7 +1043,7 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
_mesa_get_color_read_type(ctx) == type) {
err = GL_NO_ERROR;
} else if (ctx->Version < 30) {
- err = _mesa_es_error_check_format_and_type(format, type, 2);
+ err = _mesa_es_error_check_format_and_type(ctx, format, type, 2);
if (err == GL_NO_ERROR) {
if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
err = GL_INVALID_OPERATION;
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 79a91b5b6bd..5d15006bb30 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -1369,7 +1369,7 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg,
static bool
validate_io(const struct gl_shader *input_stage,
- const struct gl_shader *output_stage)
+ const struct gl_shader *output_stage, bool isES)
{
assert(input_stage && output_stage);
@@ -1385,15 +1385,25 @@ validate_io(const struct gl_shader *input_stage,
continue;
if (strcmp(in_var->name, out_var->name) == 0) {
- /* From OpenGL ES 3.1 spec:
- * "When both shaders are in separate programs, mismatched
- * precision qualifiers will result in a program interface
- * mismatch that will result in program pipeline validation
- * failures, as described in section 7.4.1 (“Shader Interface
- * Matching”) of the OpenGL ES 3.1 Specification."
+ /* Since we now only validate precision, we can skip this step for
+ * desktop GLSL shaders, there precision qualifier is ignored.
+ *
+ * From OpenGL 4.50 Shading Language spec, section 4.7:
+ * "For the purposes of determining if an output from one
+ * shader stage matches an input of the next stage, the
+ * precision qualifier need not match."
*/
- if (in_var->data.precision != out_var->data.precision)
- return false;
+ if (isES) {
+ /* From OpenGL ES 3.1 spec:
+ * "When both shaders are in separate programs, mismatched
+ * precision qualifiers will result in a program interface
+ * mismatch that will result in program pipeline validation
+ * failures, as described in section 7.4.1 (“Shader Interface
+ * Matching”) of the OpenGL ES 3.1 Specification."
+ */
+ if (in_var->data.precision != out_var->data.precision)
+ return false;
+ }
}
}
}
@@ -1420,19 +1430,10 @@ _mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline)
for (idx = prev + 1; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
if (shProg[idx]) {
- /* Since we now only validate precision, we can skip this step for
- * desktop GLSL shaders, there precision qualifier is ignored.
- *
- * From OpenGL 4.50 Shading Language spec, section 4.7:
- * "For the purposes of determining if an output from one shader
- * stage matches an input of the next stage, the precision
- * qualifier need not match."
- */
- if (shProg[prev]->IsES || shProg[idx]->IsES) {
- if (!validate_io(shProg[prev]->_LinkedShaders[prev],
- shProg[idx]->_LinkedShaders[idx]))
- return false;
- }
+ if (!validate_io(shProg[prev]->_LinkedShaders[prev],
+ shProg[idx]->_LinkedShaders[idx],
+ shProg[prev]->IsES || shProg[idx]->IsES))
+ return false;
prev = idx;
}
}
diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h
index be80752d7f2..53836f131fb 100644
--- a/src/mesa/main/shaderobj.h
+++ b/src/mesa/main/shaderobj.h
@@ -127,8 +127,7 @@ _mesa_shader_enum_to_shader_stage(GLenum v)
case GL_COMPUTE_SHADER:
return MESA_SHADER_COMPUTE;
default:
- assert(0 && "bad value in _mesa_shader_enum_to_shader_stage()");
- return MESA_SHADER_VERTEX;
+ unreachable("bad value in _mesa_shader_enum_to_shader_stage()");
}
}
@@ -159,7 +158,6 @@ static inline gl_shader_stage
_mesa_shader_stage_from_subroutine_uniform(GLenum subuniform)
{
switch (subuniform) {
- default:
case GL_VERTEX_SUBROUTINE_UNIFORM:
return MESA_SHADER_VERTEX;
case GL_GEOMETRY_SUBROUTINE_UNIFORM:
@@ -173,6 +171,7 @@ _mesa_shader_stage_from_subroutine_uniform(GLenum subuniform)
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
return MESA_SHADER_TESS_EVAL;
}
+ unreachable("not reached");
}
static inline gl_shader_stage
@@ -192,13 +191,13 @@ _mesa_shader_stage_from_subroutine(GLenum subroutine)
case GL_TESS_EVALUATION_SUBROUTINE:
return MESA_SHADER_TESS_EVAL;
}
+ unreachable("not reached");
}
static inline GLenum
_mesa_shader_stage_to_subroutine(gl_shader_stage stage)
{
switch (stage) {
- default:
case MESA_SHADER_VERTEX:
return GL_VERTEX_SUBROUTINE;
case MESA_SHADER_GEOMETRY:
@@ -212,13 +211,13 @@ _mesa_shader_stage_to_subroutine(gl_shader_stage stage)
case MESA_SHADER_TESS_EVAL:
return GL_TESS_EVALUATION_SUBROUTINE;
}
+ unreachable("not reached");
}
static inline GLenum
_mesa_shader_stage_to_subroutine_uniform(gl_shader_stage stage)
{
switch (stage) {
- default:
case MESA_SHADER_VERTEX:
return GL_VERTEX_SUBROUTINE_UNIFORM;
case MESA_SHADER_GEOMETRY:
@@ -232,6 +231,7 @@ _mesa_shader_stage_to_subroutine_uniform(gl_shader_stage stage)
case MESA_SHADER_TESS_EVAL:
return GL_TESS_EVALUATION_SUBROUTINE_UNIFORM;
}
+ unreachable("not reached");
}
extern bool
diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp
index 97f81f932f6..d288b1dbe94 100644
--- a/src/mesa/main/tests/dispatch_sanity.cpp
+++ b/src/mesa/main/tests/dispatch_sanity.cpp
@@ -1937,7 +1937,8 @@ const struct function gles11_functions_possible[] = {
{ "glGetLightxv", 11, -1 },
{ "glGetMaterialfv", 11, _gloffset_GetMaterialfv },
{ "glGetMaterialxv", 11, -1 },
- { "glGetPointerv", 11, _gloffset_GetPointerv },
+ // We check for the aliased -KHR version in GLES 1.1
+// { "glGetPointerv", 11, _gloffset_GetPointerv },
{ "glGetRenderbufferParameterivOES", 11, -1 },
{ "glGetString", 11, _gloffset_GetString },
{ "glGetTexEnvfv", 11, _gloffset_GetTexEnvfv },
@@ -2049,6 +2050,7 @@ const struct function gles11_functions_possible[] = {
{ "glGetDebugMessageLogKHR", 11, -1 },
{ "glGetObjectLabelKHR", 11, -1 },
{ "glGetObjectPtrLabelKHR", 11, -1 },
+ { "glGetPointervKHR", 11, _gloffset_GetPointerv },
{ "glObjectLabelKHR", 11, -1 },
{ "glObjectPtrLabelKHR", 11, -1 },
@@ -2284,6 +2286,7 @@ const struct function gles2_functions_possible[] = {
{ "glGetDebugMessageLogKHR", 20, -1 },
{ "glGetObjectLabelKHR", 20, -1 },
{ "glGetObjectPtrLabelKHR", 20, -1 },
+ { "glGetPointervKHR", 20, -1 },
{ "glObjectLabelKHR", 20, -1 },
{ "glObjectPtrLabelKHR", 20, -1 },
diff --git a/src/mesa/main/tests/enum_strings.cpp b/src/mesa/main/tests/enum_strings.cpp
index 96b2246f48b..4d8d12fdf2b 100644
--- a/src/mesa/main/tests/enum_strings.cpp
+++ b/src/mesa/main/tests/enum_strings.cpp
@@ -48,1848 +48,52 @@ TEST(EnumStrings, LookUpUnknownNumber)
EXPECT_STRCASEEQ("0xEEEE", _mesa_enum_to_string(0xEEEE));
}
-/* Please type the name and the value. This makes it easier to detect
- * enums with the same value but different names. The current list is
- * sorted by enum value. Please keep it that way.
- */
const struct enum_info everything[] = {
+ /* A core enum, that should take precedence over _EXT and _OES. */
+ { 0x0007, "GL_QUADS" },
+
+ /* A core enum, that should take precedence over _EXT, _ARB, and _OES. */
+ { 0x000a, "GL_LINES_ADJACENCY" },
+
+ /* A core enum, that should take precedence over a _BIT. */
{ 0x0100, "GL_ACCUM" },
- { 0x0101, "GL_LOAD" },
- { 0x0102, "GL_RETURN" },
- { 0x0103, "GL_MULT" },
- { 0x0104, "GL_ADD" },
- { 0x0200, "GL_NEVER" },
- { 0x0201, "GL_LESS" },
- { 0x0202, "GL_EQUAL" },
- { 0x0203, "GL_LEQUAL" },
- { 0x0204, "GL_GREATER" },
- { 0x0205, "GL_NOTEQUAL" },
- { 0x0206, "GL_GEQUAL" },
- { 0x0207, "GL_ALWAYS" },
- { 0x0300, "GL_SRC_COLOR" },
- { 0x0301, "GL_ONE_MINUS_SRC_COLOR" },
- { 0x0302, "GL_SRC_ALPHA" },
- { 0x0303, "GL_ONE_MINUS_SRC_ALPHA" },
- { 0x0304, "GL_DST_ALPHA" },
- { 0x0305, "GL_ONE_MINUS_DST_ALPHA" },
- { 0x0306, "GL_DST_COLOR" },
- { 0x0307, "GL_ONE_MINUS_DST_COLOR" },
- { 0x0308, "GL_SRC_ALPHA_SATURATE" },
- { 0x0400, "GL_FRONT_LEFT" },
- { 0x0401, "GL_FRONT_RIGHT" },
- { 0x0402, "GL_BACK_LEFT" },
- { 0x0403, "GL_BACK_RIGHT" },
- { 0x0404, "GL_FRONT" },
- { 0x0405, "GL_BACK" },
- { 0x0406, "GL_LEFT" },
- { 0x0407, "GL_RIGHT" },
- { 0x0408, "GL_FRONT_AND_BACK" },
- { 0x0409, "GL_AUX0" },
- { 0x040A, "GL_AUX1" },
- { 0x040B, "GL_AUX2" },
- { 0x040C, "GL_AUX3" },
- { 0x0500, "GL_INVALID_ENUM" },
- { 0x0501, "GL_INVALID_VALUE" },
- { 0x0502, "GL_INVALID_OPERATION" },
- { 0x0503, "GL_STACK_OVERFLOW" },
- { 0x0504, "GL_STACK_UNDERFLOW" },
- { 0x0505, "GL_OUT_OF_MEMORY" },
- { 0x0506, "GL_INVALID_FRAMEBUFFER_OPERATION" },
- { 0x0600, "GL_2D" },
- { 0x0601, "GL_3D" },
- { 0x0602, "GL_3D_COLOR" },
- { 0x0603, "GL_3D_COLOR_TEXTURE" },
- { 0x0604, "GL_4D_COLOR_TEXTURE" },
- { 0x0700, "GL_PASS_THROUGH_TOKEN" },
- { 0x0701, "GL_POINT_TOKEN" },
- { 0x0702, "GL_LINE_TOKEN" },
- { 0x0703, "GL_POLYGON_TOKEN" },
- { 0x0704, "GL_BITMAP_TOKEN" },
- { 0x0705, "GL_DRAW_PIXEL_TOKEN" },
- { 0x0706, "GL_COPY_PIXEL_TOKEN" },
- { 0x0707, "GL_LINE_RESET_TOKEN" },
- { 0x0800, "GL_EXP" },
- { 0x0801, "GL_EXP2" },
- { 0x0900, "GL_CW" },
- { 0x0901, "GL_CCW" },
- { 0x0A00, "GL_COEFF" },
- { 0x0A01, "GL_ORDER" },
- { 0x0A02, "GL_DOMAIN" },
- { 0x0B00, "GL_CURRENT_COLOR" },
- { 0x0B01, "GL_CURRENT_INDEX" },
- { 0x0B02, "GL_CURRENT_NORMAL" },
- { 0x0B03, "GL_CURRENT_TEXTURE_COORDS" },
- { 0x0B04, "GL_CURRENT_RASTER_COLOR" },
- { 0x0B05, "GL_CURRENT_RASTER_INDEX" },
- { 0x0B06, "GL_CURRENT_RASTER_TEXTURE_COORDS" },
- { 0x0B07, "GL_CURRENT_RASTER_POSITION" },
- { 0x0B08, "GL_CURRENT_RASTER_POSITION_VALID" },
- { 0x0B09, "GL_CURRENT_RASTER_DISTANCE" },
- { 0x0B10, "GL_POINT_SMOOTH" },
- { 0x0B11, "GL_POINT_SIZE" },
- { 0x0B12, "GL_POINT_SIZE_RANGE" },
- { 0x0B13, "GL_POINT_SIZE_GRANULARITY" },
- { 0x0B20, "GL_LINE_SMOOTH" },
- { 0x0B21, "GL_LINE_WIDTH" },
- { 0x0B22, "GL_LINE_WIDTH_RANGE" },
- { 0x0B23, "GL_LINE_WIDTH_GRANULARITY" },
- { 0x0B24, "GL_LINE_STIPPLE" },
- { 0x0B25, "GL_LINE_STIPPLE_PATTERN" },
- { 0x0B26, "GL_LINE_STIPPLE_REPEAT" },
- { 0x0B30, "GL_LIST_MODE" },
- { 0x0B31, "GL_MAX_LIST_NESTING" },
- { 0x0B32, "GL_LIST_BASE" },
- { 0x0B33, "GL_LIST_INDEX" },
- { 0x0B40, "GL_POLYGON_MODE" },
- { 0x0B41, "GL_POLYGON_SMOOTH" },
- { 0x0B42, "GL_POLYGON_STIPPLE" },
- { 0x0B43, "GL_EDGE_FLAG" },
- { 0x0B44, "GL_CULL_FACE" },
- { 0x0B45, "GL_CULL_FACE_MODE" },
- { 0x0B46, "GL_FRONT_FACE" },
- { 0x0B50, "GL_LIGHTING" },
- { 0x0B51, "GL_LIGHT_MODEL_LOCAL_VIEWER" },
- { 0x0B52, "GL_LIGHT_MODEL_TWO_SIDE" },
- { 0x0B53, "GL_LIGHT_MODEL_AMBIENT" },
- { 0x0B54, "GL_SHADE_MODEL" },
- { 0x0B55, "GL_COLOR_MATERIAL_FACE" },
- { 0x0B56, "GL_COLOR_MATERIAL_PARAMETER" },
- { 0x0B57, "GL_COLOR_MATERIAL" },
- { 0x0B60, "GL_FOG" },
- { 0x0B61, "GL_FOG_INDEX" },
- { 0x0B62, "GL_FOG_DENSITY" },
- { 0x0B63, "GL_FOG_START" },
- { 0x0B64, "GL_FOG_END" },
- { 0x0B65, "GL_FOG_MODE" },
- { 0x0B66, "GL_FOG_COLOR" },
- { 0x0B70, "GL_DEPTH_RANGE" },
- { 0x0B71, "GL_DEPTH_TEST" },
- { 0x0B72, "GL_DEPTH_WRITEMASK" },
- { 0x0B73, "GL_DEPTH_CLEAR_VALUE" },
- { 0x0B74, "GL_DEPTH_FUNC" },
- { 0x0B80, "GL_ACCUM_CLEAR_VALUE" },
- { 0x0B90, "GL_STENCIL_TEST" },
- { 0x0B91, "GL_STENCIL_CLEAR_VALUE" },
- { 0x0B92, "GL_STENCIL_FUNC" },
- { 0x0B93, "GL_STENCIL_VALUE_MASK" },
- { 0x0B94, "GL_STENCIL_FAIL" },
- { 0x0B95, "GL_STENCIL_PASS_DEPTH_FAIL" },
- { 0x0B96, "GL_STENCIL_PASS_DEPTH_PASS" },
- { 0x0B97, "GL_STENCIL_REF" },
- { 0x0B98, "GL_STENCIL_WRITEMASK" },
- { 0x0BA0, "GL_MATRIX_MODE" },
- { 0x0BA1, "GL_NORMALIZE" },
- { 0x0BA2, "GL_VIEWPORT" },
- { 0x0BA3, "GL_MODELVIEW_STACK_DEPTH" },
- { 0x0BA4, "GL_PROJECTION_STACK_DEPTH" },
- { 0x0BA5, "GL_TEXTURE_STACK_DEPTH" },
- { 0x0BA6, "GL_MODELVIEW_MATRIX" },
- { 0x0BA7, "GL_PROJECTION_MATRIX" },
- { 0x0BA8, "GL_TEXTURE_MATRIX" },
- { 0x0BB0, "GL_ATTRIB_STACK_DEPTH" },
- { 0x0BB1, "GL_CLIENT_ATTRIB_STACK_DEPTH" },
- { 0x0BC0, "GL_ALPHA_TEST" },
- { 0x0BC1, "GL_ALPHA_TEST_FUNC" },
- { 0x0BC2, "GL_ALPHA_TEST_REF" },
- { 0x0BD0, "GL_DITHER" },
- { 0x0BE0, "GL_BLEND_DST" },
- { 0x0BE1, "GL_BLEND_SRC" },
- { 0x0BE2, "GL_BLEND" },
- { 0x0BF0, "GL_LOGIC_OP_MODE" },
- { 0x0BF1, "GL_INDEX_LOGIC_OP" },
- { 0x0BF2, "GL_COLOR_LOGIC_OP" },
- { 0x0C00, "GL_AUX_BUFFERS" },
- { 0x0C01, "GL_DRAW_BUFFER" },
- { 0x0C02, "GL_READ_BUFFER" },
- { 0x0C10, "GL_SCISSOR_BOX" },
- { 0x0C11, "GL_SCISSOR_TEST" },
- { 0x0C20, "GL_INDEX_CLEAR_VALUE" },
- { 0x0C21, "GL_INDEX_WRITEMASK" },
- { 0x0C22, "GL_COLOR_CLEAR_VALUE" },
- { 0x0C23, "GL_COLOR_WRITEMASK" },
- { 0x0C30, "GL_INDEX_MODE" },
- { 0x0C31, "GL_RGBA_MODE" },
- { 0x0C32, "GL_DOUBLEBUFFER" },
- { 0x0C33, "GL_STEREO" },
- { 0x0C40, "GL_RENDER_MODE" },
- { 0x0C50, "GL_PERSPECTIVE_CORRECTION_HINT" },
- { 0x0C51, "GL_POINT_SMOOTH_HINT" },
- { 0x0C52, "GL_LINE_SMOOTH_HINT" },
- { 0x0C53, "GL_POLYGON_SMOOTH_HINT" },
- { 0x0C54, "GL_FOG_HINT" },
- { 0x0C60, "GL_TEXTURE_GEN_S" },
- { 0x0C61, "GL_TEXTURE_GEN_T" },
- { 0x0C62, "GL_TEXTURE_GEN_R" },
- { 0x0C63, "GL_TEXTURE_GEN_Q" },
- { 0x0C70, "GL_PIXEL_MAP_I_TO_I" },
- { 0x0C71, "GL_PIXEL_MAP_S_TO_S" },
- { 0x0C72, "GL_PIXEL_MAP_I_TO_R" },
- { 0x0C73, "GL_PIXEL_MAP_I_TO_G" },
- { 0x0C74, "GL_PIXEL_MAP_I_TO_B" },
- { 0x0C75, "GL_PIXEL_MAP_I_TO_A" },
- { 0x0C76, "GL_PIXEL_MAP_R_TO_R" },
- { 0x0C77, "GL_PIXEL_MAP_G_TO_G" },
- { 0x0C78, "GL_PIXEL_MAP_B_TO_B" },
- { 0x0C79, "GL_PIXEL_MAP_A_TO_A" },
- { 0x0CB0, "GL_PIXEL_MAP_I_TO_I_SIZE" },
- { 0x0CB1, "GL_PIXEL_MAP_S_TO_S_SIZE" },
- { 0x0CB2, "GL_PIXEL_MAP_I_TO_R_SIZE" },
- { 0x0CB3, "GL_PIXEL_MAP_I_TO_G_SIZE" },
- { 0x0CB4, "GL_PIXEL_MAP_I_TO_B_SIZE" },
- { 0x0CB5, "GL_PIXEL_MAP_I_TO_A_SIZE" },
- { 0x0CB6, "GL_PIXEL_MAP_R_TO_R_SIZE" },
- { 0x0CB7, "GL_PIXEL_MAP_G_TO_G_SIZE" },
- { 0x0CB8, "GL_PIXEL_MAP_B_TO_B_SIZE" },
- { 0x0CB9, "GL_PIXEL_MAP_A_TO_A_SIZE" },
- { 0x0CF0, "GL_UNPACK_SWAP_BYTES" },
- { 0x0CF1, "GL_UNPACK_LSB_FIRST" },
- { 0x0CF2, "GL_UNPACK_ROW_LENGTH" },
- { 0x0CF3, "GL_UNPACK_SKIP_ROWS" },
- { 0x0CF4, "GL_UNPACK_SKIP_PIXELS" },
- { 0x0CF5, "GL_UNPACK_ALIGNMENT" },
- { 0x0D00, "GL_PACK_SWAP_BYTES" },
- { 0x0D01, "GL_PACK_LSB_FIRST" },
- { 0x0D02, "GL_PACK_ROW_LENGTH" },
- { 0x0D03, "GL_PACK_SKIP_ROWS" },
- { 0x0D04, "GL_PACK_SKIP_PIXELS" },
- { 0x0D05, "GL_PACK_ALIGNMENT" },
- { 0x0D10, "GL_MAP_COLOR" },
- { 0x0D11, "GL_MAP_STENCIL" },
- { 0x0D12, "GL_INDEX_SHIFT" },
- { 0x0D13, "GL_INDEX_OFFSET" },
- { 0x0D14, "GL_RED_SCALE" },
- { 0x0D15, "GL_RED_BIAS" },
- { 0x0D16, "GL_ZOOM_X" },
- { 0x0D17, "GL_ZOOM_Y" },
- { 0x0D18, "GL_GREEN_SCALE" },
- { 0x0D19, "GL_GREEN_BIAS" },
- { 0x0D1A, "GL_BLUE_SCALE" },
- { 0x0D1B, "GL_BLUE_BIAS" },
- { 0x0D1C, "GL_ALPHA_SCALE" },
- { 0x0D1D, "GL_ALPHA_BIAS" },
- { 0x0D1E, "GL_DEPTH_SCALE" },
- { 0x0D1F, "GL_DEPTH_BIAS" },
- { 0x0D30, "GL_MAX_EVAL_ORDER" },
- { 0x0D31, "GL_MAX_LIGHTS" },
- { 0x0D32, "GL_MAX_CLIP_DISTANCES" },
- { 0x0D33, "GL_MAX_TEXTURE_SIZE" },
- { 0x0D34, "GL_MAX_PIXEL_MAP_TABLE" },
- { 0x0D35, "GL_MAX_ATTRIB_STACK_DEPTH" },
- { 0x0D36, "GL_MAX_MODELVIEW_STACK_DEPTH" },
- { 0x0D37, "GL_MAX_NAME_STACK_DEPTH" },
- { 0x0D38, "GL_MAX_PROJECTION_STACK_DEPTH" },
- { 0x0D39, "GL_MAX_TEXTURE_STACK_DEPTH" },
- { 0x0D3A, "GL_MAX_VIEWPORT_DIMS" },
- { 0x0D3B, "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH" },
- { 0x0D50, "GL_SUBPIXEL_BITS" },
- { 0x0D51, "GL_INDEX_BITS" },
- { 0x0D52, "GL_RED_BITS" },
- { 0x0D53, "GL_GREEN_BITS" },
- { 0x0D54, "GL_BLUE_BITS" },
- { 0x0D55, "GL_ALPHA_BITS" },
- { 0x0D56, "GL_DEPTH_BITS" },
- { 0x0D57, "GL_STENCIL_BITS" },
- { 0x0D58, "GL_ACCUM_RED_BITS" },
- { 0x0D59, "GL_ACCUM_GREEN_BITS" },
- { 0x0D5A, "GL_ACCUM_BLUE_BITS" },
- { 0x0D5B, "GL_ACCUM_ALPHA_BITS" },
- { 0x0D70, "GL_NAME_STACK_DEPTH" },
- { 0x0D80, "GL_AUTO_NORMAL" },
- { 0x0D90, "GL_MAP1_COLOR_4" },
- { 0x0D91, "GL_MAP1_INDEX" },
- { 0x0D92, "GL_MAP1_NORMAL" },
- { 0x0D93, "GL_MAP1_TEXTURE_COORD_1" },
- { 0x0D94, "GL_MAP1_TEXTURE_COORD_2" },
- { 0x0D95, "GL_MAP1_TEXTURE_COORD_3" },
- { 0x0D96, "GL_MAP1_TEXTURE_COORD_4" },
- { 0x0D97, "GL_MAP1_VERTEX_3" },
- { 0x0D98, "GL_MAP1_VERTEX_4" },
- { 0x0DB0, "GL_MAP2_COLOR_4" },
- { 0x0DB1, "GL_MAP2_INDEX" },
- { 0x0DB2, "GL_MAP2_NORMAL" },
- { 0x0DB3, "GL_MAP2_TEXTURE_COORD_1" },
- { 0x0DB4, "GL_MAP2_TEXTURE_COORD_2" },
- { 0x0DB5, "GL_MAP2_TEXTURE_COORD_3" },
- { 0x0DB6, "GL_MAP2_TEXTURE_COORD_4" },
- { 0x0DB7, "GL_MAP2_VERTEX_3" },
- { 0x0DB8, "GL_MAP2_VERTEX_4" },
- { 0x0DD0, "GL_MAP1_GRID_DOMAIN" },
- { 0x0DD1, "GL_MAP1_GRID_SEGMENTS" },
- { 0x0DD2, "GL_MAP2_GRID_DOMAIN" },
- { 0x0DD3, "GL_MAP2_GRID_SEGMENTS" },
- { 0x0DE0, "GL_TEXTURE_1D" },
- { 0x0DE1, "GL_TEXTURE_2D" },
- { 0x0DF0, "GL_FEEDBACK_BUFFER_POINTER" },
- { 0x0DF1, "GL_FEEDBACK_BUFFER_SIZE" },
- { 0x0DF2, "GL_FEEDBACK_BUFFER_TYPE" },
- { 0x0DF3, "GL_SELECTION_BUFFER_POINTER" },
- { 0x0DF4, "GL_SELECTION_BUFFER_SIZE" },
- { 0x1000, "GL_TEXTURE_WIDTH" },
- { 0x1001, "GL_TEXTURE_HEIGHT" },
- { 0x1003, "GL_TEXTURE_COMPONENTS" },
- { 0x1004, "GL_TEXTURE_BORDER_COLOR" },
- { 0x1005, "GL_TEXTURE_BORDER" },
- { 0x1100, "GL_DONT_CARE" },
- { 0x1101, "GL_FASTEST" },
- { 0x1102, "GL_NICEST" },
- { 0x1200, "GL_AMBIENT" },
- { 0x1201, "GL_DIFFUSE" },
- { 0x1202, "GL_SPECULAR" },
- { 0x1203, "GL_POSITION" },
- { 0x1204, "GL_SPOT_DIRECTION" },
- { 0x1205, "GL_SPOT_EXPONENT" },
- { 0x1206, "GL_SPOT_CUTOFF" },
- { 0x1207, "GL_CONSTANT_ATTENUATION" },
- { 0x1208, "GL_LINEAR_ATTENUATION" },
- { 0x1209, "GL_QUADRATIC_ATTENUATION" },
- { 0x1300, "GL_COMPILE" },
- { 0x1301, "GL_COMPILE_AND_EXECUTE" },
- { 0x1400, "GL_BYTE" },
- { 0x1401, "GL_UNSIGNED_BYTE" },
- { 0x1402, "GL_SHORT" },
- { 0x1403, "GL_UNSIGNED_SHORT" },
- { 0x1404, "GL_INT" },
- { 0x1405, "GL_UNSIGNED_INT" },
- { 0x1406, "GL_FLOAT" },
- { 0x1407, "GL_2_BYTES" },
- { 0x1408, "GL_3_BYTES" },
- { 0x1409, "GL_4_BYTES" },
- { 0x140A, "GL_DOUBLE" },
- { 0x140B, "GL_HALF_FLOAT" },
- { 0x140C, "GL_FIXED" },
- { 0x1500, "GL_CLEAR" },
- { 0x1501, "GL_AND" },
- { 0x1502, "GL_AND_REVERSE" },
- { 0x1503, "GL_COPY" },
- { 0x1504, "GL_AND_INVERTED" },
- { 0x1505, "GL_NOOP" },
- { 0x1506, "GL_XOR" },
- { 0x1507, "GL_OR" },
- { 0x1508, "GL_NOR" },
- { 0x1509, "GL_EQUIV" },
- { 0x150A, "GL_INVERT" },
- { 0x150B, "GL_OR_REVERSE" },
- { 0x150C, "GL_COPY_INVERTED" },
- { 0x150D, "GL_OR_INVERTED" },
- { 0x150E, "GL_NAND" },
- { 0x150F, "GL_SET" },
- { 0x1600, "GL_EMISSION" },
- { 0x1601, "GL_SHININESS" },
- { 0x1602, "GL_AMBIENT_AND_DIFFUSE" },
- { 0x1603, "GL_COLOR_INDEXES" },
- { 0x1700, "GL_MODELVIEW" },
- { 0x1701, "GL_PROJECTION" },
- { 0x1702, "GL_TEXTURE" },
- { 0x1800, "GL_COLOR" },
- { 0x1801, "GL_DEPTH" },
- { 0x1802, "GL_STENCIL" },
- { 0x1900, "GL_COLOR_INDEX" },
- { 0x1901, "GL_STENCIL_INDEX" },
- { 0x1902, "GL_DEPTH_COMPONENT" },
- { 0x1903, "GL_RED" },
- { 0x1904, "GL_GREEN" },
- { 0x1905, "GL_BLUE" },
- { 0x1906, "GL_ALPHA" },
- { 0x1907, "GL_RGB" },
- { 0x1908, "GL_RGBA" },
- { 0x1909, "GL_LUMINANCE" },
- { 0x190A, "GL_LUMINANCE_ALPHA" },
- { 0x1A00, "GL_BITMAP" },
- { 0x1B00, "GL_POINT" },
- { 0x1B01, "GL_LINE" },
- { 0x1B02, "GL_FILL" },
- { 0x1C00, "GL_RENDER" },
- { 0x1C01, "GL_FEEDBACK" },
- { 0x1C02, "GL_SELECT" },
- { 0x1D00, "GL_FLAT" },
- { 0x1D01, "GL_SMOOTH" },
- { 0x1E00, "GL_KEEP" },
- { 0x1E01, "GL_REPLACE" },
- { 0x1E02, "GL_INCR" },
- { 0x1E03, "GL_DECR" },
- { 0x1F00, "GL_VENDOR" },
- { 0x1F01, "GL_RENDERER" },
- { 0x1F02, "GL_VERSION" },
- { 0x1F03, "GL_EXTENSIONS" },
- { 0x2000, "GL_S" },
- { 0x2001, "GL_T" },
- { 0x2002, "GL_R" },
- { 0x2003, "GL_Q" },
- { 0x2100, "GL_MODULATE" },
- { 0x2101, "GL_DECAL" },
- { 0x2200, "GL_TEXTURE_ENV_MODE" },
- { 0x2201, "GL_TEXTURE_ENV_COLOR" },
- { 0x2300, "GL_TEXTURE_ENV" },
- { 0x2400, "GL_EYE_LINEAR" },
- { 0x2401, "GL_OBJECT_LINEAR" },
- { 0x2402, "GL_SPHERE_MAP" },
- { 0x2500, "GL_TEXTURE_GEN_MODE" },
- { 0x2501, "GL_OBJECT_PLANE" },
- { 0x2502, "GL_EYE_PLANE" },
- { 0x2600, "GL_NEAREST" },
- { 0x2601, "GL_LINEAR" },
- { 0x2700, "GL_NEAREST_MIPMAP_NEAREST" },
- { 0x2701, "GL_LINEAR_MIPMAP_NEAREST" },
- { 0x2702, "GL_NEAREST_MIPMAP_LINEAR" },
- { 0x2703, "GL_LINEAR_MIPMAP_LINEAR" },
- { 0x2800, "GL_TEXTURE_MAG_FILTER" },
- { 0x2801, "GL_TEXTURE_MIN_FILTER" },
- { 0x2802, "GL_TEXTURE_WRAP_S" },
- { 0x2803, "GL_TEXTURE_WRAP_T" },
- { 0x2900, "GL_CLAMP" },
- { 0x2901, "GL_REPEAT" },
- { 0x2A00, "GL_POLYGON_OFFSET_UNITS" },
- { 0x2A01, "GL_POLYGON_OFFSET_POINT" },
- { 0x2A02, "GL_POLYGON_OFFSET_LINE" },
- { 0x2A10, "GL_R3_G3_B2" },
- { 0x2A20, "GL_V2F" },
- { 0x2A21, "GL_V3F" },
- { 0x2A22, "GL_C4UB_V2F" },
- { 0x2A23, "GL_C4UB_V3F" },
- { 0x2A24, "GL_C3F_V3F" },
- { 0x2A25, "GL_N3F_V3F" },
- { 0x2A26, "GL_C4F_N3F_V3F" },
- { 0x2A27, "GL_T2F_V3F" },
- { 0x2A28, "GL_T4F_V4F" },
- { 0x2A29, "GL_T2F_C4UB_V3F" },
- { 0x2A2A, "GL_T2F_C3F_V3F" },
- { 0x2A2B, "GL_T2F_N3F_V3F" },
- { 0x2A2C, "GL_T2F_C4F_N3F_V3F" },
- { 0x2A2D, "GL_T4F_C4F_N3F_V4F" },
- { 0x3000, "GL_CLIP_DISTANCE0" },
- { 0x3001, "GL_CLIP_DISTANCE1" },
- { 0x3002, "GL_CLIP_DISTANCE2" },
- { 0x3003, "GL_CLIP_DISTANCE3" },
- { 0x3004, "GL_CLIP_DISTANCE4" },
- { 0x3005, "GL_CLIP_DISTANCE5" },
- { 0x3006, "GL_CLIP_DISTANCE6" },
- { 0x3007, "GL_CLIP_DISTANCE7" },
- { 0x4000, "GL_LIGHT0" },
- { 0x4001, "GL_LIGHT1" },
- { 0x4002, "GL_LIGHT2" },
- { 0x4003, "GL_LIGHT3" },
- { 0x4004, "GL_LIGHT4" },
- { 0x4005, "GL_LIGHT5" },
- { 0x4006, "GL_LIGHT6" },
- { 0x4007, "GL_LIGHT7" },
- /* This should be included, but it's value collides with GL_HINT_BIT. The
- * generator script picks GL_HINT_BIT because it prefers names that lack an
- * extension suffix.
+ /* An enum with "_BIT" that shouldn't get stripped out when we drop most
+ * "*_BIT" enums.
*/
-/* { 0x8000, "GL_ABGR_EXT" }, */
- { 0x8000, "GL_HINT_BIT" },
+ { 0x0d55, "GL_ALPHA_BITS" },
- { 0x8001, "GL_CONSTANT_COLOR" },
- { 0x8002, "GL_ONE_MINUS_CONSTANT_COLOR" },
- { 0x8003, "GL_CONSTANT_ALPHA" },
- { 0x8004, "GL_ONE_MINUS_CONSTANT_ALPHA" },
- { 0x8005, "GL_BLEND_COLOR" },
- { 0x8006, "GL_FUNC_ADD" },
- { 0x8007, "GL_MIN" },
- { 0x8008, "GL_MAX" },
- { 0x8009, "GL_BLEND_EQUATION" },
- { 0x800A, "GL_FUNC_SUBTRACT" },
- { 0x800B, "GL_FUNC_REVERSE_SUBTRACT" },
- { 0x8010, "GL_CONVOLUTION_1D" },
- { 0x8011, "GL_CONVOLUTION_2D" },
- { 0x8012, "GL_SEPARABLE_2D" },
- { 0x8013, "GL_CONVOLUTION_BORDER_MODE" },
- { 0x8014, "GL_CONVOLUTION_FILTER_SCALE" },
- { 0x8015, "GL_CONVOLUTION_FILTER_BIAS" },
- { 0x8016, "GL_REDUCE" },
- { 0x8017, "GL_CONVOLUTION_FORMAT" },
- { 0x8018, "GL_CONVOLUTION_WIDTH" },
- { 0x8019, "GL_CONVOLUTION_HEIGHT" },
- { 0x801A, "GL_MAX_CONVOLUTION_WIDTH" },
- { 0x801B, "GL_MAX_CONVOLUTION_HEIGHT" },
- { 0x801C, "GL_POST_CONVOLUTION_RED_SCALE" },
- { 0x801D, "GL_POST_CONVOLUTION_GREEN_SCALE" },
- { 0x801E, "GL_POST_CONVOLUTION_BLUE_SCALE" },
- { 0x801F, "GL_POST_CONVOLUTION_ALPHA_SCALE" },
- { 0x8020, "GL_POST_CONVOLUTION_RED_BIAS" },
- { 0x8021, "GL_POST_CONVOLUTION_GREEN_BIAS" },
- { 0x8022, "GL_POST_CONVOLUTION_BLUE_BIAS" },
- { 0x8023, "GL_POST_CONVOLUTION_ALPHA_BIAS" },
- { 0x8024, "GL_HISTOGRAM" },
- { 0x8025, "GL_PROXY_HISTOGRAM" },
- { 0x8026, "GL_HISTOGRAM_WIDTH" },
- { 0x8027, "GL_HISTOGRAM_FORMAT" },
- { 0x8028, "GL_HISTOGRAM_RED_SIZE" },
- { 0x8029, "GL_HISTOGRAM_GREEN_SIZE" },
- { 0x802A, "GL_HISTOGRAM_BLUE_SIZE" },
- { 0x802B, "GL_HISTOGRAM_ALPHA_SIZE" },
- { 0x802C, "GL_HISTOGRAM_LUMINANCE_SIZE" },
- { 0x802D, "GL_HISTOGRAM_SINK" },
- { 0x802E, "GL_MINMAX" },
- { 0x802F, "GL_MINMAX_FORMAT" },
- { 0x8030, "GL_MINMAX_SINK" },
- { 0x8031, "GL_TABLE_TOO_LARGE_EXT" },
- { 0x8032, "GL_UNSIGNED_BYTE_3_3_2" },
- { 0x8033, "GL_UNSIGNED_SHORT_4_4_4_4" },
- { 0x8034, "GL_UNSIGNED_SHORT_5_5_5_1" },
- { 0x8035, "GL_UNSIGNED_INT_8_8_8_8" },
- { 0x8036, "GL_UNSIGNED_INT_10_10_10_2" },
- { 0x8037, "GL_POLYGON_OFFSET_FILL" },
- { 0x8038, "GL_POLYGON_OFFSET_FACTOR" },
- { 0x8039, "GL_POLYGON_OFFSET_BIAS_EXT" },
- { 0x803A, "GL_RESCALE_NORMAL" },
- { 0x803B, "GL_ALPHA4" },
- { 0x803C, "GL_ALPHA8" },
- { 0x803D, "GL_ALPHA12" },
- { 0x803E, "GL_ALPHA16" },
- { 0x803F, "GL_LUMINANCE4" },
- { 0x8040, "GL_LUMINANCE8" },
- { 0x8041, "GL_LUMINANCE12" },
- { 0x8042, "GL_LUMINANCE16" },
- { 0x8043, "GL_LUMINANCE4_ALPHA4" },
- { 0x8044, "GL_LUMINANCE6_ALPHA2" },
- { 0x8045, "GL_LUMINANCE8_ALPHA8" },
- { 0x8046, "GL_LUMINANCE12_ALPHA4" },
- { 0x8047, "GL_LUMINANCE12_ALPHA12" },
- { 0x8048, "GL_LUMINANCE16_ALPHA16" },
- { 0x8049, "GL_INTENSITY" },
- { 0x804A, "GL_INTENSITY4" },
- { 0x804B, "GL_INTENSITY8" },
- { 0x804C, "GL_INTENSITY12" },
- { 0x804D, "GL_INTENSITY16" },
- { 0x804E, "GL_RGB2_EXT" },
- { 0x804F, "GL_RGB4" },
- { 0x8050, "GL_RGB5" },
- { 0x8051, "GL_RGB8" },
- { 0x8052, "GL_RGB10" },
- { 0x8053, "GL_RGB12" },
- { 0x8054, "GL_RGB16" },
- { 0x8055, "GL_RGBA2" },
- { 0x8056, "GL_RGBA4" },
- { 0x8057, "GL_RGB5_A1" },
- { 0x8058, "GL_RGBA8" },
- { 0x8059, "GL_RGB10_A2" },
- { 0x805A, "GL_RGBA12" },
- { 0x805B, "GL_RGBA16" },
- { 0x805C, "GL_TEXTURE_RED_SIZE" },
- { 0x805D, "GL_TEXTURE_GREEN_SIZE" },
- { 0x805E, "GL_TEXTURE_BLUE_SIZE" },
- { 0x805F, "GL_TEXTURE_ALPHA_SIZE" },
- { 0x8060, "GL_TEXTURE_LUMINANCE_SIZE" },
- { 0x8061, "GL_TEXTURE_INTENSITY_SIZE" },
+ /* An EXT-only extension that we never expect to see show up in ARB/core.
+ */
{ 0x8062, "GL_REPLACE_EXT" },
- { 0x8063, "GL_PROXY_TEXTURE_1D" },
- { 0x8064, "GL_PROXY_TEXTURE_2D" },
- { 0x8065, "GL_TEXTURE_TOO_LARGE_EXT" },
- { 0x8066, "GL_TEXTURE_PRIORITY" },
- { 0x8067, "GL_TEXTURE_RESIDENT" },
- { 0x8068, "GL_TEXTURE_BINDING_1D" },
- { 0x8069, "GL_TEXTURE_BINDING_2D" },
- { 0x806A, "GL_TEXTURE_BINDING_3D" },
- { 0x806B, "GL_PACK_SKIP_IMAGES" },
- { 0x806C, "GL_PACK_IMAGE_HEIGHT" },
- { 0x806D, "GL_UNPACK_SKIP_IMAGES" },
- { 0x806E, "GL_UNPACK_IMAGE_HEIGHT" },
- { 0x806F, "GL_TEXTURE_3D" },
- { 0x8070, "GL_PROXY_TEXTURE_3D" },
- { 0x8071, "GL_TEXTURE_DEPTH" },
- { 0x8072, "GL_TEXTURE_WRAP_R" },
- { 0x8073, "GL_MAX_3D_TEXTURE_SIZE" },
- { 0x8074, "GL_VERTEX_ARRAY" },
- { 0x8075, "GL_NORMAL_ARRAY" },
- { 0x8076, "GL_COLOR_ARRAY" },
- { 0x8077, "GL_INDEX_ARRAY" },
- { 0x8078, "GL_TEXTURE_COORD_ARRAY" },
- { 0x8079, "GL_EDGE_FLAG_ARRAY" },
- { 0x807A, "GL_VERTEX_ARRAY_SIZE" },
- { 0x807B, "GL_VERTEX_ARRAY_TYPE" },
- { 0x807C, "GL_VERTEX_ARRAY_STRIDE" },
- { 0x807D, "GL_VERTEX_ARRAY_COUNT_EXT" },
- { 0x807E, "GL_NORMAL_ARRAY_TYPE" },
- { 0x807F, "GL_NORMAL_ARRAY_STRIDE" },
- { 0x8080, "GL_NORMAL_ARRAY_COUNT_EXT" },
- { 0x8081, "GL_COLOR_ARRAY_SIZE" },
- { 0x8082, "GL_COLOR_ARRAY_TYPE" },
- { 0x8083, "GL_COLOR_ARRAY_STRIDE" },
- { 0x8084, "GL_COLOR_ARRAY_COUNT_EXT" },
- { 0x8085, "GL_INDEX_ARRAY_TYPE" },
- { 0x8086, "GL_INDEX_ARRAY_STRIDE" },
- { 0x8087, "GL_INDEX_ARRAY_COUNT_EXT" },
- { 0x8088, "GL_TEXTURE_COORD_ARRAY_SIZE" },
- { 0x8089, "GL_TEXTURE_COORD_ARRAY_TYPE" },
- { 0x808A, "GL_TEXTURE_COORD_ARRAY_STRIDE" },
- { 0x808B, "GL_TEXTURE_COORD_ARRAY_COUNT_EXT" },
- { 0x808C, "GL_EDGE_FLAG_ARRAY_STRIDE" },
- { 0x808D, "GL_EDGE_FLAG_ARRAY_COUNT_EXT" },
- { 0x808E, "GL_VERTEX_ARRAY_POINTER" },
- { 0x808F, "GL_NORMAL_ARRAY_POINTER" },
- { 0x8090, "GL_COLOR_ARRAY_POINTER" },
- { 0x8091, "GL_INDEX_ARRAY_POINTER" },
- { 0x8092, "GL_TEXTURE_COORD_ARRAY_POINTER" },
- { 0x8093, "GL_EDGE_FLAG_ARRAY_POINTER" },
- { 0x809D, "GL_MULTISAMPLE" },
- { 0x809E, "GL_SAMPLE_ALPHA_TO_COVERAGE" },
- { 0x809F, "GL_SAMPLE_ALPHA_TO_ONE" },
- { 0x80A0, "GL_SAMPLE_COVERAGE" },
- { 0x80A8, "GL_SAMPLE_BUFFERS" },
- { 0x80A9, "GL_SAMPLES" },
- { 0x80AA, "GL_SAMPLE_COVERAGE_VALUE" },
- { 0x80AB, "GL_SAMPLE_COVERAGE_INVERT" },
- { 0x80B1, "GL_COLOR_MATRIX" },
- { 0x80B2, "GL_COLOR_MATRIX_STACK_DEPTH" },
- { 0x80B3, "GL_MAX_COLOR_MATRIX_STACK_DEPTH" },
- { 0x80B4, "GL_POST_COLOR_MATRIX_RED_SCALE" },
- { 0x80B5, "GL_POST_COLOR_MATRIX_GREEN_SCALE" },
- { 0x80B6, "GL_POST_COLOR_MATRIX_BLUE_SCALE" },
- { 0x80B7, "GL_POST_COLOR_MATRIX_ALPHA_SCALE" },
- { 0x80B8, "GL_POST_COLOR_MATRIX_RED_BIAS" },
- { 0x80B9, "GL_POST_COLOR_MATRIX_GREEN_BIAS" },
- { 0x80BA, "GL_POST_COLOR_MATRIX_BLUE_BIAS" },
- { 0x80BB, "GL_POST_COLOR_MATRIX_ALPHA_BIAS" },
- { 0x80BC, "GL_TEXTURE_COLOR_TABLE_SGI" },
- { 0x80BD, "GL_PROXY_TEXTURE_COLOR_TABLE_SGI" },
- { 0x80BF, "GL_TEXTURE_COMPARE_FAIL_VALUE_ARB" },
- { 0x80C8, "GL_BLEND_DST_RGB" },
- { 0x80C9, "GL_BLEND_SRC_RGB" },
- { 0x80CA, "GL_BLEND_DST_ALPHA" },
- { 0x80CB, "GL_BLEND_SRC_ALPHA" },
- { 0x80D0, "GL_COLOR_TABLE" },
- { 0x80D1, "GL_POST_CONVOLUTION_COLOR_TABLE" },
- { 0x80D2, "GL_POST_COLOR_MATRIX_COLOR_TABLE" },
- { 0x80D3, "GL_PROXY_COLOR_TABLE" },
- { 0x80D4, "GL_PROXY_POST_CONVOLUTION_COLOR_TABLE" },
- { 0x80D5, "GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE" },
- { 0x80D6, "GL_COLOR_TABLE_SCALE" },
- { 0x80D7, "GL_COLOR_TABLE_BIAS" },
- { 0x80D8, "GL_COLOR_TABLE_FORMAT" },
- { 0x80D9, "GL_COLOR_TABLE_WIDTH" },
- { 0x80DA, "GL_COLOR_TABLE_RED_SIZE" },
- { 0x80DB, "GL_COLOR_TABLE_GREEN_SIZE" },
- { 0x80DC, "GL_COLOR_TABLE_BLUE_SIZE" },
- { 0x80DD, "GL_COLOR_TABLE_ALPHA_SIZE" },
- { 0x80DE, "GL_COLOR_TABLE_LUMINANCE_SIZE" },
- { 0x80DF, "GL_COLOR_TABLE_INTENSITY_SIZE" },
- { 0x80E0, "GL_BGR" },
- { 0x80E1, "GL_BGRA" },
- { 0x80E8, "GL_MAX_ELEMENTS_VERTICES" },
- { 0x80E9, "GL_MAX_ELEMENTS_INDICES" },
- { 0x80ED, "GL_TEXTURE_INDEX_SIZE_EXT" },
- { 0x80F0, "GL_CLIP_VOLUME_CLIPPING_HINT_EXT" },
- { 0x8126, "GL_POINT_SIZE_MIN" },
- { 0x8127, "GL_POINT_SIZE_MAX" },
- { 0x8128, "GL_POINT_FADE_THRESHOLD_SIZE" },
- { 0x8129, "GL_POINT_DISTANCE_ATTENUATION" },
- { 0x812D, "GL_CLAMP_TO_BORDER" },
- { 0x812F, "GL_CLAMP_TO_EDGE" },
- { 0x813A, "GL_TEXTURE_MIN_LOD" },
- { 0x813B, "GL_TEXTURE_MAX_LOD" },
- { 0x813C, "GL_TEXTURE_BASE_LEVEL" },
- { 0x813D, "GL_TEXTURE_MAX_LEVEL" },
- { 0x8150, "GL_IGNORE_BORDER_HP" },
- { 0x8151, "GL_CONSTANT_BORDER_HP" },
- { 0x8153, "GL_REPLICATE_BORDER_HP" },
- { 0x8154, "GL_CONVOLUTION_BORDER_COLOR" },
- { 0x8165, "GL_OCCLUSION_TEST_HP" },
- { 0x8166, "GL_OCCLUSION_TEST_RESULT_HP" },
- { 0x8170, "GL_LINEAR_CLIPMAP_LINEAR_SGIX" },
- { 0x8171, "GL_TEXTURE_CLIPMAP_CENTER_SGIX" },
- { 0x8172, "GL_TEXTURE_CLIPMAP_FRAME_SGIX" },
- { 0x8173, "GL_TEXTURE_CLIPMAP_OFFSET_SGIX" },
- { 0x8174, "GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX" },
- { 0x8175, "GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX" },
- { 0x8176, "GL_TEXTURE_CLIPMAP_DEPTH_SGIX" },
- { 0x8177, "GL_MAX_CLIPMAP_DEPTH_SGIX" },
- { 0x8178, "GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX" },
- { 0x8179, "GL_POST_TEXTURE_FILTER_BIAS_SGIX" },
- { 0x817A, "GL_POST_TEXTURE_FILTER_SCALE_SGIX" },
- { 0x817B, "GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX" },
- { 0x817C, "GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX" },
- { 0x818E, "GL_TEXTURE_LOD_BIAS_S_SGIX" },
- { 0x818F, "GL_TEXTURE_LOD_BIAS_T_SGIX" },
- { 0x8190, "GL_TEXTURE_LOD_BIAS_R_SGIX" },
- { 0x8191, "GL_GENERATE_MIPMAP" },
- { 0x8192, "GL_GENERATE_MIPMAP_HINT" },
- { 0x8198, "GL_FOG_OFFSET_SGIX" },
- { 0x8199, "GL_FOG_OFFSET_VALUE_SGIX" },
- { 0x819A, "GL_TEXTURE_COMPARE_SGIX" },
- { 0x819B, "GL_TEXTURE_COMPARE_OPERATOR_SGIX" },
- { 0x819C, "GL_TEXTURE_LEQUAL_R_SGIX" },
- { 0x819D, "GL_TEXTURE_GEQUAL_R_SGIX" },
- { 0x81A5, "GL_DEPTH_COMPONENT16" },
- { 0x81A6, "GL_DEPTH_COMPONENT24" },
- { 0x81A7, "GL_DEPTH_COMPONENT32" },
- { 0x81A8, "GL_ARRAY_ELEMENT_LOCK_FIRST_EXT" },
- { 0x81A9, "GL_ARRAY_ELEMENT_LOCK_COUNT_EXT" },
- { 0x81D4, "GL_WRAP_BORDER_SUN" },
- { 0x81EF, "GL_TEXTURE_COLOR_WRITEMASK_SGIS" },
- { 0x81F8, "GL_LIGHT_MODEL_COLOR_CONTROL" },
- { 0x81F9, "GL_SINGLE_COLOR" },
- { 0x81FA, "GL_SEPARATE_SPECULAR_COLOR" },
- { 0x81FB, "GL_SHARED_TEXTURE_PALETTE_EXT" },
- { 0x8210, "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING" },
- { 0x8211, "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE" },
- { 0x8212, "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE" },
- { 0x8213, "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE" },
- { 0x8214, "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE" },
- { 0x8215, "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE" },
- { 0x8216, "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE" },
- { 0x8217, "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE" },
- { 0x8218, "GL_FRAMEBUFFER_DEFAULT" },
- { 0x8219, "GL_FRAMEBUFFER_UNDEFINED" },
- { 0x821A, "GL_DEPTH_STENCIL_ATTACHMENT" },
- { 0x821B, "GL_MAJOR_VERSION" },
- { 0x821C, "GL_MINOR_VERSION" },
- { 0x821D, "GL_NUM_EXTENSIONS" },
- { 0x821E, "GL_CONTEXT_FLAGS" },
- { 0x8222, "GL_INDEX" },
- { 0x8223, "GL_DEPTH_BUFFER" },
- { 0x8224, "GL_STENCIL_BUFFER" },
- { 0x8225, "GL_COMPRESSED_RED" },
- { 0x8226, "GL_COMPRESSED_RG" },
- { 0x8227, "GL_RG" },
- { 0x8228, "GL_RG_INTEGER" },
- { 0x8229, "GL_R8" },
- { 0x822A, "GL_R16" },
- { 0x822B, "GL_RG8" },
- { 0x822C, "GL_RG16" },
- { 0x822D, "GL_R16F" },
- { 0x822E, "GL_R32F" },
- { 0x822F, "GL_RG16F" },
- { 0x8230, "GL_RG32F" },
- { 0x8231, "GL_R8I" },
- { 0x8232, "GL_R8UI" },
- { 0x8233, "GL_R16I" },
- { 0x8234, "GL_R16UI" },
- { 0x8235, "GL_R32I" },
- { 0x8236, "GL_R32UI" },
- { 0x8237, "GL_RG8I" },
- { 0x8238, "GL_RG8UI" },
- { 0x8239, "GL_RG16I" },
- { 0x823A, "GL_RG16UI" },
- { 0x823B, "GL_RG32I" },
- { 0x823C, "GL_RG32UI" },
- { 0x8242, "GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB" },
- { 0x8243, "GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB" },
- { 0x8244, "GL_DEBUG_CALLBACK_FUNCTION_ARB" },
- { 0x8245, "GL_DEBUG_CALLBACK_USER_PARAM_ARB" },
- { 0x8246, "GL_DEBUG_SOURCE_API_ARB" },
- { 0x8247, "GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB" },
- { 0x8248, "GL_DEBUG_SOURCE_SHADER_COMPILER_ARB" },
- { 0x8249, "GL_DEBUG_SOURCE_THIRD_PARTY_ARB" },
- { 0x824A, "GL_DEBUG_SOURCE_APPLICATION_ARB" },
- { 0x824B, "GL_DEBUG_SOURCE_OTHER_ARB" },
- { 0x824C, "GL_DEBUG_TYPE_ERROR_ARB" },
- { 0x824D, "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB" },
- { 0x824E, "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB" },
- { 0x824F, "GL_DEBUG_TYPE_PORTABILITY_ARB" },
- { 0x8250, "GL_DEBUG_TYPE_PERFORMANCE_ARB" },
- { 0x8251, "GL_DEBUG_TYPE_OTHER_ARB" },
- { 0x8252, "GL_LOSE_CONTEXT_ON_RESET_ARB" },
- { 0x8253, "GL_GUILTY_CONTEXT_RESET_ARB" },
- { 0x8254, "GL_INNOCENT_CONTEXT_RESET_ARB" },
- { 0x8255, "GL_UNKNOWN_CONTEXT_RESET_ARB" },
- { 0x8256, "GL_RESET_NOTIFICATION_STRATEGY_ARB" },
- { 0x8257, "GL_PROGRAM_BINARY_RETRIEVABLE_HINT" },
- { 0x8261, "GL_NO_RESET_NOTIFICATION_ARB" },
- { 0x826E, "GL_MAX_UNIFORM_LOCATIONS" },
- { 0x82DF, "GL_TEXTURE_IMMUTABLE_LEVELS" },
- { 0x8362, "GL_UNSIGNED_BYTE_2_3_3_REV" },
- { 0x8363, "GL_UNSIGNED_SHORT_5_6_5" },
- { 0x8364, "GL_UNSIGNED_SHORT_5_6_5_REV" },
- { 0x8365, "GL_UNSIGNED_SHORT_4_4_4_4_REV" },
- { 0x8366, "GL_UNSIGNED_SHORT_1_5_5_5_REV" },
- { 0x8367, "GL_UNSIGNED_INT_8_8_8_8_REV" },
- { 0x8368, "GL_UNSIGNED_INT_2_10_10_10_REV" },
- { 0x8369, "GL_TEXTURE_MAX_CLAMP_S_SGIX" },
- { 0x836A, "GL_TEXTURE_MAX_CLAMP_T_SGIX" },
- { 0x836B, "GL_TEXTURE_MAX_CLAMP_R_SGIX" },
- { 0x8370, "GL_MIRRORED_REPEAT" },
- { 0x83A0, "GL_RGB_S3TC" },
- { 0x83A1, "GL_RGB4_S3TC" },
- { 0x83A2, "GL_RGBA_S3TC" },
- { 0x83A3, "GL_RGBA4_S3TC" },
- { 0x83F0, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT" },
- { 0x83F1, "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" },
- { 0x83F2, "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE" },
- { 0x83F3, "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE" },
- { 0x83F9, "GL_PERFQUERY_DONOT_FLUSH_INTEL" },
- { 0x83FA, "GL_PERFQUERY_FLUSH_INTEL" },
- { 0x83FB, "GL_PERFQUERY_WAIT_INTEL" },
- { 0x844D, "GL_NEAREST_CLIPMAP_NEAREST_SGIX" },
- { 0x844E, "GL_NEAREST_CLIPMAP_LINEAR_SGIX" },
- { 0x844F, "GL_LINEAR_CLIPMAP_NEAREST_SGIX" },
- { 0x8450, "GL_FOG_COORDINATE_SOURCE" },
- { 0x8451, "GL_FOG_COORD" },
- { 0x8452, "GL_FRAGMENT_DEPTH" },
- { 0x8453, "GL_CURRENT_FOG_COORD" },
- { 0x8454, "GL_FOG_COORDINATE_ARRAY_TYPE" },
- { 0x8455, "GL_FOG_COORDINATE_ARRAY_STRIDE" },
- { 0x8456, "GL_FOG_COORDINATE_ARRAY_POINTER" },
- { 0x8457, "GL_FOG_COORDINATE_ARRAY" },
- { 0x8458, "GL_COLOR_SUM" },
- { 0x8459, "GL_CURRENT_SECONDARY_COLOR" },
- { 0x845A, "GL_SECONDARY_COLOR_ARRAY_SIZE" },
- { 0x845B, "GL_SECONDARY_COLOR_ARRAY_TYPE" },
- { 0x845C, "GL_SECONDARY_COLOR_ARRAY_STRIDE" },
- { 0x845D, "GL_SECONDARY_COLOR_ARRAY_POINTER" },
- { 0x845E, "GL_SECONDARY_COLOR_ARRAY" },
- { 0x845F, "GL_CURRENT_RASTER_SECONDARY_COLOR" },
- { 0x846D, "GL_ALIASED_POINT_SIZE_RANGE" },
- { 0x846E, "GL_ALIASED_LINE_WIDTH_RANGE" },
- { 0x84C0, "GL_TEXTURE0" },
- { 0x84C1, "GL_TEXTURE1" },
- { 0x84C2, "GL_TEXTURE2" },
- { 0x84C3, "GL_TEXTURE3" },
- { 0x84C4, "GL_TEXTURE4" },
- { 0x84C5, "GL_TEXTURE5" },
- { 0x84C6, "GL_TEXTURE6" },
- { 0x84C7, "GL_TEXTURE7" },
- { 0x84C8, "GL_TEXTURE8" },
- { 0x84C9, "GL_TEXTURE9" },
- { 0x84CA, "GL_TEXTURE10" },
- { 0x84CB, "GL_TEXTURE11" },
- { 0x84CC, "GL_TEXTURE12" },
- { 0x84CD, "GL_TEXTURE13" },
- { 0x84CE, "GL_TEXTURE14" },
- { 0x84CF, "GL_TEXTURE15" },
- { 0x84D0, "GL_TEXTURE16" },
- { 0x84D1, "GL_TEXTURE17" },
- { 0x84D2, "GL_TEXTURE18" },
- { 0x84D3, "GL_TEXTURE19" },
- { 0x84D4, "GL_TEXTURE20" },
- { 0x84D5, "GL_TEXTURE21" },
- { 0x84D6, "GL_TEXTURE22" },
- { 0x84D7, "GL_TEXTURE23" },
- { 0x84D8, "GL_TEXTURE24" },
- { 0x84D9, "GL_TEXTURE25" },
- { 0x84DA, "GL_TEXTURE26" },
- { 0x84DB, "GL_TEXTURE27" },
- { 0x84DC, "GL_TEXTURE28" },
- { 0x84DD, "GL_TEXTURE29" },
- { 0x84DE, "GL_TEXTURE30" },
- { 0x84DF, "GL_TEXTURE31" },
- { 0x84E0, "GL_ACTIVE_TEXTURE" },
- { 0x84E1, "GL_CLIENT_ACTIVE_TEXTURE" },
- { 0x84E2, "GL_MAX_TEXTURE_UNITS" },
- { 0x84E3, "GL_TRANSPOSE_MODELVIEW_MATRIX" },
- { 0x84E4, "GL_TRANSPOSE_PROJECTION_MATRIX" },
- { 0x84E5, "GL_TRANSPOSE_TEXTURE_MATRIX" },
- { 0x84E6, "GL_TRANSPOSE_COLOR_MATRIX" },
- { 0x84E7, "GL_SUBTRACT" },
- { 0x84E8, "GL_MAX_RENDERBUFFER_SIZE" },
- { 0x84E9, "GL_COMPRESSED_ALPHA" },
- { 0x84EA, "GL_COMPRESSED_LUMINANCE" },
- { 0x84EB, "GL_COMPRESSED_LUMINANCE_ALPHA" },
- { 0x84EC, "GL_COMPRESSED_INTENSITY" },
- { 0x84ED, "GL_COMPRESSED_RGB" },
- { 0x84EE, "GL_COMPRESSED_RGBA" },
- { 0x84EF, "GL_TEXTURE_COMPRESSION_HINT" },
- { 0x84F5, "GL_TEXTURE_RECTANGLE" },
- { 0x84F6, "GL_TEXTURE_BINDING_RECTANGLE" },
- { 0x84F7, "GL_PROXY_TEXTURE_RECTANGLE" },
- { 0x84F8, "GL_MAX_RECTANGLE_TEXTURE_SIZE" },
- { 0x84F9, "GL_DEPTH_STENCIL" },
- { 0x84FA, "GL_UNSIGNED_INT_24_8" },
- { 0x84FD, "GL_MAX_TEXTURE_LOD_BIAS" },
- { 0x84FE, "GL_TEXTURE_MAX_ANISOTROPY_EXT" },
- { 0x84FF, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT" },
- { 0x8500, "GL_TEXTURE_FILTER_CONTROL" },
- { 0x8501, "GL_TEXTURE_LOD_BIAS" },
+
+ /* An extension that made it from vendor to _EXT, but we never expect to
+ * see go farther.
+ */
+ { 0x80a1, "GL_1PASS_EXT" },
+
+ /* A vendor-only extension that we never expect to see show up in
+ * EXT/ARB/core.
+ */
{ 0x8503, "GL_COMBINE4_NV" },
- { 0x8504, "GL_MAX_SHININESS_NV" },
- { 0x8505, "GL_MAX_SPOT_EXPONENT_NV" },
- { 0x8507, "GL_INCR_WRAP" },
- { 0x8508, "GL_DECR_WRAP" },
- { 0x850A, "GL_MODELVIEW1_ARB" },
- { 0x8511, "GL_NORMAL_MAP" },
- { 0x8512, "GL_REFLECTION_MAP" },
- { 0x8513, "GL_TEXTURE_CUBE_MAP" },
- { 0x8514, "GL_TEXTURE_BINDING_CUBE_MAP" },
- { 0x8515, "GL_TEXTURE_CUBE_MAP_POSITIVE_X" },
- { 0x8516, "GL_TEXTURE_CUBE_MAP_NEGATIVE_X" },
- { 0x8517, "GL_TEXTURE_CUBE_MAP_POSITIVE_Y" },
- { 0x8518, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" },
- { 0x8519, "GL_TEXTURE_CUBE_MAP_POSITIVE_Z" },
- { 0x851A, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" },
- { 0x851B, "GL_PROXY_TEXTURE_CUBE_MAP" },
- { 0x851C, "GL_MAX_CUBE_MAP_TEXTURE_SIZE" },
- { 0x8534, "GL_MULTISAMPLE_FILTER_HINT_NV" },
- { 0x8558, "GL_PRIMITIVE_RESTART_NV" },
- { 0x8559, "GL_PRIMITIVE_RESTART_INDEX_NV" },
- { 0x855A, "GL_FOG_DISTANCE_MODE_NV" },
- { 0x855B, "GL_EYE_RADIAL_NV" },
- { 0x855C, "GL_EYE_PLANE_ABSOLUTE_NV" },
- { 0x8570, "GL_COMBINE" },
- { 0x8571, "GL_COMBINE_RGB" },
- { 0x8572, "GL_COMBINE_ALPHA" },
- { 0x8573, "GL_RGB_SCALE" },
- { 0x8574, "GL_ADD_SIGNED" },
- { 0x8575, "GL_INTERPOLATE" },
- { 0x8576, "GL_CONSTANT" },
- { 0x8577, "GL_PRIMARY_COLOR" },
- { 0x8578, "GL_PREVIOUS" },
- { 0x8580, "GL_SOURCE0_RGB" },
- { 0x8581, "GL_SOURCE1_RGB" },
- { 0x8582, "GL_SOURCE2_RGB" },
- { 0x8583, "GL_SOURCE3_RGB_NV" },
- { 0x8588, "GL_SOURCE0_ALPHA" },
- { 0x8589, "GL_SOURCE1_ALPHA" },
- { 0x858A, "GL_SOURCE2_ALPHA" },
- { 0x858B, "GL_SOURCE3_ALPHA_NV" },
- { 0x8590, "GL_OPERAND0_RGB" },
- { 0x8591, "GL_OPERAND1_RGB" },
- { 0x8592, "GL_OPERAND2_RGB" },
- { 0x8593, "GL_OPERAND3_RGB_NV" },
- { 0x8598, "GL_OPERAND0_ALPHA" },
- { 0x8599, "GL_OPERAND1_ALPHA" },
- { 0x859A, "GL_OPERAND2_ALPHA" },
- { 0x859B, "GL_OPERAND3_ALPHA_NV" },
- { 0x85B3, "GL_BUFFER_OBJECT_APPLE" },
- { 0x85B5, "GL_VERTEX_ARRAY_BINDING" },
- { 0x85B7, "GL_TEXTURE_RANGE_LENGTH_APPLE" },
- { 0x85B8, "GL_TEXTURE_RANGE_POINTER_APPLE" },
- { 0x85B9, "GL_YCBCR_422_APPLE" },
- { 0x85BA, "GL_UNSIGNED_SHORT_8_8_APPLE" },
- { 0x85BB, "GL_UNSIGNED_SHORT_8_8_REV_APPLE" },
- { 0x85BC, "GL_TEXTURE_STORAGE_HINT_APPLE" },
- { 0x85BD, "GL_STORAGE_PRIVATE_APPLE" },
- { 0x85BE, "GL_STORAGE_CACHED_APPLE" },
- { 0x85BF, "GL_STORAGE_SHARED_APPLE" },
- { 0x85CC, "GL_SLICE_ACCUM_SUN" },
- { 0x8614, "GL_QUAD_MESH_SUN" },
- { 0x8615, "GL_TRIANGLE_MESH_SUN" },
- { 0x8620, "GL_VERTEX_PROGRAM_ARB" },
- { 0x8621, "GL_VERTEX_STATE_PROGRAM_NV" },
- { 0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED" },
- { 0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE" },
- { 0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE" },
- { 0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE" },
- { 0x8626, "GL_CURRENT_VERTEX_ATTRIB" },
- { 0x8627, "GL_PROGRAM_LENGTH_ARB" },
- { 0x8628, "GL_PROGRAM_STRING_ARB" },
- { 0x8629, "GL_MODELVIEW_PROJECTION_NV" },
- { 0x862A, "GL_IDENTITY_NV" },
- { 0x862B, "GL_INVERSE_NV" },
- { 0x862C, "GL_TRANSPOSE_NV" },
- { 0x862D, "GL_INVERSE_TRANSPOSE_NV" },
- { 0x862E, "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB" },
- { 0x862F, "GL_MAX_PROGRAM_MATRICES_ARB" },
- { 0x8630, "GL_MATRIX0_NV" },
- { 0x8631, "GL_MATRIX1_NV" },
- { 0x8632, "GL_MATRIX2_NV" },
- { 0x8633, "GL_MATRIX3_NV" },
- { 0x8634, "GL_MATRIX4_NV" },
- { 0x8635, "GL_MATRIX5_NV" },
- { 0x8636, "GL_MATRIX6_NV" },
- { 0x8637, "GL_MATRIX7_NV" },
- { 0x8640, "GL_CURRENT_MATRIX_STACK_DEPTH_ARB" },
- { 0x8641, "GL_CURRENT_MATRIX_ARB" },
- { 0x8642, "GL_PROGRAM_POINT_SIZE" },
- { 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE" },
- { 0x8644, "GL_PROGRAM_PARAMETER_NV" },
- { 0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER" },
- { 0x8646, "GL_PROGRAM_TARGET_NV" },
- { 0x8647, "GL_PROGRAM_RESIDENT_NV" },
- { 0x8648, "GL_TRACK_MATRIX_NV" },
- { 0x8649, "GL_TRACK_MATRIX_TRANSFORM_NV" },
- { 0x864A, "GL_VERTEX_PROGRAM_BINDING_NV" },
- { 0x864B, "GL_PROGRAM_ERROR_POSITION_ARB" },
- { 0x864F, "GL_DEPTH_CLAMP" },
- { 0x8650, "GL_VERTEX_ATTRIB_ARRAY0_NV" },
- { 0x8651, "GL_VERTEX_ATTRIB_ARRAY1_NV" },
- { 0x8652, "GL_VERTEX_ATTRIB_ARRAY2_NV" },
- { 0x8653, "GL_VERTEX_ATTRIB_ARRAY3_NV" },
- { 0x8654, "GL_VERTEX_ATTRIB_ARRAY4_NV" },
- { 0x8655, "GL_VERTEX_ATTRIB_ARRAY5_NV" },
- { 0x8656, "GL_VERTEX_ATTRIB_ARRAY6_NV" },
- { 0x8657, "GL_VERTEX_ATTRIB_ARRAY7_NV" },
- { 0x8658, "GL_VERTEX_ATTRIB_ARRAY8_NV" },
- { 0x8659, "GL_VERTEX_ATTRIB_ARRAY9_NV" },
- { 0x865A, "GL_VERTEX_ATTRIB_ARRAY10_NV" },
- { 0x865B, "GL_VERTEX_ATTRIB_ARRAY11_NV" },
- { 0x865C, "GL_VERTEX_ATTRIB_ARRAY12_NV" },
- { 0x865D, "GL_VERTEX_ATTRIB_ARRAY13_NV" },
- { 0x865E, "GL_VERTEX_ATTRIB_ARRAY14_NV" },
- { 0x865F, "GL_VERTEX_ATTRIB_ARRAY15_NV" },
- { 0x8660, "GL_MAP1_VERTEX_ATTRIB0_4_NV" },
- { 0x8661, "GL_MAP1_VERTEX_ATTRIB1_4_NV" },
- { 0x8662, "GL_MAP1_VERTEX_ATTRIB2_4_NV" },
- { 0x8663, "GL_MAP1_VERTEX_ATTRIB3_4_NV" },
- { 0x8664, "GL_MAP1_VERTEX_ATTRIB4_4_NV" },
- { 0x8665, "GL_MAP1_VERTEX_ATTRIB5_4_NV" },
- { 0x8666, "GL_MAP1_VERTEX_ATTRIB6_4_NV" },
- { 0x8667, "GL_MAP1_VERTEX_ATTRIB7_4_NV" },
- { 0x8668, "GL_MAP1_VERTEX_ATTRIB8_4_NV" },
- { 0x8669, "GL_MAP1_VERTEX_ATTRIB9_4_NV" },
- { 0x866A, "GL_MAP1_VERTEX_ATTRIB10_4_NV" },
- { 0x866B, "GL_MAP1_VERTEX_ATTRIB11_4_NV" },
- { 0x866C, "GL_MAP1_VERTEX_ATTRIB12_4_NV" },
- { 0x866D, "GL_MAP1_VERTEX_ATTRIB13_4_NV" },
- { 0x866E, "GL_MAP1_VERTEX_ATTRIB14_4_NV" },
- { 0x866F, "GL_MAP1_VERTEX_ATTRIB15_4_NV" },
- { 0x8670, "GL_MAP2_VERTEX_ATTRIB0_4_NV" },
- { 0x8671, "GL_MAP2_VERTEX_ATTRIB1_4_NV" },
- { 0x8672, "GL_MAP2_VERTEX_ATTRIB2_4_NV" },
- { 0x8673, "GL_MAP2_VERTEX_ATTRIB3_4_NV" },
- { 0x8674, "GL_MAP2_VERTEX_ATTRIB4_4_NV" },
- { 0x8675, "GL_MAP2_VERTEX_ATTRIB5_4_NV" },
- { 0x8676, "GL_MAP2_VERTEX_ATTRIB6_4_NV" },
- /* Both GL_PROGRAM_BINDING_ARB and GL_MAP2_VERTEX_ATTRIB7_4_NV were
- * accidentally assigned the same value. The generator script
- * prefers ARB extension names to vendor extension names, so only
- * GL_PROGRAM_BINDING_ARB is checked.
+ /* An extension that got promoted from _EXT to _ARB, but we don't expect to
+ * see go any further.
*/
-/* { 0x8677, "GL_MAP2_VERTEX_ATTRIB7_4_NV" },*/
- { 0x8677, "GL_PROGRAM_BINDING_ARB" },
+ { 0x850a, "GL_MODELVIEW1_ARB" },
- { 0x8678, "GL_MAP2_VERTEX_ATTRIB8_4_NV" },
- { 0x8679, "GL_MAP2_VERTEX_ATTRIB9_4_NV" },
- { 0x867A, "GL_MAP2_VERTEX_ATTRIB10_4_NV" },
- { 0x867B, "GL_MAP2_VERTEX_ATTRIB11_4_NV" },
- { 0x867C, "GL_MAP2_VERTEX_ATTRIB12_4_NV" },
- { 0x867D, "GL_MAP2_VERTEX_ATTRIB13_4_NV" },
- { 0x867E, "GL_MAP2_VERTEX_ATTRIB14_4_NV" },
- { 0x867F, "GL_MAP2_VERTEX_ATTRIB15_4_NV" },
- { 0x86A0, "GL_TEXTURE_COMPRESSED_IMAGE_SIZE" },
- { 0x86A1, "GL_TEXTURE_COMPRESSED" },
- { 0x86A2, "GL_NUM_COMPRESSED_TEXTURE_FORMATS" },
- { 0x86A3, "GL_COMPRESSED_TEXTURE_FORMATS" },
- { 0x86A4, "GL_MAX_VERTEX_UNITS_ARB" },
- { 0x86A5, "GL_ACTIVE_VERTEX_UNITS_ARB" },
- { 0x86A6, "GL_WEIGHT_SUM_UNITY_ARB" },
- { 0x86A7, "GL_VERTEX_BLEND_ARB" },
- { 0x86A8, "GL_CURRENT_WEIGHT_ARB" },
- { 0x86A9, "GL_WEIGHT_ARRAY_TYPE_ARB" },
- { 0x86AA, "GL_WEIGHT_ARRAY_STRIDE_ARB" },
- { 0x86AB, "GL_WEIGHT_ARRAY_SIZE_ARB" },
- { 0x86AC, "GL_WEIGHT_ARRAY_POINTER_ARB" },
- { 0x86AD, "GL_WEIGHT_ARRAY_ARB" },
- { 0x86AE, "GL_DOT3_RGB" },
- { 0x86AF, "GL_DOT3_RGBA" },
- { 0x86B0, "GL_COMPRESSED_RGB_FXT1_3DFX" },
- { 0x86B1, "GL_COMPRESSED_RGBA_FXT1_3DFX" },
- { 0x86B2, "GL_MULTISAMPLE_3DFX" },
- { 0x86B3, "GL_SAMPLE_BUFFERS_3DFX" },
- { 0x86B4, "GL_SAMPLES_3DFX" },
- { 0x8722, "GL_MODELVIEW2_ARB" },
- { 0x8723, "GL_MODELVIEW3_ARB" },
- { 0x8724, "GL_MODELVIEW4_ARB" },
- { 0x8725, "GL_MODELVIEW5_ARB" },
- { 0x8726, "GL_MODELVIEW6_ARB" },
- { 0x8727, "GL_MODELVIEW7_ARB" },
- { 0x8728, "GL_MODELVIEW8_ARB" },
- { 0x8729, "GL_MODELVIEW9_ARB" },
- { 0x872A, "GL_MODELVIEW10_ARB" },
- { 0x872B, "GL_MODELVIEW11_ARB" },
- { 0x872C, "GL_MODELVIEW12_ARB" },
- { 0x872D, "GL_MODELVIEW13_ARB" },
- { 0x872E, "GL_MODELVIEW14_ARB" },
- { 0x872F, "GL_MODELVIEW15_ARB" },
- { 0x8730, "GL_MODELVIEW16_ARB" },
- { 0x8731, "GL_MODELVIEW17_ARB" },
- { 0x8732, "GL_MODELVIEW18_ARB" },
- { 0x8733, "GL_MODELVIEW19_ARB" },
- { 0x8734, "GL_MODELVIEW20_ARB" },
- { 0x8735, "GL_MODELVIEW21_ARB" },
- { 0x8736, "GL_MODELVIEW22_ARB" },
- { 0x8737, "GL_MODELVIEW23_ARB" },
- { 0x8738, "GL_MODELVIEW24_ARB" },
- { 0x8739, "GL_MODELVIEW25_ARB" },
- { 0x873A, "GL_MODELVIEW26_ARB" },
- { 0x873B, "GL_MODELVIEW27_ARB" },
- { 0x873C, "GL_MODELVIEW28_ARB" },
- { 0x873D, "GL_MODELVIEW29_ARB" },
- { 0x873E, "GL_MODELVIEW30_ARB" },
- { 0x873F, "GL_MODELVIEW31_ARB" },
- { 0x8740, "GL_DOT3_RGB_EXT" },
+ /* An EXT-only enum that should take precedence over a _BIT. */
+ { 0x8000, "GL_ABGR_EXT" },
- /* Both GL_DOT3_RGBA_EXT and GL_PROGRAM_BINARY_LENGTH were accidentally
- * assigned the same value. The generator script prefers "core" names to
- * extension names, so only GL_PROGRAM_BINARY_LENGTH is checked.
- */
-/* { 0x8741, "GL_DOT3_RGBA_EXT" },*/
- { 0x8741, "GL_PROGRAM_BINARY_LENGTH" },
-
- { 0x8742, "GL_MIRROR_CLAMP_EXT" },
- { 0x8743, "GL_MIRROR_CLAMP_TO_EDGE_EXT" },
- { 0x8744, "GL_MODULATE_ADD_ATI" },
- { 0x8745, "GL_MODULATE_SIGNED_ADD_ATI" },
- { 0x8746, "GL_MODULATE_SUBTRACT_ATI" },
- { 0x8757, "GL_YCBCR_MESA" },
- { 0x8758, "GL_PACK_INVERT_MESA" },
- { 0x8764, "GL_BUFFER_SIZE" },
- { 0x8765, "GL_BUFFER_USAGE" },
- { 0x87FE, "GL_NUM_PROGRAM_BINARY_FORMATS" },
- { 0x87FF, "GL_PROGRAM_BINARY_FORMATS" },
- { 0x8800, "GL_STENCIL_BACK_FUNC" },
- { 0x8801, "GL_STENCIL_BACK_FAIL" },
- { 0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL" },
- { 0x8803, "GL_STENCIL_BACK_PASS_DEPTH_PASS" },
- { 0x8804, "GL_FRAGMENT_PROGRAM_ARB" },
- { 0x8805, "GL_PROGRAM_ALU_INSTRUCTIONS_ARB" },
- { 0x8806, "GL_PROGRAM_TEX_INSTRUCTIONS_ARB" },
- { 0x8807, "GL_PROGRAM_TEX_INDIRECTIONS_ARB" },
- { 0x8808, "GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB" },
- { 0x8809, "GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB" },
- { 0x880A, "GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" },
- { 0x880B, "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB" },
- { 0x880C, "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB" },
- { 0x880D, "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB" },
- { 0x880E, "GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB" },
- { 0x880F, "GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB" },
- { 0x8810, "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" },
- { 0x8814, "GL_RGBA32F" },
- { 0x8815, "GL_RGB32F" },
- { 0x8816, "GL_ALPHA32F_ARB" },
- { 0x8817, "GL_INTENSITY32F_ARB" },
- { 0x8818, "GL_LUMINANCE32F_ARB" },
- { 0x8819, "GL_LUMINANCE_ALPHA32F_ARB" },
- { 0x881A, "GL_RGBA16F" },
- { 0x881B, "GL_RGB16F" },
- { 0x881C, "GL_ALPHA16F_ARB" },
- { 0x881D, "GL_INTENSITY16F_ARB" },
- { 0x881E, "GL_LUMINANCE16F_ARB" },
- { 0x881F, "GL_LUMINANCE_ALPHA16F_ARB" },
- { 0x8820, "GL_RGBA_FLOAT_MODE_ARB" },
- { 0x8824, "GL_MAX_DRAW_BUFFERS" },
- { 0x8825, "GL_DRAW_BUFFER0" },
- { 0x8826, "GL_DRAW_BUFFER1" },
- { 0x8827, "GL_DRAW_BUFFER2" },
- { 0x8828, "GL_DRAW_BUFFER3" },
- { 0x8829, "GL_DRAW_BUFFER4" },
- { 0x882A, "GL_DRAW_BUFFER5" },
- { 0x882B, "GL_DRAW_BUFFER6" },
- { 0x882C, "GL_DRAW_BUFFER7" },
- { 0x882D, "GL_DRAW_BUFFER8" },
- { 0x882E, "GL_DRAW_BUFFER9" },
- { 0x882F, "GL_DRAW_BUFFER10" },
- { 0x8830, "GL_DRAW_BUFFER11" },
- { 0x8831, "GL_DRAW_BUFFER12" },
- { 0x8832, "GL_DRAW_BUFFER13" },
- { 0x8833, "GL_DRAW_BUFFER14" },
- { 0x8834, "GL_DRAW_BUFFER15" },
- { 0x883D, "GL_BLEND_EQUATION_ALPHA" },
- { 0x8840, "GL_MATRIX_PALETTE_ARB" },
- { 0x8841, "GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB" },
- { 0x8842, "GL_MAX_PALETTE_MATRICES_ARB" },
- { 0x8843, "GL_CURRENT_PALETTE_MATRIX_ARB" },
- { 0x8844, "GL_MATRIX_INDEX_ARRAY_ARB" },
- { 0x8845, "GL_CURRENT_MATRIX_INDEX_ARB" },
- { 0x8846, "GL_MATRIX_INDEX_ARRAY_SIZE_ARB" },
- { 0x8847, "GL_MATRIX_INDEX_ARRAY_TYPE_ARB" },
- { 0x8848, "GL_MATRIX_INDEX_ARRAY_STRIDE_ARB" },
- { 0x8849, "GL_MATRIX_INDEX_ARRAY_POINTER_ARB" },
- { 0x884A, "GL_TEXTURE_DEPTH_SIZE" },
- { 0x884B, "GL_DEPTH_TEXTURE_MODE" },
- { 0x884C, "GL_TEXTURE_COMPARE_MODE" },
- { 0x884D, "GL_TEXTURE_COMPARE_FUNC" },
- { 0x884E, "GL_COMPARE_REF_TO_TEXTURE" },
- { 0x884F, "GL_TEXTURE_CUBE_MAP_SEAMLESS" },
- { 0x8861, "GL_POINT_SPRITE" },
- { 0x8862, "GL_COORD_REPLACE" },
- { 0x8863, "GL_POINT_SPRITE_R_MODE_NV" },
- { 0x8864, "GL_QUERY_COUNTER_BITS" },
- { 0x8865, "GL_CURRENT_QUERY" },
- { 0x8866, "GL_QUERY_RESULT" },
- { 0x8867, "GL_QUERY_RESULT_AVAILABLE" },
- { 0x8868, "GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV" },
- { 0x8869, "GL_MAX_VERTEX_ATTRIBS" },
- { 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED" },
- { 0x886E, "GL_DEPTH_STENCIL_TO_RGBA_NV" },
- { 0x886F, "GL_DEPTH_STENCIL_TO_BGRA_NV" },
- { 0x8870, "GL_FRAGMENT_PROGRAM_NV" },
- { 0x8871, "GL_MAX_TEXTURE_COORDS" },
- { 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS" },
- { 0x8873, "GL_FRAGMENT_PROGRAM_BINDING_NV" },
- { 0x8874, "GL_PROGRAM_ERROR_STRING_ARB" },
- { 0x8875, "GL_PROGRAM_FORMAT_ASCII_ARB" },
- { 0x8876, "GL_PROGRAM_FORMAT_ARB" },
- { 0x888F, "GL_TEXTURE_UNSIGNED_REMAP_MODE_NV" },
- { 0x8890, "GL_DEPTH_BOUNDS_TEST_EXT" },
- { 0x8891, "GL_DEPTH_BOUNDS_EXT" },
- { 0x8892, "GL_ARRAY_BUFFER" },
- { 0x8893, "GL_ELEMENT_ARRAY_BUFFER" },
- { 0x8894, "GL_ARRAY_BUFFER_BINDING" },
- { 0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING" },
- { 0x8896, "GL_VERTEX_ARRAY_BUFFER_BINDING" },
- { 0x8897, "GL_NORMAL_ARRAY_BUFFER_BINDING" },
- { 0x8898, "GL_COLOR_ARRAY_BUFFER_BINDING" },
- { 0x8899, "GL_INDEX_ARRAY_BUFFER_BINDING" },
- { 0x889A, "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING" },
- { 0x889B, "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING" },
- { 0x889C, "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING" },
- { 0x889D, "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING" },
- { 0x889E, "GL_WEIGHT_ARRAY_BUFFER_BINDING" },
- { 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING" },
- { 0x88A0, "GL_PROGRAM_INSTRUCTIONS_ARB" },
- { 0x88A1, "GL_MAX_PROGRAM_INSTRUCTIONS_ARB" },
- { 0x88A2, "GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB" },
- { 0x88A3, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" },
- { 0x88A4, "GL_PROGRAM_TEMPORARIES_ARB" },
- { 0x88A5, "GL_MAX_PROGRAM_TEMPORARIES_ARB" },
- { 0x88A6, "GL_PROGRAM_NATIVE_TEMPORARIES_ARB" },
- { 0x88A7, "GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB" },
- { 0x88A8, "GL_PROGRAM_PARAMETERS_ARB" },
- { 0x88A9, "GL_MAX_PROGRAM_PARAMETERS_ARB" },
- { 0x88AA, "GL_PROGRAM_NATIVE_PARAMETERS_ARB" },
- { 0x88AB, "GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB" },
- { 0x88AC, "GL_PROGRAM_ATTRIBS_ARB" },
- { 0x88AD, "GL_MAX_PROGRAM_ATTRIBS_ARB" },
- { 0x88AE, "GL_PROGRAM_NATIVE_ATTRIBS_ARB" },
- { 0x88AF, "GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB" },
- { 0x88B0, "GL_PROGRAM_ADDRESS_REGISTERS_ARB" },
- { 0x88B1, "GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB" },
- { 0x88B2, "GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" },
- { 0x88B3, "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" },
- { 0x88B4, "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB" },
- { 0x88B5, "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB" },
- { 0x88B6, "GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB" },
- { 0x88B7, "GL_TRANSPOSE_CURRENT_MATRIX_ARB" },
- { 0x88B8, "GL_READ_ONLY" },
- { 0x88B9, "GL_WRITE_ONLY" },
- { 0x88BA, "GL_READ_WRITE" },
- { 0x88BB, "GL_BUFFER_ACCESS" },
- { 0x88BC, "GL_BUFFER_MAPPED" },
- { 0x88BD, "GL_BUFFER_MAP_POINTER" },
- { 0x88BF, "GL_TIME_ELAPSED" },
- { 0x88C0, "GL_MATRIX0_ARB" },
- { 0x88C1, "GL_MATRIX1_ARB" },
- { 0x88C2, "GL_MATRIX2_ARB" },
- { 0x88C3, "GL_MATRIX3_ARB" },
- { 0x88C4, "GL_MATRIX4_ARB" },
- { 0x88C5, "GL_MATRIX5_ARB" },
- { 0x88C6, "GL_MATRIX6_ARB" },
- { 0x88C7, "GL_MATRIX7_ARB" },
- { 0x88C8, "GL_MATRIX8_ARB" },
- { 0x88C9, "GL_MATRIX9_ARB" },
- { 0x88CA, "GL_MATRIX10_ARB" },
- { 0x88CB, "GL_MATRIX11_ARB" },
- { 0x88CC, "GL_MATRIX12_ARB" },
- { 0x88CD, "GL_MATRIX13_ARB" },
- { 0x88CE, "GL_MATRIX14_ARB" },
- { 0x88CF, "GL_MATRIX15_ARB" },
- { 0x88D0, "GL_MATRIX16_ARB" },
- { 0x88D1, "GL_MATRIX17_ARB" },
- { 0x88D2, "GL_MATRIX18_ARB" },
- { 0x88D3, "GL_MATRIX19_ARB" },
- { 0x88D4, "GL_MATRIX20_ARB" },
- { 0x88D5, "GL_MATRIX21_ARB" },
- { 0x88D6, "GL_MATRIX22_ARB" },
- { 0x88D7, "GL_MATRIX23_ARB" },
- { 0x88D8, "GL_MATRIX24_ARB" },
- { 0x88D9, "GL_MATRIX25_ARB" },
- { 0x88DA, "GL_MATRIX26_ARB" },
- { 0x88DB, "GL_MATRIX27_ARB" },
- { 0x88DC, "GL_MATRIX28_ARB" },
- { 0x88DD, "GL_MATRIX29_ARB" },
- { 0x88DE, "GL_MATRIX30_ARB" },
- { 0x88DF, "GL_MATRIX31_ARB" },
- { 0x88E0, "GL_STREAM_DRAW" },
- { 0x88E1, "GL_STREAM_READ" },
- { 0x88E2, "GL_STREAM_COPY" },
- { 0x88E4, "GL_STATIC_DRAW" },
- { 0x88E5, "GL_STATIC_READ" },
- { 0x88E6, "GL_STATIC_COPY" },
- { 0x88E8, "GL_DYNAMIC_DRAW" },
- { 0x88E9, "GL_DYNAMIC_READ" },
- { 0x88EA, "GL_DYNAMIC_COPY" },
- { 0x88EB, "GL_PIXEL_PACK_BUFFER" },
- { 0x88EC, "GL_PIXEL_UNPACK_BUFFER" },
- { 0x88ED, "GL_PIXEL_PACK_BUFFER_BINDING" },
- { 0x88EF, "GL_PIXEL_UNPACK_BUFFER_BINDING" },
- { 0x88F0, "GL_DEPTH24_STENCIL8" },
- { 0x88F1, "GL_TEXTURE_STENCIL_SIZE" },
- { 0x88F4, "GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV" },
- { 0x88F5, "GL_MAX_PROGRAM_CALL_DEPTH_NV" },
- { 0x88F6, "GL_MAX_PROGRAM_IF_DEPTH_NV" },
- { 0x88F7, "GL_MAX_PROGRAM_LOOP_DEPTH_NV" },
- { 0x88F8, "GL_MAX_PROGRAM_LOOP_COUNT_NV" },
- { 0x88F9, "GL_SRC1_COLOR" },
- { 0x88FA, "GL_ONE_MINUS_SRC1_COLOR" },
- { 0x88FB, "GL_ONE_MINUS_SRC1_ALPHA" },
- { 0x88FC, "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS" },
- { 0x88FD, "GL_VERTEX_ATTRIB_ARRAY_INTEGER" },
- { 0x88FE, "GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB" },
- { 0x88FF, "GL_MAX_ARRAY_TEXTURE_LAYERS" },
- { 0x8904, "GL_MIN_PROGRAM_TEXEL_OFFSET" },
- { 0x8905, "GL_MAX_PROGRAM_TEXEL_OFFSET" },
- { 0x8910, "GL_STENCIL_TEST_TWO_SIDE_EXT" },
- { 0x8911, "GL_ACTIVE_STENCIL_FACE_EXT" },
- { 0x8912, "GL_MIRROR_CLAMP_TO_BORDER_EXT" },
- { 0x8914, "GL_SAMPLES_PASSED" },
- { 0x8916, "GL_GEOMETRY_VERTICES_OUT" },
- { 0x8917, "GL_GEOMETRY_INPUT_TYPE" },
- { 0x8918, "GL_GEOMETRY_OUTPUT_TYPE" },
- { 0x8919, "GL_SAMPLER_BINDING" },
- { 0x891A, "GL_CLAMP_VERTEX_COLOR" },
- { 0x891B, "GL_CLAMP_FRAGMENT_COLOR" },
- { 0x891C, "GL_CLAMP_READ_COLOR" },
- { 0x891D, "GL_FIXED_ONLY" },
- { 0x8920, "GL_FRAGMENT_SHADER_ATI" },
- { 0x8921, "GL_REG_0_ATI" },
- { 0x8922, "GL_REG_1_ATI" },
- { 0x8923, "GL_REG_2_ATI" },
- { 0x8924, "GL_REG_3_ATI" },
- { 0x8925, "GL_REG_4_ATI" },
- { 0x8926, "GL_REG_5_ATI" },
- { 0x8927, "GL_REG_6_ATI" },
- { 0x8928, "GL_REG_7_ATI" },
- { 0x8929, "GL_REG_8_ATI" },
- { 0x892A, "GL_REG_9_ATI" },
- { 0x892B, "GL_REG_10_ATI" },
- { 0x892C, "GL_REG_11_ATI" },
- { 0x892D, "GL_REG_12_ATI" },
- { 0x892E, "GL_REG_13_ATI" },
- { 0x892F, "GL_REG_14_ATI" },
- { 0x8930, "GL_REG_15_ATI" },
- { 0x8931, "GL_REG_16_ATI" },
- { 0x8932, "GL_REG_17_ATI" },
- { 0x8933, "GL_REG_18_ATI" },
- { 0x8934, "GL_REG_19_ATI" },
- { 0x8935, "GL_REG_20_ATI" },
- { 0x8936, "GL_REG_21_ATI" },
- { 0x8937, "GL_REG_22_ATI" },
- { 0x8938, "GL_REG_23_ATI" },
- { 0x8939, "GL_REG_24_ATI" },
- { 0x893A, "GL_REG_25_ATI" },
- { 0x893B, "GL_REG_26_ATI" },
- { 0x893C, "GL_REG_27_ATI" },
- { 0x893D, "GL_REG_28_ATI" },
- { 0x893E, "GL_REG_29_ATI" },
- { 0x893F, "GL_REG_30_ATI" },
- { 0x8940, "GL_REG_31_ATI" },
- { 0x8941, "GL_CON_0_ATI" },
- { 0x8942, "GL_CON_1_ATI" },
- { 0x8943, "GL_CON_2_ATI" },
- { 0x8944, "GL_CON_3_ATI" },
- { 0x8945, "GL_CON_4_ATI" },
- { 0x8946, "GL_CON_5_ATI" },
- { 0x8947, "GL_CON_6_ATI" },
- { 0x8948, "GL_CON_7_ATI" },
- { 0x8949, "GL_CON_8_ATI" },
- { 0x894A, "GL_CON_9_ATI" },
- { 0x894B, "GL_CON_10_ATI" },
- { 0x894C, "GL_CON_11_ATI" },
- { 0x894D, "GL_CON_12_ATI" },
- { 0x894E, "GL_CON_13_ATI" },
- { 0x894F, "GL_CON_14_ATI" },
- { 0x8950, "GL_CON_15_ATI" },
- { 0x8951, "GL_CON_16_ATI" },
- { 0x8952, "GL_CON_17_ATI" },
- { 0x8953, "GL_CON_18_ATI" },
- { 0x8954, "GL_CON_19_ATI" },
- { 0x8955, "GL_CON_20_ATI" },
- { 0x8956, "GL_CON_21_ATI" },
- { 0x8957, "GL_CON_22_ATI" },
- { 0x8958, "GL_CON_23_ATI" },
- { 0x8959, "GL_CON_24_ATI" },
- { 0x895A, "GL_CON_25_ATI" },
- { 0x895B, "GL_CON_26_ATI" },
- { 0x895C, "GL_CON_27_ATI" },
- { 0x895D, "GL_CON_28_ATI" },
- { 0x895E, "GL_CON_29_ATI" },
- { 0x895F, "GL_CON_30_ATI" },
- { 0x8960, "GL_CON_31_ATI" },
- { 0x8961, "GL_MOV_ATI" },
- { 0x8963, "GL_ADD_ATI" },
- { 0x8964, "GL_MUL_ATI" },
- { 0x8965, "GL_SUB_ATI" },
- { 0x8966, "GL_DOT3_ATI" },
- { 0x8967, "GL_DOT4_ATI" },
- { 0x8968, "GL_MAD_ATI" },
- { 0x8969, "GL_LERP_ATI" },
- { 0x896A, "GL_CND_ATI" },
- { 0x896B, "GL_CND0_ATI" },
- { 0x896C, "GL_DOT2_ADD_ATI" },
- { 0x896D, "GL_SECONDARY_INTERPOLATOR_ATI" },
- { 0x896E, "GL_NUM_FRAGMENT_REGISTERS_ATI" },
- { 0x896F, "GL_NUM_FRAGMENT_CONSTANTS_ATI" },
- { 0x8970, "GL_NUM_PASSES_ATI" },
- { 0x8971, "GL_NUM_INSTRUCTIONS_PER_PASS_ATI" },
- { 0x8972, "GL_NUM_INSTRUCTIONS_TOTAL_ATI" },
- { 0x8973, "GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI" },
- { 0x8974, "GL_NUM_LOOPBACK_COMPONENTS_ATI" },
- { 0x8975, "GL_COLOR_ALPHA_PAIRING_ATI" },
- { 0x8976, "GL_SWIZZLE_STR_ATI" },
- { 0x8977, "GL_SWIZZLE_STQ_ATI" },
- { 0x8978, "GL_SWIZZLE_STR_DR_ATI" },
- { 0x8979, "GL_SWIZZLE_STQ_DQ_ATI" },
- { 0x897A, "GL_SWIZZLE_STRQ_ATI" },
- { 0x897B, "GL_SWIZZLE_STRQ_DQ_ATI" },
- { 0x8A11, "GL_UNIFORM_BUFFER" },
- { 0x8A12, "GL_BUFFER_SERIALIZED_MODIFY_APPLE" },
- { 0x8A13, "GL_BUFFER_FLUSHING_UNMAP_APPLE" },
- { 0x8A19, "GL_RELEASED_APPLE" },
- { 0x8A1A, "GL_VOLATILE_APPLE" },
- { 0x8A1B, "GL_RETAINED_APPLE" },
- { 0x8A1C, "GL_UNDEFINED_APPLE" },
- { 0x8A1D, "GL_PURGEABLE_APPLE" },
- { 0x8A28, "GL_UNIFORM_BUFFER_BINDING" },
- { 0x8A29, "GL_UNIFORM_BUFFER_START" },
- { 0x8A2A, "GL_UNIFORM_BUFFER_SIZE" },
- { 0x8A2B, "GL_MAX_VERTEX_UNIFORM_BLOCKS" },
- { 0x8A2C, "GL_MAX_GEOMETRY_UNIFORM_BLOCKS" },
- { 0x8A2D, "GL_MAX_FRAGMENT_UNIFORM_BLOCKS" },
- { 0x8A2E, "GL_MAX_COMBINED_UNIFORM_BLOCKS" },
- { 0x8A2F, "GL_MAX_UNIFORM_BUFFER_BINDINGS" },
- { 0x8A30, "GL_MAX_UNIFORM_BLOCK_SIZE" },
- { 0x8A31, "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS" },
- { 0x8A32, "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS" },
- { 0x8A33, "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS" },
- { 0x8A34, "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT" },
- { 0x8A35, "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH" },
- { 0x8A36, "GL_ACTIVE_UNIFORM_BLOCKS" },
- { 0x8A37, "GL_UNIFORM_TYPE" },
- { 0x8A38, "GL_UNIFORM_SIZE" },
- { 0x8A39, "GL_UNIFORM_NAME_LENGTH" },
- { 0x8A3A, "GL_UNIFORM_BLOCK_INDEX" },
- { 0x8A3B, "GL_UNIFORM_OFFSET" },
- { 0x8A3C, "GL_UNIFORM_ARRAY_STRIDE" },
- { 0x8A3D, "GL_UNIFORM_MATRIX_STRIDE" },
- { 0x8A3E, "GL_UNIFORM_IS_ROW_MAJOR" },
- { 0x8A3F, "GL_UNIFORM_BLOCK_BINDING" },
- { 0x8A40, "GL_UNIFORM_BLOCK_DATA_SIZE" },
- { 0x8A41, "GL_UNIFORM_BLOCK_NAME_LENGTH" },
- { 0x8A42, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS" },
- { 0x8A43, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES" },
- { 0x8A44, "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER" },
- { 0x8A45, "GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER" },
- { 0x8A46, "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER" },
- { 0x8A48, "GL_TEXTURE_SRGB_DECODE_EXT" },
- { 0x8A49, "GL_DECODE_EXT" },
- { 0x8A4A, "GL_SKIP_DECODE_EXT" },
- { 0x8B30, "GL_FRAGMENT_SHADER" },
- { 0x8B31, "GL_VERTEX_SHADER" },
- { 0x8B40, "GL_PROGRAM_OBJECT_ARB" },
- { 0x8B48, "GL_SHADER_OBJECT_ARB" },
- { 0x8B49, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS" },
- { 0x8B4A, "GL_MAX_VERTEX_UNIFORM_COMPONENTS" },
- { 0x8B4B, "GL_MAX_VARYING_COMPONENTS" },
- { 0x8B4C, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS" },
- { 0x8B4D, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS" },
- { 0x8B4E, "GL_OBJECT_TYPE_ARB" },
- { 0x8B4F, "GL_SHADER_TYPE" },
- { 0x8B50, "GL_FLOAT_VEC2" },
- { 0x8B51, "GL_FLOAT_VEC3" },
- { 0x8B52, "GL_FLOAT_VEC4" },
- { 0x8B53, "GL_INT_VEC2" },
- { 0x8B54, "GL_INT_VEC3" },
- { 0x8B55, "GL_INT_VEC4" },
- { 0x8B56, "GL_BOOL" },
- { 0x8B57, "GL_BOOL_VEC2" },
- { 0x8B58, "GL_BOOL_VEC3" },
- { 0x8B59, "GL_BOOL_VEC4" },
- { 0x8B5A, "GL_FLOAT_MAT2" },
- { 0x8B5B, "GL_FLOAT_MAT3" },
- { 0x8B5C, "GL_FLOAT_MAT4" },
- { 0x8B5D, "GL_SAMPLER_1D" },
- { 0x8B5E, "GL_SAMPLER_2D" },
- { 0x8B5F, "GL_SAMPLER_3D" },
- { 0x8B60, "GL_SAMPLER_CUBE" },
- { 0x8B61, "GL_SAMPLER_1D_SHADOW" },
- { 0x8B62, "GL_SAMPLER_2D_SHADOW" },
- { 0x8B63, "GL_SAMPLER_2D_RECT" },
- { 0x8B64, "GL_SAMPLER_2D_RECT_SHADOW" },
- { 0x8B65, "GL_FLOAT_MAT2x3" },
- { 0x8B66, "GL_FLOAT_MAT2x4" },
- { 0x8B67, "GL_FLOAT_MAT3x2" },
- { 0x8B68, "GL_FLOAT_MAT3x4" },
- { 0x8B69, "GL_FLOAT_MAT4x2" },
- { 0x8B6A, "GL_FLOAT_MAT4x3" },
- { 0x8B80, "GL_DELETE_STATUS" },
- { 0x8B81, "GL_COMPILE_STATUS" },
- { 0x8B82, "GL_LINK_STATUS" },
- { 0x8B83, "GL_VALIDATE_STATUS" },
- { 0x8B84, "GL_INFO_LOG_LENGTH" },
- { 0x8B85, "GL_ATTACHED_SHADERS" },
- { 0x8B86, "GL_ACTIVE_UNIFORMS" },
- { 0x8B87, "GL_ACTIVE_UNIFORM_MAX_LENGTH" },
- { 0x8B88, "GL_SHADER_SOURCE_LENGTH" },
- { 0x8B89, "GL_ACTIVE_ATTRIBUTES" },
- { 0x8B8A, "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH" },
- { 0x8B8B, "GL_FRAGMENT_SHADER_DERIVATIVE_HINT" },
- { 0x8B8C, "GL_SHADING_LANGUAGE_VERSION" },
- { 0x8B8D, "GL_CURRENT_PROGRAM" },
- { 0x8B9A, "GL_IMPLEMENTATION_COLOR_READ_TYPE" },
- { 0x8B9B, "GL_IMPLEMENTATION_COLOR_READ_FORMAT" },
- { 0x8C10, "GL_TEXTURE_RED_TYPE" },
- { 0x8C11, "GL_TEXTURE_GREEN_TYPE" },
- { 0x8C12, "GL_TEXTURE_BLUE_TYPE" },
- { 0x8C13, "GL_TEXTURE_ALPHA_TYPE" },
- { 0x8C14, "GL_TEXTURE_LUMINANCE_TYPE" },
- { 0x8C15, "GL_TEXTURE_INTENSITY_TYPE" },
- { 0x8C16, "GL_TEXTURE_DEPTH_TYPE" },
- { 0x8C17, "GL_UNSIGNED_NORMALIZED" },
- { 0x8C18, "GL_TEXTURE_1D_ARRAY" },
- { 0x8C19, "GL_PROXY_TEXTURE_1D_ARRAY" },
- { 0x8C1A, "GL_TEXTURE_2D_ARRAY" },
- { 0x8C1B, "GL_PROXY_TEXTURE_2D_ARRAY" },
- { 0x8C1C, "GL_TEXTURE_BINDING_1D_ARRAY" },
- { 0x8C1D, "GL_TEXTURE_BINDING_2D_ARRAY" },
- { 0x8C29, "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS" },
- { 0x8C2A, "GL_TEXTURE_BUFFER" },
- { 0x8C2B, "GL_MAX_TEXTURE_BUFFER_SIZE" },
- { 0x8C2C, "GL_TEXTURE_BINDING_BUFFER" },
- { 0x8C2D, "GL_TEXTURE_BUFFER_DATA_STORE_BINDING" },
- { 0x8C2E, "GL_TEXTURE_BUFFER_FORMAT" },
- { 0x8C2F, "GL_ANY_SAMPLES_PASSED" },
- { 0x8C3A, "GL_R11F_G11F_B10F" },
- { 0x8C3B, "GL_UNSIGNED_INT_10F_11F_11F_REV" },
- { 0x8C3C, "GL_RGBA_SIGNED_COMPONENTS_EXT" },
- { 0x8C3D, "GL_RGB9_E5" },
- { 0x8C3E, "GL_UNSIGNED_INT_5_9_9_9_REV" },
- { 0x8C3F, "GL_TEXTURE_SHARED_SIZE" },
- { 0x8C40, "GL_SRGB" },
- { 0x8C41, "GL_SRGB8" },
- { 0x8C42, "GL_SRGB_ALPHA" },
- { 0x8C43, "GL_SRGB8_ALPHA8" },
- { 0x8C44, "GL_SLUMINANCE_ALPHA" },
- { 0x8C45, "GL_SLUMINANCE8_ALPHA8" },
- { 0x8C46, "GL_SLUMINANCE" },
- { 0x8C47, "GL_SLUMINANCE8" },
- { 0x8C48, "GL_COMPRESSED_SRGB" },
- { 0x8C49, "GL_COMPRESSED_SRGB_ALPHA" },
- { 0x8C4A, "GL_COMPRESSED_SLUMINANCE" },
- { 0x8C4B, "GL_COMPRESSED_SLUMINANCE_ALPHA" },
-#if 0
- { 0x8C4C, "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT" },
- { 0x8C4D, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT" },
- { 0x8C4E, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT" },
- { 0x8C4F, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT" },
- { 0x8C70, "GL_COMPRESSED_LUMINANCE_LATC1_EXT" },
- { 0x8C71, "GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT" },
- { 0x8C72, "GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT" },
- { 0x8C73, "GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT" },
-#endif
- { 0x8C76, "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH" },
- { 0x8C7F, "GL_TRANSFORM_FEEDBACK_BUFFER_MODE" },
- { 0x8C80, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS" },
- { 0x8C83, "GL_TRANSFORM_FEEDBACK_VARYINGS" },
- { 0x8C84, "GL_TRANSFORM_FEEDBACK_BUFFER_START" },
- { 0x8C85, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE" },
- { 0x8C87, "GL_PRIMITIVES_GENERATED" },
- { 0x8C88, "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN" },
- { 0x8C89, "GL_RASTERIZER_DISCARD" },
- { 0x8C8A, "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS" },
- { 0x8C8B, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS" },
- { 0x8C8C, "GL_INTERLEAVED_ATTRIBS" },
- { 0x8C8D, "GL_SEPARATE_ATTRIBS" },
- { 0x8C8E, "GL_TRANSFORM_FEEDBACK_BUFFER" },
- { 0x8C8F, "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING" },
- { 0x8CA0, "GL_POINT_SPRITE_COORD_ORIGIN" },
- { 0x8CA1, "GL_LOWER_LEFT" },
- { 0x8CA2, "GL_UPPER_LEFT" },
- { 0x8CA3, "GL_STENCIL_BACK_REF" },
- { 0x8CA4, "GL_STENCIL_BACK_VALUE_MASK" },
- { 0x8CA5, "GL_STENCIL_BACK_WRITEMASK" },
- { 0x8CA6, "GL_DRAW_FRAMEBUFFER_BINDING" },
- { 0x8CA7, "GL_RENDERBUFFER_BINDING" },
- { 0x8CA8, "GL_READ_FRAMEBUFFER" },
- { 0x8CA9, "GL_DRAW_FRAMEBUFFER" },
- { 0x8CAA, "GL_READ_FRAMEBUFFER_BINDING" },
- { 0x8CAB, "GL_RENDERBUFFER_SAMPLES" },
- { 0x8CAC, "GL_DEPTH_COMPONENT32F" },
- { 0x8CAD, "GL_DEPTH32F_STENCIL8" },
- { 0x8CD0, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE" },
- { 0x8CD1, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME" },
- { 0x8CD2, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL" },
- { 0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE" },
- { 0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER" },
- { 0x8CD5, "GL_FRAMEBUFFER_COMPLETE" },
- { 0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT" },
- { 0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" },
- { 0x8CD9, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT" },
- { 0x8CDA, "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT" },
- { 0x8CDB, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER" },
- { 0x8CDC, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER" },
- { 0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED" },
- { 0x8CDF, "GL_MAX_COLOR_ATTACHMENTS" },
- { 0x8CE0, "GL_COLOR_ATTACHMENT0" },
- { 0x8CE1, "GL_COLOR_ATTACHMENT1" },
- { 0x8CE2, "GL_COLOR_ATTACHMENT2" },
- { 0x8CE3, "GL_COLOR_ATTACHMENT3" },
- { 0x8CE4, "GL_COLOR_ATTACHMENT4" },
- { 0x8CE5, "GL_COLOR_ATTACHMENT5" },
- { 0x8CE6, "GL_COLOR_ATTACHMENT6" },
- { 0x8CE7, "GL_COLOR_ATTACHMENT7" },
- { 0x8CE8, "GL_COLOR_ATTACHMENT8" },
- { 0x8CE9, "GL_COLOR_ATTACHMENT9" },
- { 0x8CEA, "GL_COLOR_ATTACHMENT10" },
- { 0x8CEB, "GL_COLOR_ATTACHMENT11" },
- { 0x8CEC, "GL_COLOR_ATTACHMENT12" },
- { 0x8CED, "GL_COLOR_ATTACHMENT13" },
- { 0x8CEE, "GL_COLOR_ATTACHMENT14" },
- { 0x8CEF, "GL_COLOR_ATTACHMENT15" },
- { 0x8D00, "GL_DEPTH_ATTACHMENT" },
- { 0x8D20, "GL_STENCIL_ATTACHMENT" },
- { 0x8D40, "GL_FRAMEBUFFER" },
- { 0x8D41, "GL_RENDERBUFFER" },
- { 0x8D42, "GL_RENDERBUFFER_WIDTH" },
- { 0x8D43, "GL_RENDERBUFFER_HEIGHT" },
- { 0x8D44, "GL_RENDERBUFFER_INTERNAL_FORMAT" },
- { 0x8D46, "GL_STENCIL_INDEX1" },
- { 0x8D47, "GL_STENCIL_INDEX4" },
- { 0x8D48, "GL_STENCIL_INDEX8" },
- { 0x8D49, "GL_STENCIL_INDEX16" },
- { 0x8D50, "GL_RENDERBUFFER_RED_SIZE" },
- { 0x8D51, "GL_RENDERBUFFER_GREEN_SIZE" },
- { 0x8D52, "GL_RENDERBUFFER_BLUE_SIZE" },
- { 0x8D53, "GL_RENDERBUFFER_ALPHA_SIZE" },
- { 0x8D54, "GL_RENDERBUFFER_DEPTH_SIZE" },
- { 0x8D55, "GL_RENDERBUFFER_STENCIL_SIZE" },
- { 0x8D56, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" },
- { 0x8D57, "GL_MAX_SAMPLES" },
- { 0x8D69, "GL_PRIMITIVE_RESTART_FIXED_INDEX" },
- { 0x8D6A, "GL_ANY_SAMPLES_PASSED_CONSERVATIVE" },
- { 0x8D6B, "GL_MAX_ELEMENT_INDEX" },
- { 0x8D70, "GL_RGBA32UI" },
- { 0x8D71, "GL_RGB32UI" },
- { 0x8D72, "GL_ALPHA32UI_EXT" },
- { 0x8D73, "GL_INTENSITY32UI_EXT" },
- { 0x8D74, "GL_LUMINANCE32UI_EXT" },
- { 0x8D75, "GL_LUMINANCE_ALPHA32UI_EXT" },
- { 0x8D76, "GL_RGBA16UI" },
- { 0x8D77, "GL_RGB16UI" },
- { 0x8D78, "GL_ALPHA16UI_EXT" },
- { 0x8D79, "GL_INTENSITY16UI_EXT" },
- { 0x8D7A, "GL_LUMINANCE16UI_EXT" },
- { 0x8D7B, "GL_LUMINANCE_ALPHA16UI_EXT" },
- { 0x8D7C, "GL_RGBA8UI" },
- { 0x8D7D, "GL_RGB8UI" },
- { 0x8D7E, "GL_ALPHA8UI_EXT" },
- { 0x8D7F, "GL_INTENSITY8UI_EXT" },
- { 0x8D80, "GL_LUMINANCE8UI_EXT" },
- { 0x8D81, "GL_LUMINANCE_ALPHA8UI_EXT" },
- { 0x8D82, "GL_RGBA32I" },
- { 0x8D83, "GL_RGB32I" },
- { 0x8D84, "GL_ALPHA32I_EXT" },
- { 0x8D85, "GL_INTENSITY32I_EXT" },
- { 0x8D86, "GL_LUMINANCE32I_EXT" },
- { 0x8D87, "GL_LUMINANCE_ALPHA32I_EXT" },
- { 0x8D88, "GL_RGBA16I" },
- { 0x8D89, "GL_RGB16I" },
- { 0x8D8A, "GL_ALPHA16I_EXT" },
- { 0x8D8B, "GL_INTENSITY16I_EXT" },
- { 0x8D8C, "GL_LUMINANCE16I_EXT" },
- { 0x8D8D, "GL_LUMINANCE_ALPHA16I_EXT" },
- { 0x8D8E, "GL_RGBA8I" },
- { 0x8D8F, "GL_RGB8I" },
- { 0x8D90, "GL_ALPHA8I_EXT" },
- { 0x8D91, "GL_INTENSITY8I_EXT" },
- { 0x8D92, "GL_LUMINANCE8I_EXT" },
- { 0x8D93, "GL_LUMINANCE_ALPHA8I_EXT" },
- { 0x8D94, "GL_RED_INTEGER" },
- { 0x8D95, "GL_GREEN_INTEGER" },
- { 0x8D96, "GL_BLUE_INTEGER" },
- { 0x8D97, "GL_ALPHA_INTEGER_EXT" },
- { 0x8D98, "GL_RGB_INTEGER" },
- { 0x8D99, "GL_RGBA_INTEGER" },
- { 0x8D9A, "GL_BGR_INTEGER" },
- { 0x8D9B, "GL_BGRA_INTEGER" },
- { 0x8D9C, "GL_LUMINANCE_INTEGER_EXT" },
- { 0x8D9D, "GL_LUMINANCE_ALPHA_INTEGER_EXT" },
- { 0x8D9E, "GL_RGBA_INTEGER_MODE_EXT" },
- { 0x8D9F, "GL_INT_2_10_10_10_REV" },
- { 0x8DA7, "GL_FRAMEBUFFER_ATTACHMENT_LAYERED" },
- { 0x8DA8, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS" },
- { 0x8DA9, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB" },
- { 0x8DAD, "GL_FLOAT_32_UNSIGNED_INT_24_8_REV" },
- { 0x8DB9, "GL_FRAMEBUFFER_SRGB" },
- { 0x8DBA, "GL_FRAMEBUFFER_SRGB_CAPABLE_EXT" },
- { 0x8DBB, "GL_COMPRESSED_RED_RGTC1" },
- { 0x8DBC, "GL_COMPRESSED_SIGNED_RED_RGTC1" },
- { 0x8DBD, "GL_COMPRESSED_RG_RGTC2" },
- { 0x8DBE, "GL_COMPRESSED_SIGNED_RG_RGTC2" },
- { 0x8DC0, "GL_SAMPLER_1D_ARRAY" },
- { 0x8DC1, "GL_SAMPLER_2D_ARRAY" },
- { 0x8DC2, "GL_SAMPLER_BUFFER" },
- { 0x8DC3, "GL_SAMPLER_1D_ARRAY_SHADOW" },
- { 0x8DC4, "GL_SAMPLER_2D_ARRAY_SHADOW" },
- { 0x8DC5, "GL_SAMPLER_CUBE_SHADOW" },
- { 0x8DC6, "GL_UNSIGNED_INT_VEC2" },
- { 0x8DC7, "GL_UNSIGNED_INT_VEC3" },
- { 0x8DC8, "GL_UNSIGNED_INT_VEC4" },
- { 0x8DC9, "GL_INT_SAMPLER_1D" },
- { 0x8DCA, "GL_INT_SAMPLER_2D" },
- { 0x8DCB, "GL_INT_SAMPLER_3D" },
- { 0x8DCC, "GL_INT_SAMPLER_CUBE" },
- { 0x8DCD, "GL_INT_SAMPLER_2D_RECT" },
- { 0x8DCE, "GL_INT_SAMPLER_1D_ARRAY" },
- { 0x8DCF, "GL_INT_SAMPLER_2D_ARRAY" },
- { 0x8DD0, "GL_INT_SAMPLER_BUFFER" },
- { 0x8DD1, "GL_UNSIGNED_INT_SAMPLER_1D" },
- { 0x8DD2, "GL_UNSIGNED_INT_SAMPLER_2D" },
- { 0x8DD3, "GL_UNSIGNED_INT_SAMPLER_3D" },
- { 0x8DD4, "GL_UNSIGNED_INT_SAMPLER_CUBE" },
- { 0x8DD5, "GL_UNSIGNED_INT_SAMPLER_2D_RECT" },
- { 0x8DD6, "GL_UNSIGNED_INT_SAMPLER_1D_ARRAY" },
- { 0x8DD7, "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY" },
- { 0x8DD8, "GL_UNSIGNED_INT_SAMPLER_BUFFER" },
- { 0x8DD9, "GL_GEOMETRY_SHADER" },
- { 0x8DDA, "GL_GEOMETRY_VERTICES_OUT_ARB" },
- { 0x8DDB, "GL_GEOMETRY_INPUT_TYPE_ARB" },
- { 0x8DDC, "GL_GEOMETRY_OUTPUT_TYPE_ARB" },
- { 0x8DDD, "GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB" },
- { 0x8DDE, "GL_MAX_VERTEX_VARYING_COMPONENTS_ARB" },
- { 0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS" },
- { 0x8DE0, "GL_MAX_GEOMETRY_OUTPUT_VERTICES" },
- { 0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS" },
- { 0x8DE5, "GL_ACTIVE_SUBROUTINES" },
- { 0x8DE6, "GL_ACTIVE_SUBROUTINE_UNIFORMS" },
- { 0x8DE7, "GL_MAX_SUBROUTINES" },
- { 0x8DE8, "GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS" },
- { 0x8DF0, "GL_LOW_FLOAT" },
- { 0x8DF1, "GL_MEDIUM_FLOAT" },
- { 0x8DF2, "GL_HIGH_FLOAT" },
- { 0x8DF3, "GL_LOW_INT" },
- { 0x8DF4, "GL_MEDIUM_INT" },
- { 0x8DF5, "GL_HIGH_INT" },
- { 0x8DF9, "GL_NUM_SHADER_BINARY_FORMATS" },
- { 0x8DFA, "GL_SHADER_COMPILER" },
- { 0x8DFB, "GL_MAX_VERTEX_UNIFORM_VECTORS" },
- { 0x8DFC, "GL_MAX_VARYING_VECTORS" },
- { 0x8DFD, "GL_MAX_FRAGMENT_UNIFORM_VECTORS" },
- { 0x8E13, "GL_QUERY_WAIT" },
- { 0x8E14, "GL_QUERY_NO_WAIT" },
- { 0x8E15, "GL_QUERY_BY_REGION_WAIT" },
- { 0x8E16, "GL_QUERY_BY_REGION_NO_WAIT" },
- { 0x8E17, "GL_QUERY_WAIT_INVERTED" },
- { 0x8E18, "GL_QUERY_NO_WAIT_INVERTED" },
- { 0x8E19, "GL_QUERY_BY_REGION_WAIT_INVERTED" },
- { 0x8E1A, "GL_QUERY_BY_REGION_NO_WAIT_INVERTED" },
- { 0x8E22, "GL_TRANSFORM_FEEDBACK" },
- { 0x8E23, "GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED" },
- { 0x8E24, "GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE" },
- { 0x8E25, "GL_TRANSFORM_FEEDBACK_BINDING" },
- { 0x8E42, "GL_TEXTURE_SWIZZLE_R" },
- { 0x8E43, "GL_TEXTURE_SWIZZLE_G" },
- { 0x8E44, "GL_TEXTURE_SWIZZLE_B" },
- { 0x8E45, "GL_TEXTURE_SWIZZLE_A" },
- { 0x8E46, "GL_TEXTURE_SWIZZLE_RGBA" },
- { 0x8E47, "GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS" },
- { 0x8E48, "GL_ACTIVE_SUBROUTINE_MAX_LENGTH" },
- { 0x8E49, "GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH" },
- { 0x8E4A, "GL_NUM_COMPATIBLE_SUBROUTINES" },
- { 0x8E4B, "GL_COMPATIBLE_SUBROUTINES" },
- { 0x8E4C, "GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION" },
- { 0x8E4D, "GL_FIRST_VERTEX_CONVENTION" },
- { 0x8E4E, "GL_LAST_VERTEX_CONVENTION" },
- { 0x8E4F, "GL_PROVOKING_VERTEX" },
- { 0x8E50, "GL_SAMPLE_POSITION" },
- { 0x8E51, "GL_SAMPLE_MASK" },
- { 0x8E52, "GL_SAMPLE_MASK_VALUE" },
- { 0x8E59, "GL_MAX_SAMPLE_MASK_WORDS" },
- { 0x8E5E, "GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET" },
- { 0x8E5F, "GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET" },
- { 0x8F36, "GL_COPY_READ_BUFFER" },
- { 0x8F37, "GL_COPY_WRITE_BUFFER" },
- { 0x8F39, "GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES" },
- { 0x8F90, "GL_RED_SNORM" },
- { 0x8F91, "GL_RG_SNORM" },
- { 0x8F92, "GL_RGB_SNORM" },
- { 0x8F93, "GL_RGBA_SNORM" },
- { 0x8F94, "GL_R8_SNORM" },
- { 0x8F95, "GL_RG8_SNORM" },
- { 0x8F96, "GL_RGB8_SNORM" },
- { 0x8F97, "GL_RGBA8_SNORM" },
- { 0x8F98, "GL_R16_SNORM" },
- { 0x8F99, "GL_RG16_SNORM" },
- { 0x8F9A, "GL_RGB16_SNORM" },
- { 0x8F9B, "GL_RGBA16_SNORM" },
- { 0x8F9C, "GL_SIGNED_NORMALIZED" },
- { 0x8F9D, "GL_PRIMITIVE_RESTART" },
- { 0x8F9E, "GL_PRIMITIVE_RESTART_INDEX" },
- { 0x8F9F, "GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB" },
- { 0x906F, "GL_RGB10_A2UI" },
- { 0x90D2, "GL_SHADER_STORAGE_BUFFER" },
- { 0x90D3, "GL_SHADER_STORAGE_BUFFER_BINDING" },
- { 0x90D4, "GL_SHADER_STORAGE_BUFFER_START" },
- { 0x90D5, "GL_SHADER_STORAGE_BUFFER_SIZE" },
- { 0x90D6, "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS" },
- { 0x90D7, "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS" },
- { 0x90D8, "GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS" },
- { 0x90D9, "GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS" },
- { 0x90DA, "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS" },
- { 0x90DB, "GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS" },
- { 0x90DC, "GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS" },
- { 0x90DD, "GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS" },
- { 0x90DE, "GL_MAX_SHADER_STORAGE_BLOCK_SIZE" },
- { 0x90DF, "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT" },
- { 0x9100, "GL_TEXTURE_2D_MULTISAMPLE" },
- { 0x9101, "GL_PROXY_TEXTURE_2D_MULTISAMPLE" },
- { 0x9102, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY" },
- { 0x9103, "GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY" },
- { 0x9104, "GL_TEXTURE_BINDING_2D_MULTISAMPLE" },
- { 0x9105, "GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY" },
- { 0x9106, "GL_TEXTURE_SAMPLES" },
- { 0x9107, "GL_TEXTURE_FIXED_SAMPLE_LOCATIONS" },
- { 0x9108, "GL_SAMPLER_2D_MULTISAMPLE" },
- { 0x9109, "GL_INT_SAMPLER_2D_MULTISAMPLE" },
- { 0x910A, "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE" },
- { 0x910B, "GL_SAMPLER_2D_MULTISAMPLE_ARRAY" },
- { 0x910C, "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY" },
- { 0x910D, "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY" },
- { 0x910E, "GL_MAX_COLOR_TEXTURE_SAMPLES" },
- { 0x910F, "GL_MAX_DEPTH_TEXTURE_SAMPLES" },
- { 0x9110, "GL_MAX_INTEGER_SAMPLES" },
- { 0x9111, "GL_MAX_SERVER_WAIT_TIMEOUT" },
- { 0x9112, "GL_OBJECT_TYPE" },
- { 0x9113, "GL_SYNC_CONDITION" },
- { 0x9114, "GL_SYNC_STATUS" },
- { 0x9115, "GL_SYNC_FLAGS" },
- { 0x9116, "GL_SYNC_FENCE" },
- { 0x9117, "GL_SYNC_GPU_COMMANDS_COMPLETE" },
- { 0x9118, "GL_UNSIGNALED" },
- { 0x9119, "GL_SIGNALED" },
- { 0x911A, "GL_ALREADY_SIGNALED" },
- { 0x911B, "GL_TIMEOUT_EXPIRED" },
- { 0x911C, "GL_CONDITION_SATISFIED" },
- { 0x911D, "GL_WAIT_FAILED" },
- { 0x911F, "GL_BUFFER_ACCESS_FLAGS" },
- { 0x9120, "GL_BUFFER_MAP_LENGTH" },
- { 0x9121, "GL_BUFFER_MAP_OFFSET" },
- { 0x9122, "GL_MAX_VERTEX_OUTPUT_COMPONENTS" },
- { 0x9123, "GL_MAX_GEOMETRY_INPUT_COMPONENTS" },
- { 0x9124, "GL_MAX_GEOMETRY_OUTPUT_COMPONENTS" },
- { 0x9125, "GL_MAX_FRAGMENT_INPUT_COMPONENTS" },
- { 0x9126, "GL_CONTEXT_PROFILE_MASK" },
- { 0x9127, "GL_UNPACK_COMPRESSED_BLOCK_WIDTH" },
- { 0x9128, "GL_UNPACK_COMPRESSED_BLOCK_HEIGHT" },
- { 0x9129, "GL_UNPACK_COMPRESSED_BLOCK_DEPTH" },
- { 0x912A, "GL_UNPACK_COMPRESSED_BLOCK_SIZE" },
- { 0x912B, "GL_PACK_COMPRESSED_BLOCK_WIDTH" },
- { 0x912C, "GL_PACK_COMPRESSED_BLOCK_HEIGHT" },
- { 0x912D, "GL_PACK_COMPRESSED_BLOCK_DEPTH" },
- { 0x912E, "GL_PACK_COMPRESSED_BLOCK_SIZE" },
- { 0x912F, "GL_TEXTURE_IMMUTABLE_FORMAT" },
- { 0x9143, "GL_MAX_DEBUG_MESSAGE_LENGTH_ARB" },
- { 0x9144, "GL_MAX_DEBUG_LOGGED_MESSAGES_ARB" },
- { 0x9145, "GL_DEBUG_LOGGED_MESSAGES_ARB" },
- { 0x9146, "GL_DEBUG_SEVERITY_HIGH_ARB" },
- { 0x9147, "GL_DEBUG_SEVERITY_MEDIUM_ARB" },
- { 0x9148, "GL_DEBUG_SEVERITY_LOW_ARB" },
- { 0x9274, "GL_COMPRESSED_RGB8_ETC2" },
- { 0x9275, "GL_COMPRESSED_SRGB8_ETC2" },
- { 0x9276, "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2" },
- { 0x9277, "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2" },
- { 0x9278, "GL_COMPRESSED_RGBA8_ETC2_EAC" },
- { 0x9279, "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC" },
- { 0x9270, "GL_COMPRESSED_R11_EAC" },
- { 0x9271, "GL_COMPRESSED_SIGNED_R11_EAC" },
- { 0x9272, "GL_COMPRESSED_RG11_EAC" },
- { 0x9273, "GL_COMPRESSED_SIGNED_RG11_EAC" },
- { 0x94F0, "GL_PERFQUERY_COUNTER_EVENT_INTEL" },
- { 0x94F1, "GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL" },
- { 0x94F2, "GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL" },
- { 0x94F3, "GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL" },
- { 0x94F4, "GL_PERFQUERY_COUNTER_RAW_INTEL" },
- { 0x94F5, "GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL" },
- { 0x94F8, "GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL" },
- { 0x94F9, "GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL" },
- { 0x94FA, "GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL" },
- { 0x94FB, "GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL" },
- { 0x94FC, "GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL" },
- { 0x94FD, "GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL" },
- { 0x94FE, "GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL" },
- { 0x94FF, "GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL" },
- { 0x9500, "GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL" },
+ /* An unusually-large enum */
{ 0x19262, "GL_RASTER_POSITION_UNCLIPPED_IBM" },
+
+ /* Bitfields like GL_SCISSOR_BIT and GL_ALL_ATTRIB_BITS should not appear
+ * in the table.
+ */
+ { 0x00080000, "0x80000" },
+ { 0x000fffff, "0xfffff" },
+ { (int)0xffffffff, "0xffffffff" },
+
{ 0, NULL }
};
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
index fd9f335a767..419fd78e893 100644
--- a/src/mesa/main/texformat.c
+++ b/src/mesa/main/texformat.c
@@ -782,17 +782,3 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
_mesa_enum_to_string(internalFormat));
return MESA_FORMAT_NONE;
}
-
-GLboolean
-_mesa_tex_target_is_array(GLenum target)
-{
- switch (target) {
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
- case GL_TEXTURE_CUBE_MAP_ARRAY:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h
index 32e209997ac..ed965f84f1d 100644
--- a/src/mesa/main/texformat.h
+++ b/src/mesa/main/texformat.h
@@ -35,7 +35,4 @@ extern mesa_format
_mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
GLint internalFormat, GLenum format, GLenum type);
-extern GLboolean
-_mesa_tex_target_is_array(GLenum target);
-
#endif
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index 945890aeeb5..b273aaac2a1 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -88,12 +88,6 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions,
return;
}
- if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
- depth = height;
- height = 1;
- }
-
- assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint srcRowStride;
@@ -141,7 +135,6 @@ get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
assert(type == GL_UNSIGNED_INT_24_8 ||
type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
- assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint rowstride;
@@ -233,7 +226,6 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
{
GLint img, row;
- assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint rowstride;
@@ -431,13 +423,6 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
bool needsRebase;
void *rgba = NULL;
- if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
- depth = height;
- height = 1;
- zoffset = yoffset;
- yoffset = 0;
- }
-
/* Depending on the base format involved we may need to apply a rebase
* transform (for example: if we download to a Luminance format we want
* G=0 and B=0).
@@ -737,6 +722,17 @@ _mesa_GetTexSubImage_sw(struct gl_context *ctx,
pixels = ADD_POINTERS(buf, pixels);
}
+ /* for all array textures, the Z axis selects the layer */
+ if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
+ depth = height;
+ height = 1;
+ zoffset = yoffset;
+ yoffset = 0;
+ assert(zoffset + depth <= texImage->Height);
+ } else {
+ assert(zoffset + depth <= texImage->Depth);
+ }
+
if (get_tex_memcpy(ctx, xoffset, yoffset, zoffset, width, height, depth,
format, type, pixels, texImage)) {
/* all done */
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index ac7599f9fd4..73b3318e948 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1699,7 +1699,7 @@ texture_format_error_check_gles(struct gl_context *ctx, GLenum format,
}
}
else {
- err = _mesa_es_error_check_format_and_type(format, type, dimensions);
+ err = _mesa_es_error_check_format_and_type(ctx, format, type, dimensions);
if (err != GL_NO_ERROR) {
_mesa_error(ctx, err, "%s(format = %s, type = %s)",
callerName, _mesa_enum_to_string(format),
@@ -2028,7 +2028,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
* if is not consistent with the format, dimensions, and
* contents of the specified image.
*/
- reason = "imageSize inconsistant with width/height/format";
+ reason = "imageSize inconsistent with width/height/format";
error = GL_INVALID_VALUE;
goto error;
}
@@ -2492,8 +2492,8 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
if (!_mesa_source_buffer_exists(ctx, texImage->_BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(missing readbuffer, format=0x%x)", caller,
- texImage->_BaseFormat);
+ "%s(missing readbuffer, format=%s)", caller,
+ _mesa_enum_to_string(texImage->_BaseFormat));
return GL_TRUE;
}
@@ -4303,15 +4303,15 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims,
if ((GLint) format != texImage->InternalFormat) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(format=0x%x)",
- callerName, format);
+ "%s(format=%s)",
+ callerName, _mesa_enum_to_string(format));
return GL_TRUE;
}
if (compressedteximage_only_format(ctx, format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(format=0x%x cannot be updated)",
- callerName, format);
+ "%s(format=%s cannot be updated)",
+ callerName, _mesa_enum_to_string(format));
return GL_TRUE;
}
@@ -4901,8 +4901,8 @@ _mesa_texture_buffer_range(struct gl_context *ctx,
format = _mesa_validate_texbuffer_format(ctx, internalFormat);
if (format == MESA_FORMAT_NONE) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "%s(internalFormat 0x%x)", caller, internalFormat);
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat %s)",
+ caller, _mesa_enum_to_string(internalFormat));
return;
}
diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c
index 103011ce572..976b2686a60 100644
--- a/src/mesa/main/transformfeedback.c
+++ b/src/mesa/main/transformfeedback.c
@@ -861,7 +861,7 @@ _mesa_TransformFeedbackVaryings(GLuint program, GLsizei count,
if (buffers > ctx->Const.MaxTransformFeedbackBuffers) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTransformFeedbackVaryings(too many gl_NextBuffer "
- "occurences)");
+ "occurrences)");
return;
}
} else {
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 083087d6baa..b2ac65fd68f 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -758,6 +758,10 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
return;
}
}
+ /* We need to reset the validate flag on changes to samplers in case
+ * two different sampler types are set to the same texture unit.
+ */
+ ctx->_Shader->Validated = GL_FALSE;
}
if (uni->type->is_image()) {
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index 887d0c03a50..c71e16a1e56 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -135,6 +135,11 @@ vertex_attrib_binding(struct gl_context *ctx,
{
struct gl_vertex_attrib_array *array = &vao->VertexAttrib[attribIndex];
+ if (!_mesa_is_bufferobj(vao->VertexBinding[bindingIndex].BufferObj))
+ vao->VertexAttribBufferMask &= ~VERT_BIT(attribIndex);
+ else
+ vao->VertexAttribBufferMask |= VERT_BIT(attribIndex);
+
if (array->VertexBinding != bindingIndex) {
const GLbitfield64 array_bit = VERT_BIT(attribIndex);
@@ -154,12 +159,12 @@ vertex_attrib_binding(struct gl_context *ctx,
* Binds a buffer object to the vertex buffer binding point given by index,
* and sets the Offset and Stride fields.
*/
-static void
-bind_vertex_buffer(struct gl_context *ctx,
- struct gl_vertex_array_object *vao,
- GLuint index,
- struct gl_buffer_object *vbo,
- GLintptr offset, GLsizei stride)
+void
+_mesa_bind_vertex_buffer(struct gl_context *ctx,
+ struct gl_vertex_array_object *vao,
+ GLuint index,
+ struct gl_buffer_object *vbo,
+ GLintptr offset, GLsizei stride)
{
struct gl_vertex_buffer_binding *binding = &vao->VertexBinding[index];
@@ -174,6 +179,11 @@ bind_vertex_buffer(struct gl_context *ctx,
binding->Offset = offset;
binding->Stride = stride;
+ if (!_mesa_is_bufferobj(vbo))
+ vao->VertexAttribBufferMask &= ~binding->_BoundArrays;
+ else
+ vao->VertexAttribBufferMask |= binding->_BoundArrays;
+
vao->NewArrays |= binding->_BoundArrays;
}
}
@@ -247,6 +257,52 @@ get_legal_types_mask(const struct gl_context *ctx)
}
+/**
+ * \param attrib The index of the attribute array
+ * \param size Components per element (1, 2, 3 or 4)
+ * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
+ * \param format Either GL_RGBA or GL_BGRA.
+ * \param normalized Whether integer types are converted to floats in [-1, 1]
+ * \param integer Integer-valued values (will not be normalized to [-1, 1])
+ * \param doubles Double values not reduced to floats
+ * \param relativeOffset Offset of the first element relative to the binding
+ * offset.
+ * \param flush_verties Should \c FLUSH_VERTICES be invoked before updating
+ * state?
+ */
+void
+_mesa_update_array_format(struct gl_context *ctx,
+ struct gl_vertex_array_object *vao,
+ GLuint attrib, GLint size, GLenum type,
+ GLenum format, GLboolean normalized,
+ GLboolean integer, GLboolean doubles,
+ GLuint relativeOffset, bool flush_vertices)
+{
+ struct gl_vertex_attrib_array *const array = &vao->VertexAttrib[attrib];
+ GLint elementSize;
+
+ assert(size <= 4);
+
+ if (flush_vertices) {
+ FLUSH_VERTICES(ctx, 0);
+ }
+
+ elementSize = _mesa_bytes_per_vertex_attrib(size, type);
+ assert(elementSize != -1);
+
+ array->Size = size;
+ array->Type = type;
+ array->Format = format;
+ array->Normalized = normalized;
+ array->Integer = integer;
+ array->Doubles = doubles;
+ array->RelativeOffset = relativeOffset;
+ array->_ElementSize = elementSize;
+
+ vao->NewArrays |= VERT_BIT(attrib);
+ ctx->NewState |= _NEW_ARRAY;
+}
+
/**
* Does error checking and updates the format in an attrib array.
*
@@ -274,9 +330,7 @@ update_array_format(struct gl_context *ctx,
GLboolean normalized, GLboolean integer, GLboolean doubles,
GLuint relativeOffset)
{
- struct gl_vertex_attrib_array *array;
GLbitfield typeBit;
- GLint elementSize;
GLenum format = GL_RGBA;
if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) {
@@ -377,23 +431,9 @@ update_array_format(struct gl_context *ctx,
return false;
}
- assert(size <= 4);
-
- elementSize = _mesa_bytes_per_vertex_attrib(size, type);
- assert(elementSize != -1);
-
- array = &vao->VertexAttrib[attrib];
- array->Size = size;
- array->Type = type;
- array->Format = format;
- array->Normalized = normalized;
- array->Integer = integer;
- array->Doubles = doubles;
- array->RelativeOffset = relativeOffset;
- array->_ElementSize = elementSize;
-
- vao->NewArrays |= VERT_BIT(attrib);
- ctx->NewState |= _NEW_ARRAY;
+ _mesa_update_array_format(ctx, vao, attrib, size, type, format,
+ normalized, integer, doubles, relativeOffset,
+ false);
return true;
}
@@ -491,8 +531,9 @@ update_array(struct gl_context *ctx,
/* Update the vertex buffer binding */
effectiveStride = stride != 0 ? stride : array->_ElementSize;
- bind_vertex_buffer(ctx, ctx->Array.VAO, attrib, ctx->Array.ArrayBufferObj,
- (GLintptr) ptr, effectiveStride);
+ _mesa_bind_vertex_buffer(ctx, ctx->Array.VAO, attrib,
+ ctx->Array.ArrayBufferObj, (GLintptr) ptr,
+ effectiveStride);
}
@@ -735,10 +776,26 @@ _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type,
update_array(ctx, "glVertexAttribLPointer", VERT_ATTRIB_GENERIC(index),
legalTypes, 1, 4,
- size, type, stride, GL_TRUE, GL_FALSE, GL_TRUE, ptr);
+ size, type, stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
}
+void
+_mesa_enable_vertex_array_attrib(struct gl_context *ctx,
+ struct gl_vertex_array_object *vao,
+ unsigned attrib)
+{
+ assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
+
+ if (!vao->VertexAttrib[attrib].Enabled) {
+ /* was disabled, now being enabled */
+ FLUSH_VERTICES(ctx, _NEW_ARRAY);
+ vao->VertexAttrib[attrib].Enabled = GL_TRUE;
+ vao->_Enabled |= VERT_BIT(attrib);
+ vao->NewArrays |= VERT_BIT(attrib);
+ }
+}
+
static void
enable_vertex_array_attrib(struct gl_context *ctx,
struct gl_vertex_array_object *vao,
@@ -750,15 +807,7 @@ enable_vertex_array_attrib(struct gl_context *ctx,
return;
}
- assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib));
-
- if (!vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
- /* was disabled, now being enabled */
- FLUSH_VERTICES(ctx, _NEW_ARRAY);
- vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_TRUE;
- vao->_Enabled |= VERT_BIT_GENERIC(index);
- vao->NewArrays |= VERT_BIT_GENERIC(index);
- }
+ _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
}
@@ -1716,8 +1765,8 @@ vertex_array_vertex_buffer(struct gl_context *ctx,
vbo = ctx->Shared->NullBufferObj;
}
- bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
- vbo, offset, stride);
+ _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
+ vbo, offset, stride);
}
@@ -1804,8 +1853,8 @@ vertex_array_vertex_buffers(struct gl_context *ctx,
struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
for (i = 0; i < count; i++)
- bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
- vbo, 0, 16);
+ _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
+ vbo, 0, 16);
return;
}
@@ -1876,8 +1925,8 @@ vertex_array_vertex_buffers(struct gl_context *ctx,
vbo = ctx->Shared->NullBufferObj;
}
- bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
- vbo, offsets[i], strides[i]);
+ _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
+ vbo, offsets[i], strides[i]);
}
_mesa_end_bufferobj_lookups(ctx);
diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h
index 5583ed5a1d1..a766afad5bc 100644
--- a/src/mesa/main/varray.h
+++ b/src/mesa/main/varray.h
@@ -90,6 +90,26 @@ _mesa_attr_zero_aliases_vertex(struct gl_context *ctx)
&& !is_forward_compatible_context));
}
+extern void
+_mesa_update_array_format(struct gl_context *ctx,
+ struct gl_vertex_array_object *vao,
+ GLuint attrib, GLint size, GLenum type,
+ GLenum format, GLboolean normalized,
+ GLboolean integer, GLboolean doubles,
+ GLuint relativeOffset, bool flush_vertices);
+
+extern void
+_mesa_enable_vertex_array_attrib(struct gl_context *ctx,
+ struct gl_vertex_array_object *vao,
+ unsigned attrib);
+
+extern void
+_mesa_bind_vertex_buffer(struct gl_context *ctx,
+ struct gl_vertex_array_object *vao,
+ GLuint index,
+ struct gl_buffer_object *vbo,
+ GLintptr offset, GLsizei stride);
+
extern void GLAPIENTRY
_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride,
const GLvoid *ptr);
diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c
index 314b26dc74f..e92bb111cc4 100644
--- a/src/mesa/main/version.c
+++ b/src/mesa/main/version.c
@@ -199,6 +199,7 @@ _mesa_override_gl_version(struct gl_context *ctx)
* "
*/
create_version_string(ctx, _mesa_is_gles(ctx) ? "OpenGL ES " : "");
+ ctx->Extensions.Version = ctx->Version;
}
}
diff --git a/src/mesa/program/ir_to_mesa.h b/src/mesa/program/ir_to_mesa.h
index 2488a4582db..a70f575bb5c 100644
--- a/src/mesa/program/ir_to_mesa.h
+++ b/src/mesa/program/ir_to_mesa.h
@@ -34,7 +34,6 @@ struct gl_shader;
struct gl_shader_program;
void _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
-GLboolean _mesa_ir_compile_shader(struct gl_context *ctx, struct gl_shader *shader);
GLboolean _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
void
diff --git a/src/mesa/program/prog_execute.h b/src/mesa/program/prog_execute.h
index 09542bfa294..ffaa0c94fa2 100644
--- a/src/mesa/program/prog_execute.h
+++ b/src/mesa/program/prog_execute.h
@@ -78,10 +78,6 @@ struct gl_program_machine
};
-extern void
-_mesa_get_program_register(struct gl_context *ctx, gl_register_file file,
- GLuint index, GLfloat val[4]);
-
extern GLboolean
_mesa_execute_program(struct gl_context *ctx,
const struct gl_program *program,
diff --git a/src/mesa/state_tracker/st_cb_perfmon.c b/src/mesa/state_tracker/st_cb_perfmon.c
index 8fdf0e8497f..cd7fdc06173 100644
--- a/src/mesa/state_tracker/st_cb_perfmon.c
+++ b/src/mesa/state_tracker/st_cb_perfmon.c
@@ -329,8 +329,20 @@ st_GetPerfMonitorResult(struct gl_context *ctx,
bool
-st_init_perfmon(struct st_context *st)
+st_have_perfmon(struct st_context *st)
{
+ struct pipe_screen *screen = st->pipe->screen;
+
+ if (!screen->get_driver_query_info || !screen->get_driver_query_group_info)
+ return false;
+
+ return screen->get_driver_query_group_info(screen, 0, NULL) != 0;
+}
+
+static void
+st_InitPerfMonitorGroups(struct gl_context *ctx)
+{
+ struct st_context *st = st_context(ctx);
struct gl_perf_monitor_state *perfmon = &st->ctx->PerfMonitor;
struct pipe_screen *screen = st->pipe->screen;
struct gl_perf_monitor_group *groups = NULL;
@@ -338,20 +350,14 @@ st_init_perfmon(struct st_context *st)
int num_counters, num_groups;
int gid, cid;
- if (!screen->get_driver_query_info || !screen->get_driver_query_group_info)
- return false;
-
/* Get the number of available queries. */
num_counters = screen->get_driver_query_info(screen, 0, NULL);
- if (!num_counters)
- return false;
/* Get the number of available groups. */
num_groups = screen->get_driver_query_group_info(screen, 0, NULL);
- if (num_groups)
- groups = CALLOC(num_groups, sizeof(*groups));
+ groups = CALLOC(num_groups, sizeof(*groups));
if (!groups)
- return false;
+ return;
stgroups = CALLOC(num_groups, sizeof(*stgroups));
if (!stgroups)
@@ -432,7 +438,7 @@ st_init_perfmon(struct st_context *st)
perfmon->Groups = groups;
st->perfmon = stgroups;
- return true;
+ return;
fail:
for (gid = 0; gid < num_groups; gid++) {
@@ -442,7 +448,6 @@ fail:
FREE(stgroups);
fail_only_groups:
FREE(groups);
- return false;
}
void
@@ -461,6 +466,7 @@ st_destroy_perfmon(struct st_context *st)
void st_init_perfmon_functions(struct dd_function_table *functions)
{
+ functions->InitPerfMonitorGroups = st_InitPerfMonitorGroups;
functions->NewPerfMonitor = st_NewPerfMonitor;
functions->DeletePerfMonitor = st_DeletePerfMonitor;
functions->BeginPerfMonitor = st_BeginPerfMonitor;
diff --git a/src/mesa/state_tracker/st_cb_perfmon.h b/src/mesa/state_tracker/st_cb_perfmon.h
index 29732866bf8..98202f23c83 100644
--- a/src/mesa/state_tracker/st_cb_perfmon.h
+++ b/src/mesa/state_tracker/st_cb_perfmon.h
@@ -73,7 +73,7 @@ st_perf_monitor_object(struct gl_perf_monitor_object *q)
}
bool
-st_init_perfmon(struct st_context *st);
+st_have_perfmon(struct st_context *st);
void
st_destroy_perfmon(struct st_context *st);
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 6e20fd1fda2..1459f258f94 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -255,9 +255,7 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
st_init_extensions(st->pipe->screen, &ctx->Const,
&ctx->Extensions, &st->options, ctx->Mesa_DXTn);
- if (st_init_perfmon(st)) {
- /* GL_AMD_performance_monitor is only enabled when the underlying
- * driver expose GPU hardware performance counters. */
+ if (st_have_perfmon(st)) {
ctx->Extensions.AMD_performance_monitor = GL_TRUE;
}
diff --git a/src/mesa/state_tracker/st_copytex.c b/src/mesa/state_tracker/st_copytex.c
new file mode 100644
index 00000000000..d246d8b6a71
--- /dev/null
+++ b/src/mesa/state_tracker/st_copytex.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2015 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.
+ */
+
+#include "main/mtypes.h"
+#include "main/buffers.h"
+#include "main/errors.h"
+#include "main/fbobject.h"
+#include "main/get.h"
+#include "main/teximage.h"
+#include "main/texparam.h"
+#include "st_copytex.h"
+
+
+/**
+ * Copy a colorbuffer from the window system framebuffer (a window or
+ * pbuffer) to a texture.
+ * This is a helper used by the wglBindTexImageARB() function.
+ *
+ * \param srcBuffer source buffer (GL_FRONT_LEFT, GL_BACK_LEFT, etc)
+ * \param fbWidth width of the source framebuffer
+ * \param fbHeight height of the source framebuffer
+ * \param texTarget which texture target to copy to (GL_TEXTURE_1D/2D/CUBE_MAP)
+ * \param texLevel which texture mipmap level to copy to
+ * \param cubeFace which cube face to copy to (in [0,5])
+ * \param texFormat what texture format to use, if texture doesn't exist
+ */
+void
+st_copy_framebuffer_to_texture(GLenum srcBuffer,
+ GLint fbWidth, GLint fbHeight,
+ GLenum texTarget, GLint texLevel,
+ GLuint cubeFace, GLenum texFormat)
+{
+ GLint readFBOSave, readBufSave, width, height;
+
+ assert(cubeFace < 6);
+
+ /* Save current FBO / readbuffer */
+ _mesa_GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFBOSave);
+ _mesa_GetIntegerv(GL_READ_BUFFER, &readBufSave);
+
+ /* Read from the winsys buffer */
+ _mesa_BindFramebuffer(GL_READ_BUFFER, 0);
+ _mesa_ReadBuffer(srcBuffer);
+
+ /* copy image from pbuffer to texture */
+ switch (texTarget) {
+ case GL_TEXTURE_1D:
+ _mesa_GetTexLevelParameteriv(GL_TEXTURE_1D, texLevel,
+ GL_TEXTURE_WIDTH, &width);
+ if (width == fbWidth) {
+ /* replace existing texture */
+ _mesa_CopyTexSubImage1D(GL_TEXTURE_1D,
+ texLevel,
+ 0, /* xoffset */
+ 0, 0, /* x, y */
+ fbWidth);
+ } else {
+ /* define initial texture */
+ _mesa_CopyTexImage1D(GL_TEXTURE_1D,
+ texLevel,
+ texFormat,
+ 0, 0, /* x, y */
+ fbWidth, 0);
+ }
+ break;
+ case GL_TEXTURE_2D:
+ _mesa_GetTexLevelParameteriv(GL_TEXTURE_2D, texLevel,
+ GL_TEXTURE_WIDTH, &width);
+ _mesa_GetTexLevelParameteriv(GL_TEXTURE_2D, texLevel,
+ GL_TEXTURE_HEIGHT, &height);
+ if (width == fbWidth && height == fbHeight) {
+ /* replace existing texture */
+ _mesa_CopyTexSubImage2D(GL_TEXTURE_2D,
+ texLevel,
+ 0, 0, /* xoffset, yoffset */
+ 0, 0, /* x, y */
+ fbWidth, fbHeight);
+ } else {
+ /* define initial texture */
+ _mesa_CopyTexImage2D(GL_TEXTURE_2D,
+ texLevel,
+ texFormat,
+ 0, 0, /* x, y */
+ fbWidth, fbHeight, 0);
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ {
+ const GLenum target =
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace;
+ _mesa_GetTexLevelParameteriv(target, texLevel,
+ GL_TEXTURE_WIDTH, &width);
+ _mesa_GetTexLevelParameteriv(target, texLevel,
+ GL_TEXTURE_HEIGHT, &height);
+ if (width == fbWidth && height == fbHeight) {
+ /* replace existing texture */
+ _mesa_CopyTexSubImage2D(target,
+ texLevel,
+ 0, 0, /* xoffset, yoffset */
+ 0, 0, /* x, y */
+ fbWidth, fbHeight);
+ } else {
+ /* define new texture */
+ _mesa_CopyTexImage2D(target,
+ texLevel,
+ texFormat,
+ 0, 0, /* x, y */
+ fbWidth, fbHeight, 0);
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL,
+ "unexpected target in st_copy_framebuffer_to_texture()\n");
+ }
+
+ /* restore readbuffer */
+ _mesa_ReadBuffer(readBufSave);
+ _mesa_BindFramebuffer(GL_READ_BUFFER, readFBOSave);
+}
diff --git a/src/mesa/state_tracker/st_copytex.h b/src/mesa/state_tracker/st_copytex.h
new file mode 100644
index 00000000000..451bd2edca5
--- /dev/null
+++ b/src/mesa/state_tracker/st_copytex.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015 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 ST_COPYTEX_H
+#define ST_COPYTEX_H
+
+#include "main/glheader.h"
+
+extern void
+st_copy_framebuffer_to_texture(GLenum srcBuffer,
+ GLint fbWidth, GLint fbHeight,
+ GLenum texTarget, GLint texLevel,
+ GLuint cubeFace, GLenum texFormat);
+
+
+#endif /* ST_COPYTEX_H */
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 40c77258de7..b6a0e6b4f4f 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1655,7 +1655,13 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
st_dst_reg temp_dst = st_dst_reg(temp);
st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp);
- emit_asm(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]);
+ if (ir->operands[0]->type->is_boolean() &&
+ ir->operands[1]->as_constant() &&
+ ir->operands[1]->as_constant()->is_one()) {
+ emit_asm(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), op[0]);
+ } else {
+ emit_asm(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]);
+ }
/* Emit 1-3 AND operations to combine the SEQ results. */
switch (ir->operands[0]->type->vector_elements) {
@@ -1708,7 +1714,13 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
st_src_reg temp = get_temp(native_integers ?
glsl_type::uvec4_type :
glsl_type::vec4_type);
- emit_asm(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
+ if (ir->operands[0]->type->is_boolean() &&
+ ir->operands[1]->as_constant() &&
+ ir->operands[1]->as_constant()->is_zero()) {
+ emit_asm(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), op[0]);
+ } else {
+ emit_asm(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
+ }
if (native_integers) {
st_dst_reg temp_dst = st_dst_reg(temp);
diff --git a/src/util/debug.c b/src/util/debug.c
index 3729ce85670..98b1853325d 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -51,3 +51,28 @@ parse_debug_string(const char *debug,
return flag;
}
+
+/**
+ * Reads an environment variable and interprets its value as a boolean.
+ *
+ * Recognizes 0/false/no and 1/true/yes. Other values result in the default value.
+ */
+bool
+env_var_as_boolean(const char *var_name, bool default_value)
+{
+ const char *str = getenv(var_name);
+ if (str == NULL)
+ return default_value;
+
+ if (strcmp(str, "1") == 0 ||
+ strcasecmp(str, "true") == 0 ||
+ strcasecmp(str, "yes") == 0) {
+ return true;
+ } else if (strcmp(str, "0") == 0 ||
+ strcasecmp(str, "false") == 0 ||
+ strcasecmp(str, "no") == 0) {
+ return false;
+ } else {
+ return default_value;
+ }
+}
diff --git a/src/util/debug.h b/src/util/debug.h
index 801736aafff..11a8561eb57 100644
--- a/src/util/debug.h
+++ b/src/util/debug.h
@@ -25,6 +25,7 @@
#define _DEBUG_H
#include
+#include
#ifdef __cplusplus
extern "C" {
@@ -38,6 +39,8 @@ struct debug_control {
uint64_t
parse_debug_string(const char *debug,
const struct debug_control *control);
+bool
+env_var_as_boolean(const char *var_name, bool default_value);
#ifdef __cplusplus
} /* extern C */
diff --git a/src/util/format_srgb.h b/src/util/format_srgb.h
index 4a8d73f125f..34b50afe3d1 100644
--- a/src/util/format_srgb.h
+++ b/src/util/format_srgb.h
@@ -57,7 +57,7 @@ util_format_linear_to_srgb_helper_table[104];
static inline float
util_format_linear_to_srgb_float(float cl)
{
- if (cl < 0.0f)
+ if (cl <= 0.0f)
return 0.0f;
else if (cl < 0.0031308f)
return 12.92f * cl;
diff --git a/src/util/macros.h b/src/util/macros.h
index 84e4f182bcf..0c8958feae9 100644
--- a/src/util/macros.h
+++ b/src/util/macros.h
@@ -24,6 +24,8 @@
#ifndef UTIL_MACROS_H
#define UTIL_MACROS_H
+#include
+
/* Compute the size of an array */
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
@@ -184,7 +186,7 @@ do { \
* inline a static function that we later use in an alias. - ajax
*/
#ifndef PUBLIC
-# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+# if defined(__GNUC__)
# define PUBLIC __attribute__((visibility("default")))
# define USED __attribute__((used))
# elif defined(_MSC_VER)
diff --git a/src/util/u_atomic_test.c b/src/util/u_atomic_test.c
index 7844f616222..7a77768c966 100644
--- a/src/util/u_atomic_test.c
+++ b/src/util/u_atomic_test.c
@@ -26,7 +26,7 @@
**************************************************************************/
-/* Force assertions, even on debug builds. */
+/* Force assertions, even on release builds. */
#undef NDEBUG
diff --git a/src/vulkan/anv_cmd_buffer.c b/src/vulkan/anv_cmd_buffer.c
index d34d53dcbb3..5a56bb53c5e 100644
--- a/src/vulkan/anv_cmd_buffer.c
+++ b/src/vulkan/anv_cmd_buffer.c
@@ -589,22 +589,14 @@ fill_descriptor_buffer_surface_state(struct anv_device *device, void *state,
uint32_t offset, uint32_t range)
{
VkFormat format;
- uint32_t stride;
-
switch (type) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
- if (device->instance->physicalDevice.compiler->scalar_stage[stage]) {
- stride = 4;
- } else {
- stride = 16;
- }
format = VK_FORMAT_R32G32B32A32_SFLOAT;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
- stride = 1;
format = VK_FORMAT_UNDEFINED;
break;
@@ -614,7 +606,7 @@ fill_descriptor_buffer_surface_state(struct anv_device *device, void *state,
anv_fill_buffer_surface_state(device, state,
anv_format_for_vk_format(format),
- offset, range, stride);
+ offset, range, 1);
}
VkResult
@@ -938,7 +930,7 @@ anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
const unsigned local_id_dwords = cs_prog_data->local_invocation_id_regs * 8;
const unsigned push_constant_data_size =
- (local_id_dwords + prog_data->nr_params) * sizeof(gl_constant_value);
+ (local_id_dwords + prog_data->nr_params) * sizeof(union gl_constant_value *);
const unsigned reg_aligned_constant_size = ALIGN(push_constant_data_size, 32);
const unsigned param_aligned_count =
reg_aligned_constant_size / sizeof(uint32_t);
diff --git a/src/vulkan/anv_nir_apply_dynamic_offsets.c b/src/vulkan/anv_nir_apply_dynamic_offsets.c
index c500ab3e03c..16b29b46fc9 100644
--- a/src/vulkan/anv_nir_apply_dynamic_offsets.c
+++ b/src/vulkan/anv_nir_apply_dynamic_offsets.c
@@ -50,13 +50,10 @@ apply_dynamic_offsets_block(nir_block *block, void *void_state)
unsigned block_idx_src;
switch (intrin->intrinsic) {
case nir_intrinsic_load_ubo:
- case nir_intrinsic_load_ubo_indirect:
case nir_intrinsic_load_ssbo:
- case nir_intrinsic_load_ssbo_indirect:
block_idx_src = 0;
break;
case nir_intrinsic_store_ssbo:
- case nir_intrinsic_store_ssbo_indirect:
block_idx_src = 1;
break;
default:
@@ -77,103 +74,36 @@ apply_dynamic_offsets_block(nir_block *block, void *void_state)
b->cursor = nir_before_instr(&intrin->instr);
- int indirect_src;
- switch (intrin->intrinsic) {
- case nir_intrinsic_load_ubo_indirect:
- case nir_intrinsic_load_ssbo_indirect:
- indirect_src = 1;
- break;
- case nir_intrinsic_store_ssbo_indirect:
- indirect_src = 2;
- break;
- default:
- indirect_src = -1;
- break;
- }
-
/* First, we need to generate the uniform load for the buffer offset */
uint32_t index = state->layout->set[set].dynamic_offset_start +
set_layout->binding[binding].dynamic_offset_index;
- nir_const_value *const_arr_idx =
- nir_src_as_const_value(res_intrin->src[0]);
-
- nir_intrinsic_op offset_load_op;
- if (const_arr_idx)
- offset_load_op = nir_intrinsic_load_uniform;
- else
- offset_load_op = nir_intrinsic_load_uniform_indirect;
-
nir_intrinsic_instr *offset_load =
- nir_intrinsic_instr_create(state->shader, offset_load_op);
+ nir_intrinsic_instr_create(state->shader, nir_intrinsic_load_uniform);
offset_load->num_components = 2;
- offset_load->const_index[0] = state->indices_start + index * 2;
-
- if (const_arr_idx) {
- offset_load->const_index[1] = const_arr_idx->u[0] * 2;
- } else {
- offset_load->const_index[1] = 0;
- offset_load->src[0] = nir_src_for_ssa(
- nir_imul(b, nir_ssa_for_src(b, res_intrin->src[0], 1),
- nir_imm_int(b, 2)));
- }
+ offset_load->const_index[0] = state->indices_start + index * 8;
+ offset_load->src[0] = nir_src_for_ssa(nir_imul(b, res_intrin->src[0].ssa,
+ nir_imm_int(b, 8)));
nir_ssa_dest_init(&offset_load->instr, &offset_load->dest, 2, NULL);
nir_builder_instr_insert(b, &offset_load->instr);
- /* We calculate the full offset and don't bother with the base
- * offset. We need the full offset for the predicate anyway.
- */
- nir_ssa_def *rel_offset = nir_imm_int(b, intrin->const_index[0]);
- if (indirect_src >= 0) {
- assert(intrin->src[indirect_src].is_ssa);
- rel_offset = nir_iadd(b, intrin->src[indirect_src].ssa, rel_offset);
- }
- nir_ssa_def *global_offset = nir_iadd(b, rel_offset,
- &offset_load->dest.ssa);
-
- /* Now we replace the load/store intrinsic */
-
- nir_intrinsic_op indirect_op;
- switch (intrin->intrinsic) {
- case nir_intrinsic_load_ubo:
- indirect_op = nir_intrinsic_load_ubo_indirect;
- break;
- case nir_intrinsic_load_ssbo:
- indirect_op = nir_intrinsic_load_ssbo_indirect;
- break;
- case nir_intrinsic_store_ssbo:
- indirect_op = nir_intrinsic_store_ssbo_indirect;
- break;
- default:
- unreachable("Invalid direct load/store intrinsic");
- }
-
- nir_intrinsic_instr *copy =
- nir_intrinsic_instr_create(state->shader, indirect_op);
- copy->num_components = intrin->num_components;
-
- /* The indirect is always the last source */
- indirect_src = nir_intrinsic_infos[indirect_op].num_srcs - 1;
-
- for (unsigned i = 0; i < (unsigned)indirect_src; i++)
- nir_src_copy(©->src[i], &intrin->src[i], ©->instr);
-
- copy->src[indirect_src] = nir_src_for_ssa(global_offset);
- nir_ssa_dest_init(©->instr, ©->dest,
- intrin->dest.ssa.num_components,
- intrin->dest.ssa.name);
+ nir_src *offset_src = nir_get_io_offset_src(intrin);
+ nir_ssa_def *new_offset = nir_iadd(b, offset_src->ssa,
+ &offset_load->dest.ssa);
/* In order to avoid out-of-bounds access, we predicate */
- nir_ssa_def *pred = nir_fge(b, nir_channel(b, &offset_load->dest.ssa, 1),
- rel_offset);
+ nir_ssa_def *pred = nir_uge(b, nir_channel(b, &offset_load->dest.ssa, 1),
+ offset_src->ssa);
nir_if *if_stmt = nir_if_create(b->shader);
if_stmt->condition = nir_src_for_ssa(pred);
nir_cf_node_insert(b->cursor, &if_stmt->cf_node);
- nir_instr_insert_after_cf_list(&if_stmt->then_list, ©->instr);
+ nir_instr_remove(&intrin->instr);
+ *offset_src = nir_src_for_ssa(new_offset);
+ nir_instr_insert_after_cf_list(&if_stmt->then_list, &intrin->instr);
- if (indirect_op != nir_intrinsic_store_ssbo) {
+ if (intrin->intrinsic != nir_intrinsic_store_ssbo) {
/* It's a load, we need a phi node */
nir_phi_instr *phi = nir_phi_instr_create(b->shader);
nir_ssa_dest_init(&phi->instr, &phi->dest,
@@ -182,7 +112,7 @@ apply_dynamic_offsets_block(nir_block *block, void *void_state)
nir_phi_src *src1 = ralloc(phi, nir_phi_src);
struct exec_node *tnode = exec_list_get_tail(&if_stmt->then_list);
src1->pred = exec_node_data(nir_block, tnode, cf_node.node);
- src1->src = nir_src_for_ssa(©->dest.ssa);
+ src1->src = nir_src_for_ssa(&intrin->dest.ssa);
exec_list_push_tail(&phi->srcs, &src1->node);
b->cursor = nir_after_cf_list(&if_stmt->else_list);
@@ -195,14 +125,12 @@ apply_dynamic_offsets_block(nir_block *block, void *void_state)
src2->src = nir_src_for_ssa(zero);
exec_list_push_tail(&phi->srcs, &src2->node);
- nir_instr_insert_after_cf(&if_stmt->cf_node, &phi->instr);
-
assert(intrin->dest.is_ssa);
nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
nir_src_for_ssa(&phi->dest.ssa));
- }
- nir_instr_remove(&intrin->instr);
+ nir_instr_insert_after_cf(&if_stmt->cf_node, &phi->instr);
+ }
}
return true;
@@ -234,10 +162,10 @@ anv_nir_apply_dynamic_offsets(struct anv_pipeline *pipeline,
struct anv_push_constants *null_data = NULL;
for (unsigned i = 0; i < MAX_DYNAMIC_BUFFERS; i++) {
prog_data->param[i * 2 + shader->num_uniforms] =
- (const gl_constant_value *)&null_data->dynamic[i].offset;
+ (const union gl_constant_value *)&null_data->dynamic[i].offset;
prog_data->param[i * 2 + 1 + shader->num_uniforms] =
- (const gl_constant_value *)&null_data->dynamic[i].range;
+ (const union gl_constant_value *)&null_data->dynamic[i].range;
}
- shader->num_uniforms += MAX_DYNAMIC_BUFFERS * 2;
+ shader->num_uniforms += MAX_DYNAMIC_BUFFERS * 8;
}
diff --git a/src/vulkan/anv_nir_apply_pipeline_layout.c b/src/vulkan/anv_nir_apply_pipeline_layout.c
index 8632dc74e57..5a31b02ae4f 100644
--- a/src/vulkan/anv_nir_apply_pipeline_layout.c
+++ b/src/vulkan/anv_nir_apply_pipeline_layout.c
@@ -22,6 +22,7 @@
*/
#include "anv_nir.h"
+#include "program/prog_parameter.h"
#include "glsl/nir/nir_builder.h"
struct apply_pipeline_layout_state {
@@ -238,8 +239,8 @@ apply_pipeline_layout_block(nir_block *block, void *void_state)
}
static void
-setup_vec4_uniform_value(const gl_constant_value **params,
- const gl_constant_value *values,
+setup_vec4_uniform_value(const union gl_constant_value **params,
+ const union gl_constant_value *values,
unsigned n)
{
static const gl_constant_value zero = { 0 };
@@ -292,17 +293,17 @@ anv_nir_apply_pipeline_layout(nir_shader *shader,
const struct brw_image_param *image_param = null_data->images;
for (uint32_t i = 0; i < layout->stage[shader->stage].image_count; i++) {
setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_SURFACE_IDX_OFFSET,
- (const gl_constant_value *)&image_param->surface_idx, 1);
+ (const union gl_constant_value *)&image_param->surface_idx, 1);
setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_OFFSET_OFFSET,
- (const gl_constant_value *)image_param->offset, 2);
+ (const union gl_constant_value *)image_param->offset, 2);
setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_SIZE_OFFSET,
- (const gl_constant_value *)image_param->size, 3);
+ (const union gl_constant_value *)image_param->size, 3);
setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_STRIDE_OFFSET,
- (const gl_constant_value *)image_param->stride, 4);
+ (const union gl_constant_value *)image_param->stride, 4);
setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_TILING_OFFSET,
- (const gl_constant_value *)image_param->tiling, 3);
+ (const union gl_constant_value *)image_param->tiling, 3);
setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_SWIZZLING_OFFSET,
- (const gl_constant_value *)image_param->swizzling, 2);
+ (const union gl_constant_value *)image_param->swizzling, 2);
param += BRW_IMAGE_PARAM_SIZE;
image_param ++;
diff --git a/src/vulkan/anv_pipeline.c b/src/vulkan/anv_pipeline.c
index 9b6eef8074b..05d84feba68 100644
--- a/src/vulkan/anv_pipeline.c
+++ b/src/vulkan/anv_pipeline.c
@@ -321,8 +321,8 @@ anv_pipeline_compile(struct anv_pipeline *pipeline,
if (prog_data->nr_params > 0) {
/* XXX: I think we're leaking this */
- prog_data->param = (const gl_constant_value **)
- malloc(prog_data->nr_params * sizeof(gl_constant_value *));
+ prog_data->param = (const union gl_constant_value **)
+ malloc(prog_data->nr_params * sizeof(union gl_constant_value *));
/* We now set the param values to be offsets into a
* anv_push_constant_data structure. Since the compiler doesn't
@@ -333,7 +333,7 @@ anv_pipeline_compile(struct anv_pipeline *pipeline,
if (nir->num_uniforms > 0) {
/* Fill out the push constants section of the param array */
for (unsigned i = 0; i < MAX_PUSH_CONSTANTS_SIZE / sizeof(float); i++)
- prog_data->param[i] = (const gl_constant_value *)
+ prog_data->param[i] = (const union gl_constant_value *)
&null_data->client_data[i * sizeof(float)];
}
}
@@ -362,7 +362,7 @@ anv_pipeline_compile(struct anv_pipeline *pipeline,
/* nir_lower_io will only handle the push constants; we need to set this
* to the full number of possible uniforms.
*/
- nir->num_uniforms = prog_data->nr_params;
+ nir->num_uniforms = prog_data->nr_params * 4;
return nir;
}
diff --git a/src/vulkan/gen8_cmd_buffer.c b/src/vulkan/gen8_cmd_buffer.c
index fccc2f4d084..4e5db676722 100644
--- a/src/vulkan/gen8_cmd_buffer.c
+++ b/src/vulkan/gen8_cmd_buffer.c
@@ -521,7 +521,7 @@ flush_compute_descriptor_set(struct anv_cmd_buffer *cmd_buffer)
unsigned local_id_dwords = cs_prog_data->local_invocation_id_regs * 8;
unsigned push_constant_data_size =
- (prog_data->nr_params + local_id_dwords) * sizeof(gl_constant_value);
+ (prog_data->nr_params + local_id_dwords) * sizeof(union gl_constant_value *);
unsigned reg_aligned_constant_size = ALIGN(push_constant_data_size, 32);
unsigned push_constant_regs = reg_aligned_constant_size / 32;